[clang] [clang] Print static_assert values of arithmetic binary operators (PR #71671)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 23 23:20:11 PST 2023


Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/71671 at github.com>


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71671

>From a4db205a672220282735af1c7fcee1b47b334dd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 8 Nov 2023 13:32:41 +0100
Subject: [PATCH 1/2] [clang] Print static_assert values of arithmetic binary
 operators

These are actually quite useful to print.
---
 clang/lib/Sema/SemaDeclCXX.cpp         |  8 ++++----
 clang/test/SemaCXX/complex-folding.cpp | 27 +++++++++++++++++---------
 clang/test/SemaCXX/static-assert.cpp   | 10 ++++++++++
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3688192e6cbe5c5..91c9a82bcfa0edc 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -17218,10 +17218,10 @@ static bool UsefulToPrintExpr(const Expr *E) {
   if (const auto *UnaryOp = dyn_cast<UnaryOperator>(E))
     return UsefulToPrintExpr(UnaryOp->getSubExpr());
 
-  // Ignore nested binary operators. This could be a FIXME for improvements
-  // to the diagnostics in the future.
-  if (isa<BinaryOperator>(E))
-    return false;
+  // Only print nested arithmetic operators.
+  if (const auto *BO = dyn_cast<BinaryOperator>(E))
+    return (BO->isShiftOp() || BO->isAdditiveOp() || BO->isMultiplicativeOp() ||
+            BO->isBitwiseOp());
 
   return true;
 }
diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp
index 8c56cf0e5d984b0..054f159e9ce0dd2 100644
--- a/clang/test/SemaCXX/complex-folding.cpp
+++ b/clang/test/SemaCXX/complex-folding.cpp
@@ -3,7 +3,8 @@
 // Test the constant folding of builtin complex numbers.
 
 static_assert((0.0 + 0.0j) == (0.0 + 0.0j));
-static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}}
+static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}} \
+                                             // expected-note {{evaluates to}}
 
 static_assert((0.0 + 0.0j) == 0.0);
 static_assert(0.0 == (0.0 + 0.0j));
@@ -14,21 +15,29 @@ static_assert(0.0 != 1.0j);
 
 // Walk around the complex plane stepping between angular differences and
 // equality.
-static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}}
+static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}} \
+                                             // expected-note {{evaluates to}}
 static_assert((1.0 + 0.0j) == (1.0 + 0.0j));
-static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}}
+static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}} \
+                                             // expected-note {{evaluates to}}
 static_assert((1.0 + 1.0j) == (1.0 + 1.0j));
-static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}}
+static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}} \
+                                             // expected-note {{evaluates to}}
 static_assert((0.0 + 1.0j) == (0.0 + 1.0j));
-static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}}
+static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}} \
+                                              // expected-note {{evaluates to}}
 static_assert((-1.0 + 1.0j) == (-1.0 + 1.0j));
-static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}}
+static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}} \
+                                               // expected-note {{evaluates to}}
 static_assert((-1.0 + 0.0j) == (-1.0 + 0.0j));
-static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}}
+static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}} \
+                                               // expected-note {{evaluates to}}
 static_assert((-1.0 - 1.0j) == (-1.0 - 1.0j));
-static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}}
+static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}} \
+                                              // expected-note {{evaluates to}}
 static_assert((0.0 - 1.0j) == (0.0 - 1.0j));
-static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}}
+static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}} \
+                                             // expected-note {{evaluates to}}
 static_assert((1.0 - 1.0j) == (1.0 - 1.0j));
 
 // Test basic mathematical folding of both complex and real operands.
diff --git a/clang/test/SemaCXX/static-assert.cpp b/clang/test/SemaCXX/static-assert.cpp
index 4200d821339edeb..6e1701602ae30cf 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -351,4 +351,14 @@ namespace Diagnostics {
     ""
   );
 
+  static_assert(1 + 1 != 2, ""); // expected-error {{failed}} \
+                                 // expected-note {{evaluates to '2 != 2'}}
+  static_assert(1 - 1 == 2, ""); // expected-error {{failed}} \
+                                 // expected-note {{evaluates to '0 == 2'}}
+  static_assert(1 * 1 == 2, ""); // expected-error {{failed}} \
+                                 // expected-note {{evaluates to '1 == 2'}}
+  static_assert(1 / 1 == 2, ""); // expected-error {{failed}} \
+                                 // expected-note {{evaluates to '1 == 2'}}
+  static_assert(1 << 3 != 8, ""); // expected-error {{failed}} \
+                                 // expected-note {{evaluates to '8 != 8'}}
 }

>From 0519abefdfba6649b073f317e6e6a7a3dd7a84bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 24 Nov 2023 08:19:41 +0100
Subject: [PATCH 2/2] Add release note

---
 clang/docs/ReleaseNotes.rst | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5fdc061c32cb998..7182f702c3e379a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -457,6 +457,22 @@ Improvements to Clang's diagnostics
   with GCC.
 - Clang will warn on deprecated specializations used in system headers when their instantiation
   is caused by user code.
+- Clang will now print ``static_assert`` failure details for arithmetic binary operators.
+  Example:
+
+  .. code-block:: c++
+    static_assert(1 << 4 == 15);
+
+  will now print:
+
+  .. code-block:: text
+    error: static assertion failed due to requirement '1 << 4 == 15'
+       48 | static_assert(1 << 4 == 15);
+          |               ^~~~~~~~~~~~
+    note: expression evaluates to '16 == 15'
+       48 | static_assert(1 << 4 == 15);
+          |               ~~~~~~~^~~~~
+
 
 Improvements to Clang's time-trace
 ----------------------------------



More information about the cfe-commits mailing list