diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-08 02:03:25 +0000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2011-04-08 11:06:54 -0400 |
commit | e7d688d9ade0a43a305deb5cc73b0a8cde20956f (patch) | |
tree | e7b293e6f4c14cd6b2dea46db5a95eec76c7ec74 | |
parent | 5a7de054d9af65d2888d4c8075766d5535be30b5 (diff) | |
download | gcc-jason/4.6-cxx0x.tar.gz |
PR c++/48451jason/4.6-cxx0x
* pt.c (fn_type_unification): Don't clear incomplete pack flag.
(type_unification_real): Clear it here instead.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 118 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic107.C | 15 |
4 files changed, 87 insertions, 56 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ece5b049492..e867d9ff5bc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 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. + +2011-04-07 Jason Merrill <jason@redhat.com> + PR c++/48450 * call.c (resolve_args): Take complain. (build_new_function_call, build_operator_new_call): Pass it. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ed48203ee0e..bf0466cabf5 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 973e21da2d5..c7bd0cd1de9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2011-04-07 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/variadic107.C: New. + +2011-04-07 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/sfinae9.C: New. 2011-04-07 Jason Merrill <jason@redhat.com> 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 <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 |