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:
parent
815effe155
commit
9e356571d4
@ -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
|
||||
|
51
gcc/cp/pt.c
51
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". */
|
||||
|
14
gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
Normal file
14
gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
Normal 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>({});
|
||||
}
|
21
gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
Normal 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> {};
|
Loading…
Reference in New Issue
Block a user