Backported also got GCC 14 as:
https://gcc.gnu.org/cgit/gcc/commit/?id=11e8abd241128cf23b1da1eb5ce6db4cfefa55e9

On Thu, Feb 5, 2026 at 9:43 AM Tomasz Kaminski <[email protected]> wrote:

>
>
> On Mon, Jan 19, 2026 at 12:54 PM Jonathan Wakely <[email protected]>
> wrote:
>
>> On Mon, 19 Jan 2026 at 11:01, Tomasz Kaminski <[email protected]>
>> wrote:
>> >
>> >
>> >
>> > On Mon, Jan 19, 2026 at 11:53 AM Jonathan Wakely <[email protected]>
>> wrote:
>> >>
>> >> On Mon, 19 Jan 2026 at 08:44, Tomasz Kamiński <[email protected]>
>> wrote:
>> >> >
>> >> > 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 hat erogenous
>> calls.
>> >>
>> >> I'm not sure what "hat erogenous" was meant to say :-)
>> >
>> > "heterogeneous"
>> >>
>> >>
>> >> >
>> >> > This patch addresses above, by also checking for free-functions and
>> member
>> >> > overloads of operator<=>, before fall backing to pointer comparison.
>> We do
>> >>
>> >> "falling back"
>> >>
>> >> > not put any contains on the return type of selected operator, in
>> particular
>> >>
>> >> "contains" -> "constraints"
>> >>
>> >> > 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.
>> >>
>> >> I would have missed checking the reversed args, and the unconventional
>> >> return types from operator<=>.
>> >
>> > I also missed them originally, but decided it would be worthwhile to
>> test mixed operators,
>> > and they failed for (const char*, CSTr) cases.
>> >>
>> >>
>> >> > 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.
>> >>
>> >> A nice solution - thanks.
>> >>
>> >> OK for trunk with the commit message fixes mentioned above.
>> >
>> > What about backports? It is C++20, but produces hard to debug issues.
>> > (I was thinking about letting it sit for a week or two and then
>> backporting it).
>>
>> Yes, I agree with that plan, then backport to gcc-15. We can consider
>> backporting further if we think users will still care about using
>> C++20 with gcc-14. I think gcc-13 doesn't matter for C++20 now.
>>
> I have just backported the patch to GCC-15. I will also backport is to
> GCC-14, as we already use if constexpr as extension in this versions,
> and operator<=> was one of the first features I started using with C++20.
>

Reply via email to