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

            Bug ID: 105200
           Summary: user-defined operator <=> for enumerated types is
                    ignored
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: falbrechtskirchinger at gmail dot com
  Target Milestone: ---

Version: g++
(Compiler-Explorer-Build-gcc-45fb78c9c456ace1d914c836d15af38ae345b902-binutils-2.36.1)
12.0.1 20220407 (experimental)

Code:

#include <compare>
#include <iostream>

enum class foo { a, b, c, d };

inline std::partial_ordering operator<=>(const foo lhs, const foo rhs) {
        std::cout << "foo <=> called\n";
        return std::partial_ordering::less;
}

int main() {
        std::cout << std::boolalpha;

        bool b1 = foo::b < foo::a;
        std::cout << "foo::b < foo::a := " << b1 << "\n";

        std::cout << "=============\n";

        bool b2 = std::is_lt(foo::b <=> foo::a);
        std::cout << "std::is_lt(foo::b <=> foo::a) := " << b2 << "\n";
}

Comparison of GCC, Clang, MSVC, ICC:
https://godbolt.org/z/n7GnqhMvn


GCC (apparently) always selects the builtin operator <=> for enumerated types
and ignores the user-defined one. GCC's behavior differs from Clang, MSVC, and
ICC (although the latter, despite calling user-defined <=>, still produces the
wrong result).

Of course defining the regular comparison operators works as intended and so
this different behavior with user-defined <=> seems inconsistent, even if it
can be argued that it is to letter of the standard (see [expr.spaceship] on
comparing enumerated types). I disagree with this reading of the standard over
all.

Discussing this on IRC and referring to sections [expr.spaceship],
[over.built], [over.match.oper], and [over.match.best] of the standard no
consensus was reached as to which implementation is correct and I was asked to
open this bug report.

As a reminder to myself: Trying to find a workaround, I deleted operator <
which resulted in a segfault. I should try to re-create this ICE and file a
separate bug.

Reply via email to