re PR c++/55220 ([c++11] ICE when doing partial template specialization on variadic...
authorJason Merrill <jason@redhat.com>
Fri, 15 Feb 2013 01:27:12 +0000 (20:27 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 15 Feb 2013 01:27:12 +0000 (20:27 -0500)
PR c++/55220
* pt.c (unify): A pack expansion that is not the last template
argument makes the entire template argument list non-deduced.

From-SVN: r196068

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

index 76cefcf848bc4dd6f3b1e4d98f2f8e1233973635..1ecbb7b0b1a0fb83d356b5eda604b8a5fa728d0b 100644 (file)
@@ -1,5 +1,9 @@
 2013-02-14  Jason Merrill  <jason@redhat.com>
 
+       PR c++/55220
+       * pt.c (unify): A pack expansion that is not the last template
+       argument makes the entire template argument list non-deduced.
+
        PR c++/56323
        * name-lookup.c (do_class_using_decl): Handle typedefs with
        inheriting constructors.
index e88ea855694d05df71be88cccc27a5a403dfe371..440df1ea2317a4803d1fe5a4e6ce63e9ca07e350 100644 (file)
@@ -16548,6 +16548,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
                 && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
               parm_variadic_p = 1;
             
+             for (i = 0; i < len - parm_variadic_p; ++i)
+              /* If the template argument list of P contains a pack
+                 expansion that is not the last template argument, the
+                 entire template argument list is a non-deduced
+                 context.  */
+              if (PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, i)))
+                return unify_success (explain_p);
+
             if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
               return unify_too_few_arguments (explain_p,
                                              TREE_VEC_LENGTH (argvec), len);
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-nondeduce2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-nondeduce2.C
new file mode 100644 (file)
index 0000000..a82a098
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/55220
+// { dg-do compile { target c++11 } }
+
+template <typename ...> struct something_like_tuple
+{
+
+};
+
+template <typename, typename> struct is_last
+{
+  static const bool value = false;
+};
+
+// Head is non-deducible, so this can't work as the user intended
+template <typename T, template <typename ...> class Tuple, typename ... Head>
+struct is_last<T, Tuple<Head ..., T>>
+{
+  static const bool value = true;
+};
+
+#define SA(X) static_assert (X, #X)
+
+typedef something_like_tuple<char, int, float> something_like_tuple_t;
+SA ((is_last<float, something_like_tuple_t>::value == false));
+SA ((is_last<int, something_like_tuple_t>::value == false));