c++: Expr pack expansion equality [pr94454]
authorNathan Sidwell <nathan@acm.org>
Mon, 20 Apr 2020 13:48:45 +0000 (06:48 -0700)
committerNathan Sidwell <nathan@acm.org>
Mon, 20 Apr 2020 13:48:45 +0000 (06:48 -0700)
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.

gcc/cp/ChangeLog
gcc/cp/tree.c

index 5191db9580ed18d2a63202903472c08727553429..49db85d1c1ae04db1c206c45bb45a883763bfdb3 100644 (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.
index dc4f1f48d3c5cd6eae4f9bc5207d72286c517ab4..092a2fab35679f17aae03aacc7a53edfbfb7cf45 100644 (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;
 }