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.

Reply via email to