https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114153

--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <[email protected]>:

https://gcc.gnu.org/g:8fad43b7850a99b32c48570fc2a3d8ae5a76542a

commit r16-6898-g8fad43b7850a99b32c48570fc2a3d8ae5a76542a
Author: Tomasz KamiÅski <[email protected]>
Date:   Fri Jan 16 14:01:53 2026 +0100

    libstdc++: Use overload operator<=> when provided in relational functors
[PR114153]

    The implementation of less<> did not consider the possibility of t < u
being
    rewritten from overloaded operator<=>. This lead to situation when for t,u
that:
    * provide overload operator<=>, such that (t < u) is rewritten to (t <=> u)
< 0,
    * are convertible to pointers,
    the expression std::less<>(t, u) would incorrectly result in call of
    std::less<void*> on values converted to the pointers, instead of t < u.
    The similar issues also occurred for greater<>, less_equal<>,
greater_equal<>,
    their range equivalents, and in three_way_compare for heterogeneous calls.

    This patch addresses above, by also checking for free-functions and member
    overloads of operator<=>, before falling back to pointer comparison. We do
    not put any constraints on the return type of selected operator, in
particular
    in being one of the standard defined comparison categories, as the language
    does not put any restriction of returned type, and if (t <=> u) is well
    formed, (t op u) is interpreted as (t <=> u) op 0. If that later expression
    is ill-formed, the expression using op also is (see included tests).

    The relational operator rewrites try both order of arguments, t < u,
    can be rewritten into operator<=>(t, u) < 0 or 0 < operator<=>(u, t), it
    means that we need to test both operator<=>(T, U) and operator<=>(U, T)
    if T and U are not the same types. This is now extracted into
    __not_overloaded_spaceship helper concept, placed in <concepts>, to
    avoid extending set of includes.

    The compare_three_way functor defined in compare, already considers
overloaded
    operator<=>, however it does not consider reversed candidates, leading
    to situation in which t <=> u results in 0 <=> operator<=>(u, t), while
    compare_three_way{}(t, u) uses pointer comparison. This is also addressed
by
    using __not_overloaded_spaceship, that check both order of arguments.

    Finally, as operator<=> is introduced in C++20, for std::less(_equal)?<>,
    std::greater(_equal)?<>, we use provide separate __ptr_cmp implementation
    in that mode, that relies on use of requires expression. We use a nested
    requires clause to guarantee short-circuiting of their evaluation.
    The operator() of aforementioned functors is reworked to use if constexpr,
    in all standard modes (as we allow is as extension), eliminating the need
    for _S_cmp function.

            PR libstdc++/114153

    libstdc++-v3/ChangeLog:

            * include/bits/ranges_cmp.h (__detail::__less_builtin_ptr_cmp):
            Add __not_overloaded_spaceship spaceship check.
            * include/bits/stl_function.h (greater<void>::operator())
            (less<void>::operator(), greater_equal<void>::operator())
            (less_equal<void>::operator()): Implement using if constexpr.
            (greater<void>::__S_cmp, less<void>::__S_cmp)
            (greater_equal<void>::__ptr_comp, less_equal<void>::S_cmp):
            Remove.
            (greater<void>::__ptr_cmp, less<void>::__ptr_cmp)
            (greater_equal<void>::__ptr_comp, less_equal<void>::ptr_cmp):
Change
            tostatic constexpr variable. Define in terms of requires
expressions
            and __not_overloaded_spaceship check.
            * include/std/concepts: (__detail::__not_overloaded_spaceship):
            Define.
            * libsupc++/compare: (__detail::__3way_builtin_ptr_cmp): Use
            __not_overloaded_spaceship concept.
            *
testsuite/20_util/function_objects/comparisons_pointer_spaceship.cc: New test.

    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz KamiÅski <[email protected]>

Reply via email to