================ @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +struct A { + int a, b[3], c; + bool operator==(const A&) const = default; +}; + +constexpr auto a0 = A{0, 0, 3, 4, 5}; + +// expected-note@+1 {{evaluates to 'A{0, {0, 3, 4}, 5} == A{1, {2, 3, 4}, 5}'}} +static_assert(a0 == A{1, {2, 3, 4}, 5}); // expected-error {{failed}} + +struct _arr { + const int b[3]; + constexpr bool operator==(const int rhs[3]) const { + for (unsigned i = 0; i < sizeof(b) / sizeof(int); i++) + if (b[i] != rhs[i]) + return false; + return true; + } +}; + +// expected-note@+1 {{{evaluates to '_arr{{2, 3, 4}} == (int[3]){0, 3, 4}'}}} +static_assert(_arr{2, 3, 4} == a0.b); // expected-error {{failed}} + +struct B { + int a, c; // named the same just to keep things fresh + bool operator==(const B&) const = default; +}; + +// expected-note@+1 {{evaluates to 'B{7, 6} == B{8, 6}'}} +static_assert(B{7, 6} == B{8, 6}); // expected-error {{failed}} + +typedef int v4si __attribute__((__vector_size__(16))); + +struct C: A, B { + enum { E1, E2 } e; + bool operator==(const C&) const = default; +}; + +constexpr auto cc = C{A{1, {2, 3, 4}, 5}, B{7, 6}, C::E1}; + +// expected-note@+1 {{{evaluates to 'C{{1, {2, 3, 4}, 5}, {7, 6}, 0} == C{{0, {0, 3, 4}, 5}, {5, 0}, 1}'}}} +static_assert(cc == C{a0, {5}, C::E2}); // expected-error {{failed}} ---------------- sethp wrote:
It is confusing, but I don't think this change makes it any worse; the output I see from clang with my change is: ```c++ clang/test/SemaCXX/static-assert-diagnostics.cpp:177:15: error: static assertion failed due to requirement 'S{1, 2, 3} == S{1, 2, 3}' 177 | static_assert(S{1,2,3} == S{1,2,3}); | ^~~~~~~~~~~~~~~~~~~~ clang/test/SemaCXX/static-assert-diagnostics.cpp:177:24: note: expression evaluates to 'S{1, 2, 3} == S{1, 2, 3}' 177 | static_assert(S{1,2,3} == S{1,2,3}); | ~~~~~~~~~^~~~~~~~~~~ ``` The `note` this change adds is redundant, sure, but I don't think it's more confusing than omitting it: either way, I'm going to go hunt for an `operator==` between two `S`s and see if I can figure out why two things that sure feel like they _ought_ to be `==` aren't. A different example with the same `operator==` overload there might be something like this: ``` struct alignas(int) S { unsigned char a, b, c; }; constexpr bool operator==(const S&, const S&) { return false; } static_assert(S{1, 2, 3} == std::bit_cast<S>(0x030201)); ``` Which now outputs: ``` clang/test/SemaCXX/static-assert-diagnostics.cpp:177:15: error: static assertion failed due to requirement 'S{1, 2, 3} == std::bit_cast(197121)' 177 | static_assert(S{1, 2, 3} == std::bit_cast<S>(0x030201)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ clang/test/SemaCXX/static-assert-diagnostics.cpp:177:26: note: expression evaluates to 'S{1, 2, 3} == struct S{1, 2, 3}' 177 | static_assert(S{1, 2, 3} == std::bit_cast<S>(0x030201)); | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` Here the note is, I think, quite helpful: to me it very strongly suggests to me that the issue isn't the `bit_cast` or a endian-ness mismatch or anything like that, but the `operator==` implementation. https://github.com/llvm/llvm-project/pull/74852 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits