llvm / llvm-project

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

nameless struct leads to deleted operator== with no diagnostics #92497

Open tiagomacarios opened 4 months ago

tiagomacarios commented 4 months ago

The following code: https://godbolt.org/z/rM83Md9jT

struct S {
    struct {
        bool b;
    };

    bool operator==(const S&) const noexcept = default;
};

bool f(S const& a, S const& b) { return a == b; }

int main() {}

Fails at link time with:

<source>:9:(.text+0x19): undefined reference to `S::operator==(S const&) const'

gcc diagnostics are much better and earlier (compile time):

<source>:9:46: error: use of deleted function 'constexpr bool S::operator==(const S&) const'
    9 | bool f(S const& a, S const& b) { return a == b; }
      |                                              ^
<source>:6:10: note: 'constexpr bool S::operator==(const S&) const' is implicitly deleted because the default definition would be ill-formed:
    6 |     bool operator==(const S&) const noexcept = default;
      |          ^~~~~~~~
<source>:2:5: error: no match for 'operator==' (operand types are 'S::<unnamed struct>' and 'S::<unnamed struct>')
    2 |     struct {
      |     ^~~~~~

Could we add the same warning as gcc?

MitalAshok commented 4 months ago

Definitely a bug. This related snippet:

struct S {
    struct {
        bool b;
    };

    bool operator==(const S&) const noexcept;
};

bool S::operator==(const S&) const noexcept = default;

bool f(S const& a, S const& b) { return a == b; }

is invalid but causes a crash https://godbolt.org/z/1Kj4s8axT

<source>:11:41: error: cannot compile this scalar expression yet
   11 | bool f(S const& a, S const& b) { return a == b; }
      |                                         ^~~~~~
Unexpected placeholder builtin type!
UNREACHABLE executed at /root/llvm-project/clang/lib/CodeGen/CodeGenTypes.cpp:542!
llvmbot commented 4 months ago

@llvm/issue-subscribers-clang-frontend

Author: Tiago (tiagomacarios)

The following code: https://godbolt.org/z/rM83Md9jT ``` struct S { struct { bool b; }; bool operator==(const S&) const noexcept = default; }; bool f(S const& a, S const& b) { return a == b; } int main() {} ``` Fails at link time with: ``` <source>:9:(.text+0x19): undefined reference to `S::operator==(S const&) const' ``` gcc diagnostics are much better and earlier (compile time): ``` <source>:9:46: error: use of deleted function 'constexpr bool S::operator==(const S&) const' 9 | bool f(S const& a, S const& b) { return a == b; } | ^ <source>:6:10: note: 'constexpr bool S::operator==(const S&) const' is implicitly deleted because the default definition would be ill-formed: 6 | bool operator==(const S&) const noexcept = default; | ^~~~~~~~ <source>:2:5: error: no match for 'operator==' (operand types are 'S::<unnamed struct>' and 'S::<unnamed struct>') 2 | struct { | ^~~~~~ ``` Could we add the same warning as gcc?
shafik commented 4 months ago

Worth noting edg/MSVC accept, the original example: https://godbolt.org/z/GMv36vYKr

CC @Endilll

zygoloid commented 4 months ago

Ideally it seems like we should accept this, and compare the anonymous struct member elementwise.