From 9e356571d442ca5241117b05428fb5055b55d0aa Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 3 Aug 2013 16:32:00 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 ++++ gcc/cp/pt.c | 51 ++++++++++++++++++---- gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C | 14 ++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C | 21 +++++++++ 4 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 74e5f837e52..8b9b997c2c5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2013-08-03 Jason Merrill + + 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 * error.c (dump_aggr_type): Use specialized pretty printer diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 82c72dd96df..bbaeb7d8daa 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 00000000000..25781a484e0 --- /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 list{}; +template +using tail=list; +template +void f(tail); // { dg-error "alias" } + +int main() +{ + f({}); +} 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 00000000000..d6a3e12cea2 --- /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