This patch fixes 78701. The problematic case with a non-type template
arg whose default value is dependent on a previous non-type arg that
failed to be deduced on the first iteration of the loop in
type_unification_real.
Just before the tsubst_template_arg we've already done:
if (TREE_CODE (parm) == PARM_DECL
&& uses_template_parms (TREE_TYPE (parm))
&& saw_undeduced < 2)
continue;
to check the type of the arg is deduced. This patch adds the equivalent
check just after tsubsting, to see if we managed to get all the template
parms replaced. I wasn't sure if it should check for PARM_DECL, perhaps
convert_template_argument can cope with the case of a non-subst template
parm, so checking would save a call to uses_template_parms in the
type-parm case?
Unfortunately because at this point we've pushed some state, we can't
simply 'continue'. Hence I chose to set arg to NULL and check it later.
The deleted continue is the last statement of the loop, hence deleted.
ok?
nathan
--
Nathan Sidwell
2016-12-14 Nathan Sidwell <nat...@acm.org>
PR c++/78701
* pt.c (type_unification_real): Check tsubst arg doesn't have
remaining template parms before converting it.
PR c++/78701
* g++.dg/cpp0x/pr78701.C: New.
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 243580)
+++ cp/pt.c (working copy)
@@ -18987,14 +18987,19 @@ type_unification_real (tree tparms,
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
- arg = convert_template_argument (parm, arg, full_targs, complain,
- i, NULL_TREE);
+ if (!uses_template_parms (arg))
+ arg = convert_template_argument (parm, arg, full_targs, complain,
+ i, NULL_TREE);
+ else if (saw_undeduced < 2)
+ arg = NULL_TREE;
+ else
+ arg = error_mark_node;
input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
if (arg == error_mark_node)
return 1;
- else
+ else if (arg)
{
TREE_VEC_ELT (targs, i) = arg;
/* The position of the first default template argument,
@@ -19002,7 +19007,6 @@ type_unification_real (tree tparms,
Record that. */
if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
- continue;
}
}
Index: testsuite/g++.dg/cpp0x/pr78701.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr78701.C (revision 0)
+++ testsuite/g++.dg/cpp0x/pr78701.C (working copy)
@@ -0,0 +1,9 @@
+// PR c++/58707
+// { dg-do compile { target c++11 } }
+
+// ICE during deduction of default parms
+
+template <class T, T N = T(), bool B = N>
+ void f(T x) {}
+
+template void f<int> (int);