PR c++/85765 - SFINAE and non-type default template arg.

* pt.c (type_unification_real): Do full semantic processing if
	substituting a partial args list replaces all template parms.

From-SVN: r261146
This commit is contained in:
Jason Merrill 2018-06-04 09:22:52 -04:00 committed by Jason Merrill
parent 1ccaa21f0c
commit 92a38cfd77
3 changed files with 47 additions and 7 deletions

View File

@ -1,3 +1,9 @@
2018-06-04 Jason Merrill <jason@redhat.com>
PR c++/85765 - SFINAE and non-type default template arg.
* pt.c (type_unification_real): Do full semantic processing if
substituting a partial args list replaces all template parms.
2018-06-03 Jason Merrill <jason@redhat.com>
PR c++/85739 - ICE with pointer to member template parm.

View File

@ -20387,8 +20387,6 @@ type_unification_real (tree tparms,
location_t save_loc = input_location;
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
if (saw_undeduced == 1)
++processing_template_decl;
if (saw_undeduced == 1
&& TREE_CODE (parm) == PARM_DECL
@ -20396,11 +20394,14 @@ type_unification_real (tree tparms,
{
/* The type of this non-type parameter depends on undeduced
parameters. Don't try to use its default argument yet,
since we might deduce an argument for it on the next pass,
but do check whether the arguments we already have cause
substitution failure, so that that happens before we try
later default arguments (78489). */
++processing_template_decl;
tree type = tsubst (TREE_TYPE (parm), full_targs, complain,
NULL_TREE);
--processing_template_decl;
if (type == error_mark_node)
arg = error_mark_node;
else
@ -20408,10 +20409,27 @@ type_unification_real (tree tparms,
}
else
{
arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
tree substed = NULL_TREE;
if (saw_undeduced == 1 && processing_template_decl == 0)
{
/* First instatiate in template context, in case we still
depend on undeduced template parameters. */
++processing_template_decl;
substed = tsubst_template_arg (arg, full_targs, complain,
NULL_TREE);
--processing_template_decl;
if (substed != error_mark_node
&& !uses_template_parms (substed))
/* We replaced all the tparms, substitute again out of
template context. */
substed = NULL_TREE;
}
if (!substed)
substed = tsubst_template_arg (arg, full_targs, complain,
NULL_TREE);
if (!uses_template_parms (arg))
arg = convert_template_argument (parm, arg, full_targs,
if (!uses_template_parms (substed))
arg = convert_template_argument (parm, substed, full_targs,
complain, i, NULL_TREE);
else if (saw_undeduced == 1)
arg = NULL_TREE;
@ -20419,8 +20437,6 @@ type_unification_real (tree tparms,
arg = error_mark_node;
}
if (saw_undeduced == 1)
--processing_template_decl;
input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();

View File

@ -0,0 +1,18 @@
// PR c++/85765
// { dg-do compile { target c++11 } }
struct il { il(); il(const il&); };
int* begin(il);
template<class T> T&& declval();
template<class T, class U = decltype(begin(declval<T&>())), decltype(*U(),0) = 0>
U g(T& t, long) { return begin(t); } // #1
template<class T>
int g(T& t, ...); // #2
volatile il a;
auto n = g(a, 0); // calls #1 and ends with a hard error, should call #2