aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-02-14 20:27:12 -0500
committerJason Merrill <jason@gcc.gnu.org>2013-02-14 20:27:12 -0500
commitd132b74abae28ef6dafb6d194d32c838b204db77 (patch)
tree8086b22c332006fd4c411faae7343dcc311dfc25 /gcc
parent06449b408eb72fbc8f5b78fea962efd4e72db5e6 (diff)
downloadgcc-d132b74abae28ef6dafb6d194d32c838b204db77.zip
gcc-d132b74abae28ef6dafb6d194d32c838b204db77.tar.gz
gcc-d132b74abae28ef6dafb6d194d32c838b204db77.tar.bz2
re PR c++/55220 ([c++11] ICE when doing partial template specialization on variadic template)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-nondeduce2.C25
3 files changed, 37 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 76cefcf..1ecbb7b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e88ea85..440df1e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..a82a098
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-nondeduce2.C
@@ -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));