llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.03k stars 11.96k forks source link

default equality operator== const selects not-const conversion operator #102588

Closed Fedr closed 2 months ago

Fedr commented 3 months ago

This program

struct A {
    int i = 0;
    constexpr operator int() const { return i; }
    constexpr operator int&() { return ++i; }
};

struct B : A {
    bool operator==(const B &) const = default;
};

constexpr bool f() {
    B x;
    return x == x;
}

static_assert( f() ); // fails in Clang

is accepted by GCC and MSVC, but fails static assertion in Clang. Online demo: https://gcc.godbolt.org/z/5hYob3K66

Clang looks wrong here, because not-const operator int& should not be called from within B::operator==(const B &) const.

Related discussion: https://stackoverflow.com/q/78850335/7325599

llvmbot commented 3 months ago

@llvm/issue-subscribers-clang-frontend

Author: Fedor Chelnokov (Fedr)

This program ``` struct A { int i = 0; constexpr operator int() const { return i; } constexpr operator int&() { return ++i; } }; struct B : A { bool operator==(const B &) const = default; }; constexpr bool f() { B x; return x == x; } static_assert( f() ); // fails in Clang ``` is accepted by GCC and MSVC, but fails static assertion in Clang. Online demo: https://gcc.godbolt.org/z/5hYob3K66 Clang looks wrong here, because not-const `operator int&` should not be called from within `B::operator==(const B &) const`. Related discussion: https://stackoverflow.com/q/78850335/7325599