From: Nathan Sidwell Date: Mon, 20 Apr 2020 13:48:45 +0000 (-0700) Subject: c++: Expr pack expansion equality [pr94454] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7fcb93431ef18a31c9af142f77faa176bbd9b3dc;p=gcc.git 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. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5191db9580e..49db85d1c1a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-04-20 Nathan Sidwell + 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 dc4f1f48d3c..092a2fab356 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; }