From 6ae81785e54e593a369b9e0b92594f6ff474bc83 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 7 Apr 2011 22:03:25 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 4 + gcc/cp/pt.c | 118 ++++++++++++----------- gcc/testsuite/ChangeLog | 2 + gcc/testsuite/g++.dg/cpp0x/variadic107.C | 15 +++ 4 files changed, 83 insertions(+), 56 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic107.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d20cf5165a3..fcb5232af72 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-04-07 Jason Merrill + PR c++/48451 + * pt.c (fn_type_unification): Don't clear incomplete pack flag. + (type_unification_real): Clear it here instead. + PR c++/48468 * except.c (build_noexcept_spec): Propagate error_mark_node. (finish_noexcept_expr): Likewise. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 66db880acd5..4edd4045ca9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13719,7 +13719,8 @@ fn_type_unification (tree fn, template_parm_level_and_index (parm, &level, &idx); /* 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); if (targ) { @@ -13776,22 +13777,6 @@ fn_type_unification (tree fn, targs, parms, args, nargs, /*subr=*/0, 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, ensure that the arguments deduced for the template template parameters have compatible template parameter lists. We cannot @@ -14136,15 +14121,17 @@ type_unification_real (tree tparms, return 1; 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; - - if (TREE_VEC_ELT (tparms, i) == error_mark_node) - continue; + tree targ = TREE_VEC_ELT (targs, i); + tree tparm = TREE_VEC_ELT (tparms, i); - 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 a type parameter, try another pass; its type may have been @@ -14154,59 +14141,78 @@ type_unification_real (tree tparms, && uses_template_parms (TREE_TYPE (tparm)) && !saw_undeduced++) 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 - default template argument, if any, is used. + /* Clear the "incomplete" flags on all argument packs now so that + 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 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 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, i, NULL_TREE); - if (arg == error_mark_node) - return 1; - else - { - TREE_VEC_ELT (targs, i) = arg; + if (arg == error_mark_node) + return 1; + else + { + TREE_VEC_ELT (targs, i) = arg; /* The position of the first default template argument, is also the number of non-defaulted arguments in TARGS. Record that. */ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i); - continue; - } - } + continue; + } + } - /* If the type parameter is a parameter pack, then it will - be deduced to an empty parameter pack. */ - if (template_parameter_pack_p (tparm)) - { - tree arg; + /* If the type parameter is a parameter pack, then it will + be deduced to an empty parameter pack. */ + if (template_parameter_pack_p (tparm)) + { + tree arg; - if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) - { - arg = make_node (NONTYPE_ARGUMENT_PACK); - TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm)); - TREE_CONSTANT (arg) = 1; - } - else - arg = cxx_make_type (TYPE_ARGUMENT_PACK); + if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) + { + arg = make_node (NONTYPE_ARGUMENT_PACK); + TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm)); + TREE_CONSTANT (arg) = 1; + } + else + 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; - continue; - } + TREE_VEC_ELT (targs, i) = arg; + continue; + } return 2; } + } #ifdef ENABLE_CHECKING if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc446df8a0b..8f52da21e08 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-04-07 Jason Merrill + * g++.dg/cpp0x/variadic107.C: New. + * g++.dg/cpp0x/sfinae11.C: New. * g++.dg/cpp0x/noexcept02.C: Fix. diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic107.C b/gcc/testsuite/g++.dg/cpp0x/variadic107.C new file mode 100644 index 00000000000..5c3f468515d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic107.C @@ -0,0 +1,15 @@ +// PR c++/48451 +// { dg-options -std=c++0x } + +namespace std { + template T&& declval(); +} + +template()...)) + > +char f(int); + +struct From2Ints { From2Ints(int, int); }; + +static_assert(sizeof(f(0)) == 1, "Error"); // b -- 2.30.2