Skip to content

[clang] Rejects-valid enum comparison that bypasses rewritten candidate <=> #147517

Open
@Eisenwave

Description

@Eisenwave

https://godbolt.org/z/vhxbYPq3j

#include <utility>

enum class e { a, b };

inline std::strong_ordering operator<=>(e, e) {
    return std::strong_ordering::less;
}

constexpr bool hoo(e lhs, e rhs) {
    if (lhs < rhs) {
        return true;
    }
    if (rhs >= lhs) {
        return false;
    }
    return false;
}

static_assert(hoo(e::a, e::b), "");

This code fails to compile:

<source>:19:15: error: static assertion expression is not an integral constant expression
   19 | static_assert(hoo(e::a, e::b), "");
      |               ^~~~~~~~~~~~~~~
<source>:10:13: note: non-constexpr function 'operator<=>' cannot be used in a constant expression
   10 |     if (lhs < rhs) {
      |             ^
<source>:19:15: note: in call to 'hoo(0, 1)'
   19 | static_assert(hoo(e::a, e::b), "");
      |               ^~~~~~~~~~~~~~~
<source>:5:29: note: declared here
    5 | inline std::strong_ordering operator<=>(e, e) {
      |                             ^

This error is incorrect. GCC accepts.

https://eel.is/c++draft/over.match.best.general#2.8 states that a function is a better candidate if it is rewritten and the other is not, and there exists a built-in candidate for < (https://eel.is/c++draft/over.match.oper#3.3, https://eel.is/c++draft/over.built) which would thus be better than the rewritten candidate which uses (lhs <=> rhs) < 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second partyrejects-valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions