[clang] [Clang][Sema] Print more static_assert exprs (PR #74852)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 9 09:50:02 PST 2024


================
@@ -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 at +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 at +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 at +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 at +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}}
----------------
erichkeane wrote:

I really like the idea of printing enum values (though we obviously have to revert to the number in cases where there isn't a value).

However, these longer ones make me wonder if we should be printing JUST the differences here instead of all of this.  I realize this is a divergence in the direction of this patch, but feels like it would be a MUCH nicer experience.

MAYBE it is a second note?  And perhaps it should only happen when there is no user-defined == (and maybe the printing everythign should only happen in that case?).

Consider:

```
struct S {
int a,b,c;
};
constexpr bool operator==(const S&, const S&) { return false;}

static_assert(S{1,2,3} == S{1,2,3});
```

This diagnostic would be REALLY confusing as is, right?  'static-assert-failed' followed by 'S{1,2,3} != S{1,2,3}`.

https://github.com/llvm/llvm-project/pull/74852


More information about the cfe-commits mailing list