aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-08-03 16:32:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-08-03 16:32:00 -0400
commit9e356571d442ca5241117b05428fb5055b55d0aa (patch)
tree41425791228c8d39bef684f2738624f37bed404c /gcc
parent815effe15595b6f680baedaf28868a0d21335302 (diff)
downloadgcc-9e356571d442ca5241117b05428fb5055b55d0aa.zip
gcc-9e356571d442ca5241117b05428fb5055b55d0aa.tar.gz
gcc-9e356571d442ca5241117b05428fb5055b55d0aa.tar.bz2
DR 1430 PR c++/51239
DR 1430 PR c++/51239 * pt.c (pack_expansion_args_count): Rename from any_pack_expanson_args_p. (coerce_template_parms): Reject pack expansion to non-pack template parameter of alias template. From-SVN: r201469
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c51
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C21
4 files changed, 87 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 74e5f83..8b9b997 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2013-08-03 Jason Merrill <jason@redhat.com>
+
+ DR 1430
+ PR c++/51239
+ * pt.c (pack_expansion_args_count): Rename from
+ any_pack_expanson_args_p.
+ (coerce_template_parms): Reject pack expansion to
+ non-pack template parameter of alias template.
+
2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
* error.c (dump_aggr_type): Use specialized pretty printer
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 82c72dd..bbaeb7d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6542,18 +6542,22 @@ coerce_template_parameter_pack (tree parms,
return argument_pack;
}
-/* Returns true if the template argument vector ARGS contains
- any pack expansions, false otherwise. */
+/* Returns the number of pack expansions in the template argument vector
+ ARGS. */
-static bool
-any_pack_expanson_args_p (tree args)
+static int
+pack_expansion_args_count (tree args)
{
int i;
+ int count = 0;
if (args)
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
- if (PACK_EXPANSION_P (TREE_VEC_ELT (args, i)))
- return true;
- return false;
+ {
+ tree elt = TREE_VEC_ELT (args, i);
+ if (elt && PACK_EXPANSION_P (elt))
+ ++count;
+ }
+ return count;
}
/* Convert all template arguments to their appropriate types, and
@@ -6588,6 +6592,7 @@ coerce_template_parms (tree parms,
subtract it from nparms to get the number of non-variadic
parameters. */
int variadic_p = 0;
+ int variadic_args_p = 0;
int post_variadic_parms = 0;
if (args == error_mark_node)
@@ -6617,11 +6622,14 @@ coerce_template_parms (tree parms,
if (!post_variadic_parms)
inner_args = expand_template_argument_pack (inner_args);
+ /* Count any pack expansion args. */
+ variadic_args_p = pack_expansion_args_count (inner_args);
+
nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
if ((nargs > nparms && !variadic_p)
|| (nargs < nparms - variadic_p
&& require_all_args
- && !any_pack_expanson_args_p (inner_args)
+ && !variadic_args_p
&& (!use_default_args
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
&& !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
@@ -6644,6 +6652,33 @@ coerce_template_parms (tree parms,
return error_mark_node;
}
+ /* We can't pass a pack expansion to a non-pack parameter of an alias
+ template (DR 1430). */
+ else if (in_decl && DECL_ALIAS_TEMPLATE_P (in_decl)
+ && variadic_args_p
+ && nargs - variadic_args_p < nparms - variadic_p)
+ {
+ if (complain & tf_error)
+ {
+ for (int i = 0; i < TREE_VEC_LENGTH (inner_args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (inner_args, i);
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+
+ if (PACK_EXPANSION_P (arg)
+ && !template_parameter_pack_p (parm))
+ {
+ error ("pack expansion argument for non-pack parameter "
+ "%qD of alias template %qD", parm, in_decl);
+ inform (DECL_SOURCE_LOCATION (parm), "declared here");
+ goto found;
+ }
+ }
+ gcc_unreachable ();
+ found:;
+ }
+ return error_mark_node;
+ }
/* We need to evaluate the template arguments, even though this
template-id may be nested within a "sizeof". */
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
new file mode 100644
index 0000000..25781a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
@@ -0,0 +1,14 @@
+// PR c++/51239
+// { dg-require-effective-target c++11 }
+
+template<class... x>
+class list{};
+template<class a, class... b>
+using tail=list<b...>;
+template <class...T>
+void f(tail<T...>); // { dg-error "alias" }
+
+int main()
+{
+ f<int,int>({});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
new file mode 100644
index 0000000..d6a3e12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
@@ -0,0 +1,21 @@
+// PR c++/57138
+// { dg-do compile { target c++11 } }
+
+template <template <typename ... X> class T, typename ... Y>
+struct D
+{
+ template <typename ... Z>
+ using type = T <Y..., Z...>; // { dg-error "pack expansion" }
+};
+template <typename T>
+class A {};
+template <typename X, typename Y>
+struct B;
+template <typename T>
+struct B <int, T>
+{
+ typedef A <T> type;
+};
+template <typename X, typename Y>
+using C = typename B <X, Y>::type;
+struct E : public D <C> {};