re PR c++/60374 ([c++11] ICE with invalid template specialization)
authorJason Merrill <jason@redhat.com>
Tue, 1 Apr 2014 21:25:20 +0000 (17:25 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 1 Apr 2014 21:25:20 +0000 (17:25 -0400)
PR c++/60374
* pt.c (coerce_template_parms): Check that the pack expansion
pattern works with the first matching parameter.

From-SVN: r208999

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/variadic154.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/variadic155.C [new file with mode: 0644]

index 332894f..764400c 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/60374
+       * pt.c (coerce_template_parms): Check that the pack expansion
+       pattern works with the first matching parameter.
+
 2014-04-01  Fabien ChĂȘne  <fabien@gcc.gnu.org>
 
        * cp/init.c (perform_member_init): Homogenize uninitialized
index bfb49d7..9de00d5 100644 (file)
@@ -6933,6 +6933,26 @@ coerce_template_parms (tree parms,
        {
           if (PACK_EXPANSION_P (arg))
             {
+             /* "If every valid specialization of a variadic template
+                requires an empty template parameter pack, the template is
+                ill-formed, no diagnostic required."  So check that the
+                pattern works with this parameter.  */
+             tree pattern = PACK_EXPANSION_PATTERN (arg);
+             tree conv = convert_template_argument (TREE_VALUE (parm),
+                                                    pattern, new_args,
+                                                    complain, parm_idx,
+                                                    in_decl);
+             if (conv == error_mark_node)
+               {
+                 inform (input_location, "so any instantiation with a "
+                        "non-empty parameter pack would be ill-formed");
+                 ++lost;
+               }
+             else if (TYPE_P (conv) && !TYPE_P (pattern))
+               /* Recover from missing typename.  */
+               TREE_VEC_ELT (inner_args, arg_idx)
+                 = make_pack_expansion (conv);
+
               /* We don't know how many args we have yet, just
                  use the unconverted ones for now.  */
               new_inner_args = inner_args;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic154.C b/gcc/testsuite/g++.dg/cpp0x/variadic154.C
new file mode 100644 (file)
index 0000000..198f9c5
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/60374
+// { dg-do compile { target c++11 } }
+
+template<typename> struct A {};
+
+template<typename...T> struct A<T::T...> {}; // { dg-error "typename|partial|T" }
+
+A<int> a;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic155.C b/gcc/testsuite/g++.dg/cpp0x/variadic155.C
new file mode 100644 (file)
index 0000000..d912317
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct A {};
+template <int... I> struct B: A<I...> {}; // { dg-error "type" }