diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-04-20 06:48:45 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-04-20 06:48:45 -0700 |
commit | 7fcb93431ef18a31c9af142f77faa176bbd9b3dc (patch) | |
tree | 6e60d0d04b86933e0888c8deb3f85db1669e7546 /gcc | |
parent | aa576f2a860c8287cac6bbe6d37f5f37448bf06a (diff) | |
download | gcc-7fcb93431ef18a31c9af142f77faa176bbd9b3dc.zip gcc-7fcb93431ef18a31c9af142f77faa176bbd9b3dc.tar.gz gcc-7fcb93431ef18a31c9af142f77faa176bbd9b3dc.tar.bz2 |
c++: Expr pack expansion equality [pr94454]
We were not comparing expression pack expansions correctly. We could
consider distinct expansions equal and creating two, apparently equal,
specializations that would sometimes collide. cp_tree_operand_length
says a pack has 1 operand (for mangling), whereas it actually has 3,
but only two of which are significant for equality. We must special
case that in cp_tree_equal. That new code matches the hasher and the
type_pack_expansion case in structural_comp_types.
* tree.c (cp_tree_equal): [TEMPLATE_ID_EXPR, default] Refactor.
[EXPR_PACK_EXPANSION]: Add.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/tree.c | 24 |
2 files changed, 22 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5191db9..49db85d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-04-20 Nathan Sidwell <nathan@acm.org> + PR 94454 - Expr pack expansion equality + * tree.c (cp_tree_equal): [TEMPLATE_ID_EXPR, default] Refactor. + [EXPR_PACK_EXPANSION]: Add. + PR c++/94454 Template Argument Hashing * pt.c (iterative_hash_template_arg): Strip nodes as template_args_equal does. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index dc4f1f4..092a2fa 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -3771,8 +3771,11 @@ cp_tree_equal (tree t1, tree t2) TREE_TYPE (TEMPLATE_PARM_DECL (t2)))); case TEMPLATE_ID_EXPR: - return (cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)) - && cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1))); + if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))) + return false; + if (!comp_template_args (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1))) + return false; + return true; case CONSTRAINT_INFO: return cp_tree_equal (CI_ASSOCIATED_CONSTRAINTS (t1), @@ -3902,6 +3905,15 @@ cp_tree_equal (tree t1, tree t2) return true; } + case EXPR_PACK_EXPANSION: + if (!cp_tree_equal (PACK_EXPANSION_PATTERN (t1), + PACK_EXPANSION_PATTERN (t2))) + return false; + if (!comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1), + PACK_EXPANSION_EXTRA_ARGS (t2))) + return false; + return true; + default: break; } @@ -3916,14 +3928,12 @@ cp_tree_equal (tree t1, tree t2) case tcc_reference: case tcc_statement: { - int i, n; - - n = cp_tree_operand_length (t1); + int n = cp_tree_operand_length (t1); if (TREE_CODE_CLASS (code1) == tcc_vl_exp && n != TREE_OPERAND_LENGTH (t2)) return false; - for (i = 0; i < n; ++i) + for (int i = 0; i < n; ++i) if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i))) return false; @@ -3932,9 +3942,11 @@ cp_tree_equal (tree t1, tree t2) case tcc_type: return same_type_p (t1, t2); + default: gcc_unreachable (); } + /* We can get here with --disable-checking. */ return false; } |