diff mbox series

C++ PATCH for c++/84770, ICE with parameter pack and typedef

Message ID CADzB+2=c5Q+aSrB-PW4C=TAA09950f0j2-kVmXmQY7hchQ4WXw@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/84770, ICE with parameter pack and typedef | expand

Commit Message

Jason Merrill March 10, 2018, 3:27 a.m. UTC
Now that argument packs don't have a type, the check for a non-type
argument with a typedefy type wasn't working for them.  So let's
recurse.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox series

Patch

commit 7a163ab3c89382ad5c3bda2f345950760bc499c7
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Mar 9 21:56:18 2018 -0500

            PR c++/84770 - ICE with typedef and parameter pack.
    
            * pt.c (verify_unstripped_args_1): Split out from
            verify_unstripped_args.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2d7ce6062a7..c53f0bc23bb 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1133,27 +1133,32 @@  optimize_specialization_lookup_p (tree tmpl)
 /* Make sure ARGS doesn't use any inappropriate typedefs; we should have
    gone through coerce_template_parms by now.  */
 
+static void
+verify_unstripped_args_1 (tree inner)
+{
+  for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i)
+    {
+      tree arg = TREE_VEC_ELT (inner, i);
+      if (TREE_CODE (arg) == TEMPLATE_DECL)
+	/* OK */;
+      else if (TYPE_P (arg))
+	gcc_assert (strip_typedefs (arg, NULL) == arg);
+      else if (ARGUMENT_PACK_P (arg))
+	verify_unstripped_args_1 (ARGUMENT_PACK_ARGS (arg));
+      else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg))
+	/* Allow typedefs on the type of a non-type argument, since a
+	   parameter can have them.  */;
+      else
+	gcc_assert (strip_typedefs_expr (arg, NULL) == arg);
+    }
+}
+
 static void
 verify_unstripped_args (tree args)
 {
   ++processing_template_decl;
   if (!any_dependent_template_arguments_p (args))
-    {
-      tree inner = INNERMOST_TEMPLATE_ARGS (args);
-      for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i)
-	{
-	  tree arg = TREE_VEC_ELT (inner, i);
-	  if (TREE_CODE (arg) == TEMPLATE_DECL)
-	    /* OK */;
-	  else if (TYPE_P (arg))
-	    gcc_assert (strip_typedefs (arg, NULL) == arg);
-	  else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg))
-	    /* Allow typedefs on the type of a non-type argument, since a
-	       parameter can have them.  */;
-	  else
-	    gcc_assert (strip_typedefs_expr (arg, NULL) == arg);
-	}
-    }
+    verify_unstripped_args_1 (INNERMOST_TEMPLATE_ARGS (args));
   --processing_template_decl;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic173.C b/gcc/testsuite/g++.dg/cpp0x/variadic173.C
new file mode 100644
index 00000000000..a0ca89b764f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic173.C
@@ -0,0 +1,10 @@ 
+// PR c++/84770
+// { dg-do compile { target c++11 } }
+
+typedef int T;
+
+template<T&...> struct A {};
+
+int i;
+
+A<i> a;