summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-08 02:03:25 +0000
committerJason Merrill <jason@redhat.com>2011-04-08 11:06:54 -0400
commite7d688d9ade0a43a305deb5cc73b0a8cde20956f (patch)
treee7b293e6f4c14cd6b2dea46db5a95eec76c7ec74
parent5a7de054d9af65d2888d4c8075766d5535be30b5 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/pt.c118
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic107.C15
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