Several recent C++ features are specified to try overload resolution, and if no viable candidate is found, do something else. But our error return doesn't distinguish between that situation and finding multiple viable candidates that end up being ambiguous. We're already trying to separately return the single function we found even if it ends up being ill-formed for some reason; for ambiguity let's pass back error_mark_node, to be distinguished from NULL_TREE meaning no viable candidate. Most callers won't notice the change, as they only look at this information if the call succeeds.
Tested x86_64-pc-linux-gnu, applying to trunk. gcc/cp/ChangeLog: * call.c (build_new_op_1): Set *overload for ambiguity. (build_new_method_call_1): Likewise. --- gcc/cp/call.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f1e0bcb796b..221e3de0c70 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6357,6 +6357,8 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, print_z_candidates (loc, candidates); } result = error_mark_node; + if (overload) + *overload = error_mark_node; } else if (TREE_CODE (cand->fn) == FUNCTION_DECL) { @@ -10438,6 +10440,8 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, free (pretty_name); } call = error_mark_node; + if (fn_p) + *fn_p = error_mark_node; } else { base-commit: f7251a2c103bc48775cb9726a4bebeaebde96684 -- 2.27.0