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
This commit is contained in:
Jason Merrill 2013-08-03 16:32:00 -04:00 committed by Jason Merrill
parent 815effe155
commit 9e356571d4
4 changed files with 87 additions and 8 deletions

View File

@ -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

View File

@ -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". */

View File

@ -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>({});
}

View File

@ -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> {};