https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101904
--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>: https://gcc.gnu.org/g:47543e5f9d1fc502be79f91c87cbeb6eda17e641 commit r12-3346-g47543e5f9d1fc502be79f91c87cbeb6eda17e641 Author: Patrick Palka <ppa...@redhat.com> Date: Fri Sep 3 11:33:41 2021 -0400 c++: shortcut bad convs during overload resolution [PR101904] In the context of overload resolution we have the notion of a "bad" argument conversion, which is a conversion that "would be a permitted with a bending of the language standards", and we handle such bad conversions specially. In particular, we rank a bad conversion as better than no conversion but worse than a good conversion, and a bad conversion doesn't necessarily make a candidate unviable. With the flag -fpermissive, we permit the situation where overload resolution selects a candidate that contains a bad conversion (which we call a non-strictly viable candidate). And without the flag, the caller of overload resolution usually issues a distinct permerror in this situation instead. One consequence of this defacto behavior is that in order to distinguish a non-strictly viable candidate from an unviable candidate, if we encounter a bad argument conversion during overload resolution we must keep converting subsequent arguments because a subsequent conversion could render the candidate unviable instead of just non-strictly viable. But checking subsequent arguments can force template instantiations and result in otherwise avoidable hard errors. And in particular, all 'this' conversions are at worst bad, so this means the const/ref-qualifiers of a member function can't be used to prune a candidate quickly, which is the subject of the mentioned PR. This patch tries to improve the situation without changing the defacto output of add_candidates. Specifically, when considering a candidate during overload resolution this patch makes us shortcut argument conversion checking upon encountering the first bad conversion (tentatively marking the candidate as non-strictly viable, though it could ultimately be unviable) under the assumption that we'll eventually find a strictly viable candidate anyway (which renders moot the distinction between non-strictly viable and unviable, since both are worse than a strictly viable candidate). If this assumption turns out to be false, we'll fully reconsider the candidate under the defacto behavior (without the shortcutting) so that all its conversions are computed. So in the best case (there's a strictly viable candidate), we avoid some argument conversions and/or template argument deduction that may cause a hard error. In the worst case (there's no such candidate), we have to redundantly consider some candidates twice. (In a previous version of the patch, to avoid this redundant checking I created a new "deferred" conversion type that represents a conversion that is yet to be computed, and instead of reconsidering a candidate I just realized its deferred conversions. But it doesn't seem this redundancy is a significant performance issue to justify the added complexity of this other approach.) PR c++/101904 gcc/cp/ChangeLog: * call.c (build_this_conversion): New function, split out from add_function_candidate. (add_function_candidate): New parameter shortcut_bad_convs. Document it. Use build_this_conversion. Stop at the first bad argument conversion when shortcut_bad_convs is true. (add_template_candidate_real): New parameter shortcut_bad_convs. Use build_this_conversion to check the 'this' conversion before attempting deduction. When the rejection reason code is rr_bad_arg_conversion, pass -1 instead of 0 as the viable parameter to add_candidate. Pass 'convs' to add_candidate. (add_template_candidate): New parameter shortcut_bad_convs. (add_template_conv_candidate): Pass false as shortcut_bad_convs to add_template_candidate_real. (add_candidates): Prefer to shortcut bad conversions during overload resolution under the assumption that we'll eventually see a strictly viable candidate. If this assumption turns out to be false, re-process the non-strictly viable candidates without shortcutting those bad conversions. gcc/testsuite/ChangeLog: * g++.dg/template/conv17.C: New test.