Things later in compilation were getting confused because we didn't
catch the unexpanded parameter pack soon enough.
While looking at this I also fixed a location issue with the error about
a parameter pack before the end of a class template parameter list, and
avoided some follow-on errors when a template parameter is erroneous.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 93c26661038b76775f56a4a277ee78aa03b23578
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Dec 22 21:41:40 2014 -0500
PR c++/63522
* parser.c (cp_parser_type_parameter): Call
check_for_bare_parameter_packs on default argument.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e57a5bd..2af1576 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13499,6 +13499,8 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
"default arguments");
default_argument = NULL_TREE;
}
+ else if (check_for_bare_parameter_packs (default_argument))
+ default_argument = error_mark_node;
pop_deferring_access_checks ();
}
else
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic164.C b/gcc/testsuite/g++.dg/cpp0x/variadic164.C
new file mode 100644
index 0000000..8f9cdb1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic164.C
@@ -0,0 +1,12 @@
+// PR c++/63522
+// { dg-do compile { target c++11 } }
+
+template <typename...> struct tuple;
+template <typename...> void slice();
+template <int Index, typename...> using slice_result = decltype(slice<Index>);
+template <typename Tuple, typename... Tuples, int... ElementIndices,
+ typename =
+ typename tuple<slice_result<ElementIndices, Tuples...>,
+ slice_result<ElementIndices, Tuples...>...>::type> // { dg-error "parameter pack" }
+void zip_with(Tuple...);
+decltype(zip_with(0)) d; // { dg-error "no match" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34052.C b/gcc/testsuite/g++.dg/cpp0x/vt-34052.C
index 1036537..31d2831 100644
--- a/gcc/testsuite/g++.dg/cpp0x/vt-34052.C
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34052.C
@@ -1,8 +1,8 @@
// { dg-do compile { target c++11 } }
-template<typename... T, typename = T> struct A {}; // { dg-error "must be at the end" }
+template<typename... T, typename = T> struct A {}; // { dg-error "parameter pack" }
-template<template<typename... T, typename = T> class U> struct B // { dg-error "must be at the end" }
+template<template<typename... T, typename = T> class U> struct B // { dg-error "parameter pack" }
{
- template<int> U<int> foo(); // { dg-error "mismatch|constant|invalid|invalid" }
+ template<int> U<int> foo(); // { dg-error "mismatch|constant|wrong|invalid" }
};
commit 9fede37842c061ad13cf7ee82d9d94befc68463d
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Dec 23 13:50:27 2014 -0500
* pt.c (check_default_tmpl_args): Uses the parameter source
location in the diagnostic.
(convert_template_argument): Just return if parm is error_mark_node.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f5bd842..21d0d3a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4578,13 +4578,8 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
parameter pack, at the end of the template
parameter list. */
- if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
- error ("parameter pack %qE must be at the end of the"
- " template parameter list", TREE_VALUE (parm));
- else
- error ("parameter pack %qT must be at the end of the"
- " template parameter list",
- TREE_TYPE (TREE_VALUE (parm)));
+ error ("parameter pack %q+D must be at the end of the"
+ " template parameter list", TREE_VALUE (parm));
TREE_VALUE (TREE_VEC_ELT (inner_parms, i))
= error_mark_node;
@@ -6524,6 +6519,9 @@ convert_template_argument (tree parm,
tree val;
int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
+ if (parm == error_mark_node)
+ return error_mark_node;
+
if (TREE_CODE (arg) == TREE_LIST
&& TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31432.C b/gcc/testsuite/g++.dg/cpp0x/pr31432.C
index 1f2ea50..2048077 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr31432.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr31432.C
@@ -4,5 +4,5 @@ template<typename..., typename> struct A // { dg-error "parameter pack" }
static int i;
};
-A<int, int> a; // { dg-error "mismatch|expected|invalid type" }
-A<char,int> b; // { dg-error "mismatch|expected|invalid type" }
+A<int, int> a;
+A<char,int> b;
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31442.C b/gcc/testsuite/g++.dg/cpp0x/pr31442.C
index 7fd20e7..b4c737c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr31442.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr31442.C
@@ -6,4 +6,4 @@ struct B
template <template <typename...> class C> B(C<int>);
};
-B b = A<int>(); // { dg-error "mismatch|expected" }
+B b = A<int>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr32115.C b/gcc/testsuite/g++.dg/cpp0x/pr32115.C
index 5722aa3..fafa4ee 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr32115.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr32115.C
@@ -1,4 +1,4 @@
// { dg-do compile { target c++11 } }
template<typename ...T, int = 0> struct A {}; // { dg-error "end of" }
-A<int> a; // { dg-error "mismatch|expected|invalid" }
+A<int> a;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic40.C b/gcc/testsuite/g++.dg/cpp0x/variadic40.C
index e4df9b8..e62d62c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic40.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic40.C
@@ -1,3 +1,3 @@
// { dg-do compile { target c++11 } }
-template<typename... Values, typename T>
-struct backward_tuple {}; // { dg-error "end" }
+template<typename... Values, typename T> // { dg-error "end" }
+struct backward_tuple {};
diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C
index 7cf9f1e..9b80fd1 100644
--- a/gcc/testsuite/g++.dg/template/crash55.C
+++ b/gcc/testsuite/g++.dg/template/crash55.C
@@ -3,4 +3,4 @@
template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" }
struct A {};
-template<int> void foo(A<int>); // { dg-error "mismatch|constant|template argument" }
+template<int> void foo(A<int>); // { dg-error "cast|argument" "" { target c++98_only } }
diff --git a/gcc/testsuite/g++.dg/template/crash57.C b/gcc/testsuite/g++.dg/template/crash57.C
index cf1c3c2..ad05e6a 100644
--- a/gcc/testsuite/g++.dg/template/crash57.C
+++ b/gcc/testsuite/g++.dg/template/crash57.C
@@ -7,4 +7,4 @@ template<typename> struct B
template<int(> struct C; // { dg-error "token" }
};
-A<char> a; // { dg-error "type/value mismatch|constant|declaration" }
+A<char> a;