diff options
author | Jason Merrill <jason@redhat.com> | 2013-08-03 16:32:00 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-08-03 16:32:00 -0400 |
commit | 9e356571d442ca5241117b05428fb5055b55d0aa (patch) | |
tree | 41425791228c8d39bef684f2738624f37bed404c /gcc | |
parent | 815effe15595b6f680baedaf28868a0d21335302 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/pt.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C | 21 |
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> {}; |