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
{
/* 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
}
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;
arg = error_mark_node;
}
- if (saw_undeduced == 1)
- --processing_template_decl;
input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
--- /dev/null
+// 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