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.
This commit is contained in:
Nathan Sidwell 2020-04-20 06:48:45 -07:00
parent aa576f2a86
commit 7fcb93431e
2 changed files with 22 additions and 6 deletions

View File

@ -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.

View File

@ -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;
}