Commit 6ae81785 by Jason Merrill Committed by Jason Merrill

re PR c++/48451 ([C++0x][SFINAE] Failures with n-ary initialization expressions…

re PR c++/48451 ([C++0x][SFINAE] Failures with n-ary initialization expressions (with template default argument))

	PR c++/48451
	* pt.c (fn_type_unification): Don't clear incomplete pack flag.
	(type_unification_real): Clear it here instead.

From-SVN: r172159
parent ca1c6ce3
2011-04-07 Jason Merrill <jason@redhat.com> 2011-04-07 Jason Merrill <jason@redhat.com>
PR c++/48451
* pt.c (fn_type_unification): Don't clear incomplete pack flag.
(type_unification_real): Clear it here instead.
PR c++/48468 PR c++/48468
* except.c (build_noexcept_spec): Propagate error_mark_node. * except.c (build_noexcept_spec): Propagate error_mark_node.
(finish_noexcept_expr): Likewise. (finish_noexcept_expr): Likewise.
......
...@@ -13719,7 +13719,8 @@ fn_type_unification (tree fn, ...@@ -13719,7 +13719,8 @@ fn_type_unification (tree fn,
template_parm_level_and_index (parm, &level, &idx); template_parm_level_and_index (parm, &level, &idx);
/* Mark the argument pack as "incomplete". We could /* Mark the argument pack as "incomplete". We could
still deduce more arguments during unification. */ still deduce more arguments during unification.
We remove this mark in type_unification_real. */
targ = TMPL_ARG (converted_args, level, idx); targ = TMPL_ARG (converted_args, level, idx);
if (targ) if (targ)
{ {
...@@ -13776,22 +13777,6 @@ fn_type_unification (tree fn, ...@@ -13776,22 +13777,6 @@ fn_type_unification (tree fn,
targs, parms, args, nargs, /*subr=*/0, targs, parms, args, nargs, /*subr=*/0,
strict, flags); strict, flags);
if (result == 0 && incomplete_argument_packs_p)
{
int i, len = NUM_TMPL_ARGS (targs);
/* Clear the "incomplete" flags on all argument packs. */
for (i = 0; i < len; i++)
{
tree arg = TREE_VEC_ELT (targs, i);
if (ARGUMENT_PACK_P (arg))
{
ARGUMENT_PACK_INCOMPLETE_P (arg) = 0;
ARGUMENT_PACK_EXPLICIT_ARGS (arg) = NULL_TREE;
}
}
}
/* Now that we have bindings for all of the template arguments, /* Now that we have bindings for all of the template arguments,
ensure that the arguments deduced for the template template ensure that the arguments deduced for the template template
parameters have compatible template parameter lists. We cannot parameters have compatible template parameter lists. We cannot
...@@ -14136,15 +14121,17 @@ type_unification_real (tree tparms, ...@@ -14136,15 +14121,17 @@ type_unification_real (tree tparms,
return 1; return 1;
if (!subr) if (!subr)
for (i = 0; i < ntparms; i++) {
if (!TREE_VEC_ELT (targs, i)) /* Check to see if we need another pass before we start clearing
ARGUMENT_PACK_INCOMPLETE_P. */
for (i = 0; i < ntparms; i++)
{ {
tree tparm; tree targ = TREE_VEC_ELT (targs, i);
tree tparm = TREE_VEC_ELT (tparms, i);
if (TREE_VEC_ELT (tparms, i) == error_mark_node)
continue;
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); if (targ || tparm == error_mark_node)
continue;
tparm = TREE_VALUE (tparm);
/* If this is an undeduced nontype parameter that depends on /* If this is an undeduced nontype parameter that depends on
a type parameter, try another pass; its type may have been a type parameter, try another pass; its type may have been
...@@ -14154,59 +14141,78 @@ type_unification_real (tree tparms, ...@@ -14154,59 +14141,78 @@ type_unification_real (tree tparms,
&& uses_template_parms (TREE_TYPE (tparm)) && uses_template_parms (TREE_TYPE (tparm))
&& !saw_undeduced++) && !saw_undeduced++)
goto again; goto again;
}
/* Core issue #226 (C++0x) [temp.deduct]: for (i = 0; i < ntparms; i++)
{
tree targ = TREE_VEC_ELT (targs, i);
tree tparm = TREE_VEC_ELT (tparms, i);
If a template argument has not been deduced, its /* Clear the "incomplete" flags on all argument packs now so that
default template argument, if any, is used. substituting them into later default arguments works. */
if (targ && ARGUMENT_PACK_P (targ))
{
ARGUMENT_PACK_INCOMPLETE_P (targ) = 0;
ARGUMENT_PACK_EXPLICIT_ARGS (targ) = NULL_TREE;
}
When we are in C++98 mode, TREE_PURPOSE will either if (targ || tparm == error_mark_node)
continue;
tparm = TREE_VALUE (tparm);
/* Core issue #226 (C++0x) [temp.deduct]:
If a template argument has not been deduced, its
default template argument, if any, is used.
When we are in C++98 mode, TREE_PURPOSE will either
be NULL_TREE or ERROR_MARK_NODE, so we do not need be NULL_TREE or ERROR_MARK_NODE, so we do not need
to explicitly check cxx_dialect here. */ to explicitly check cxx_dialect here. */
if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i))) if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
{ {
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i)); tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE); arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE);
arg = convert_template_argument (parm, arg, targs, tf_none, arg = convert_template_argument (parm, arg, targs, tf_none,
i, NULL_TREE); i, NULL_TREE);
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return 1;
else else
{ {
TREE_VEC_ELT (targs, i) = arg; TREE_VEC_ELT (targs, i) = arg;
/* The position of the first default template argument, /* The position of the first default template argument,
is also the number of non-defaulted arguments in TARGS. is also the number of non-defaulted arguments in TARGS.
Record that. */ Record that. */
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i); SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
continue; continue;
} }
} }
/* If the type parameter is a parameter pack, then it will /* If the type parameter is a parameter pack, then it will
be deduced to an empty parameter pack. */ be deduced to an empty parameter pack. */
if (template_parameter_pack_p (tparm)) if (template_parameter_pack_p (tparm))
{ {
tree arg; tree arg;
if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX)
{ {
arg = make_node (NONTYPE_ARGUMENT_PACK); arg = make_node (NONTYPE_ARGUMENT_PACK);
TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm)); TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm));
TREE_CONSTANT (arg) = 1; TREE_CONSTANT (arg) = 1;
} }
else else
arg = cxx_make_type (TYPE_ARGUMENT_PACK); arg = cxx_make_type (TYPE_ARGUMENT_PACK);
SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0)); SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0));
TREE_VEC_ELT (targs, i) = arg; TREE_VEC_ELT (targs, i) = arg;
continue; continue;
} }
return 2; return 2;
} }
}
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs)); SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
......
2011-04-07 Jason Merrill <jason@redhat.com> 2011-04-07 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/variadic107.C: New.
* g++.dg/cpp0x/sfinae11.C: New. * g++.dg/cpp0x/sfinae11.C: New.
* g++.dg/cpp0x/noexcept02.C: Fix. * g++.dg/cpp0x/noexcept02.C: Fix.
......
// PR c++/48451
// { dg-options -std=c++0x }
namespace std {
template <class T> T&& declval();
}
template<class T, class... Args,
class = decltype(T(std::declval<Args>()...))
>
char f(int);
struct From2Ints { From2Ints(int, int); };
static_assert(sizeof(f<From2Ints, int, int>(0)) == 1, "Error"); // b
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment