On Wed, 11 Feb 2026 at 02:44, Jakub Jelinek <[email protected]> wrote: > > Hi! > > When implementing expansion statements, cp_perform_range_for_lookup > does for the non-method begin/end: > /* Use global functions with ADL. */ > releasing_vec vec; > > vec_safe_push (vec, range); > > member_begin = perform_koenig_lookup (id_begin, vec, > complain); > if ((complain & tf_error) == 0 && member_begin == id_begin) > return error_mark_node; > *begin = finish_call_expr (member_begin, &vec, false, true, > complain); > member_end = perform_koenig_lookup (id_end, vec, > tf_warning_or_error); > if ((complain & tf_error) == 0 && member_end == id_end) > { > *begin = error_mark_node; > return error_mark_node; > } > *end = finish_call_expr (member_end, &vec, false, true, > complain); > } > > /* Last common checks. */ > if (*begin == error_mark_node || *end == error_mark_node) > { > /* If one of the expressions is an error do no more checks. */ > *begin = *end = error_mark_node; > return error_mark_node; > } > and finish_expansion_stmt uses > iter_type = cp_perform_range_for_lookup (range_temp, &begin_expr, > &end_expr, tf_none); > if (begin_expr != error_mark_node && end_expr != error_mark_node) > { > kind = esk_iterating; > gcc_assert (iter_type); > } > to select iterating over destructuring only if both are > non-error_mark_nodes. > This is not what the standard says right now, but is what > the proposed resolution of CWG 3123 says: > https://cplusplus.github.io/CWG/issues/3123.html > I think for the pre-CWG 3123 wording I'd need to propagate to the > caller whether perform_koenig_lookup was successfull but whether > finish_call_expr succeeded or not should then be done without tf_none > after choosing esk_iterating. > > Anyway, with the hope that CWG 3123 is voted in, this patch adds > a testcase for it.
This was discussed some moments ago on the Core reflector, and it was pointed out that it's quite intentional in the proposed resolution of CWG 3123 that there's no overload resolution used for determining whether iteration is the chosen approach instead of destructuring, just a viability check. As far as I understand the code, finish_call_expr indeed does overload resolution. This additional testcase was provided: https://godbolt.org/z/o39hEs876 In it, overload resolution fails due to an ambiguity, for iteration, and then destructuring is used instead. But the intent of the proposed resolution is that the semantics are (more) similar to what range-for uses, so the intent is that for iteration, only the presence of viable overloads is checked, and then iteration is committed to, and then the testcase should be rejected because the actual attempt to expand with iteration fails due to the aforementioned ambiguity. None of that affects this patch as such, but I think it's worth pointing out where this should eventually be going.
