On 07/05/2012 03:37 PM, Jason Merrill wrote:
have not done that for non-type arguments so far.  This patch implements
typedef stripping for non-type template arguments, and thereby avoids
the need for any fixup of sibling information.

The patch also fixes 53039, which is another case of treating things as
interchangeable that turn out not to be: in this case they are template
parameter packs that are compared for identity in arg_from_parm_pack_p,
which was running into problems during template parameter fixup.  I
didn't expect this patch to fix the bug, but apparently removing the
fixup solves the problem for this testcase.

And since we no longer have to try to deal with comparing fixed-up and non-fixed-up template parms, we can revert the earlier patch for PR 46394 which led to the issue in 53039.

Tested x86_64-pc-linux-gnu, applying to trunk.

commit 1213de7ecf31a323c64fa75fba30e523431602db
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Jul 5 15:49:23 2012 -0400

    	PR c++/53039
    	* pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
    	cp_tree_equal.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e07a362..df5d1f6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3760,34 +3760,13 @@ arg_from_parm_pack_p (tree arg_pack, tree parm_pack)
     {
       tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
       tree pattern = PACK_EXPANSION_PATTERN (expansion);
-      /* So we have an argument_pack<P...>.  We want to test if P
-	 is actually PARM_PACK.  We will not use cp_tree_equal to
-	 test P and PARM_PACK because during type fixup (by
-	 fixup_template_parm) P can be a pre-fixup version of a
-	 type and PARM_PACK be its post-fixup version.
-	 cp_tree_equal would consider them as different even
-	 though we would want to consider them compatible for our
-	 precise purpose here.
-
-	 Thus we are going to consider that P and PARM_PACK are
-	 compatible if they have the same DECL.  */
-      if ((/* If ARG_PACK is a type parameter pack named by the
-	      same DECL as parm_pack ...  */
-	   (TYPE_P (pattern)
-	    && TYPE_P (parm_pack)
-	    && TYPE_NAME (pattern) == TYPE_NAME (parm_pack))
-	   /* ... or if PARM_PACK is a non-type parameter named by the
-	      same DECL as ARG_PACK.  Note that PARM_PACK being a
-	      non-type parameter means it's either a PARM_DECL or a
-	      TEMPLATE_PARM_INDEX.  */
-	   || (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX
-	       && ((TREE_CODE (parm_pack) == PARM_DECL
-		    && (TEMPLATE_PARM_DECL (pattern)
-			== TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack))))
-		   || (TREE_CODE (parm_pack) == TEMPLATE_PARM_INDEX
-		       && (TEMPLATE_PARM_DECL (pattern)
-			   == TEMPLATE_PARM_DECL (parm_pack))))))
-	  && template_parameter_pack_p (pattern))
+      if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
+	  || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
+	/* The argument pack that the parameter maps to is just an
+	   expansion of the parameter itself, such as one would
+	   find in the implicit typedef of a class inside the
+	   class itself.  Consider this parameter "unsubstituted",
+	   so that we will maintain the outer pack expansion.  */
 	return true;
     }
   return false;

Reply via email to