[clang] [clang] Avoid printing overly large integer/_BitInt numbers in static assertion failure diagnostics #71675 (PR #145053)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 26 07:12:22 PDT 2025


https://github.com/maramatias updated https://github.com/llvm/llvm-project/pull/145053

>From 8589275000bc7012c651866d04465876d43d0cf9 Mon Sep 17 00:00:00 2001
From: Mara Matias <mara.matias1 at gmail.com>
Date: Wed, 18 Jun 2025 09:06:10 -0700
Subject: [PATCH] [clang] Avoid printing overly large integer/_BitInt numbers
 in static assertion failure diagnostics #71675

---
 clang/docs/ReleaseNotes.rst          |  4 ++++
 clang/lib/Sema/SemaDeclCXX.cpp       | 17 ++++++++++++++++-
 clang/test/AST/ByteCode/intap.cpp    |  8 ++++----
 clang/test/Sema/enum.c               |  2 +-
 clang/test/SemaCXX/static-assert.cpp |  6 ++++++
 5 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96477ef6ddc9a..5a3e234ea1bcd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -642,6 +642,10 @@ Improvements to Clang's diagnostics
   #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490,
   #GH36703, #GH32903, #GH23312, #GH69874.
 
+- Improved the performance of static assertions envolving large integers by
+  using hex format instead of string.
+
+  Fixes #GH71675
 
 Improvements to Clang's time-trace
 ----------------------------------
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 16645ecf411e5..c45eafeca5f04 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -47,6 +47,7 @@
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/Template.h"
 #include "clang/Sema/TemplateDeduction.h"
+#include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
@@ -17575,7 +17576,21 @@ static bool ConvertAPValueToString(const APValue &V, QualType T,
           break;
         }
       }
-      V.getInt().toString(Str);
+
+      llvm::APSInt vInt = V.getInt();
+      if (llvm::APSInt::compareValues(
+              vInt, llvm::APSInt::getUnsigned(
+                        std::numeric_limits<uint64_t>::max())) >= 0 ||
+          vInt < std::numeric_limits<int64_t>::min()) {
+        // The value of cutSize is not special, it is just a number of
+        // characters that gives us enough info without losing readability
+        const int cutSize = 20;
+        vInt.toString(Str, 16);
+        Str.erase(Str.begin() + cutSize, Str.end() - cutSize);
+        Str.insert(Str.begin() + cutSize, 3, '.');
+      } else {
+        vInt.toString(Str);
+      }
     }
 
     break;
diff --git a/clang/test/AST/ByteCode/intap.cpp b/clang/test/AST/ByteCode/intap.cpp
index 3f952ddf626b5..c32b8d67baf8b 100644
--- a/clang/test/AST/ByteCode/intap.cpp
+++ b/clang/test/AST/ByteCode/intap.cpp
@@ -79,12 +79,12 @@ typedef unsigned __int128 uint128_t;
 static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
 static_assert(UINT128_MAX == -1, "");
 static_assert(UINT128_MAX == 1, ""); // both-error {{static assertion failed}} \
-                                     // both-note {{'340282366920938463463374607431768211455 == 1'}}
+                                     // both-note {{'FFFFFFFFFFFFFFFFFFFF...FFFFFFFFFFFFFFFFFFFF == 1'}}
 
 static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
 static_assert(INT128_MAX != 0, "");
 static_assert(INT128_MAX == 0, ""); // both-error {{failed}} \
-                                    // both-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
+                                    // both-note {{evaluates to '7FFFFFFFFFFFFFFFFFFF...FFFFFFFFFFFFFFFFFFFF == 0'}}
 static const __int128_t INT128_MIN = -INT128_MAX - 1;
 
 
@@ -105,14 +105,14 @@ namespace i128 {
   static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
   static_assert(UINT128_MAX == -1, "");
   static_assert(UINT128_MAX == 1, ""); // both-error {{static assertion failed}} \
-                                       // both-note {{'340282366920938463463374607431768211455 == 1'}}
+                                       // both-note {{'FFFFFFFFFFFFFFFFFFFF...FFFFFFFFFFFFFFFFFFFF == 1'}}
 
   constexpr uint128_t TooMuch = UINT128_MAX * 2;
 
   static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
   static_assert(INT128_MAX != 0, "");
   static_assert(INT128_MAX == 0, ""); // both-error {{failed}} \
-                                      // both-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
+                                      // both-note {{evaluates to '7FFFFFFFFFFFFFFFFFFF...FFFFFFFFFFFFFFFFFFFF == 0'}}
 
   constexpr int128_t TooMuch2 = INT128_MAX * INT128_MAX; // both-error {{must be initialized by a constant expression}} \
                                                          // both-note {{value 28948022309329048855892746252171976962977213799489202546401021394546514198529 is outside the range of representable}}
diff --git a/clang/test/Sema/enum.c b/clang/test/Sema/enum.c
index 01e41d4ebe956..80315a0c29b6a 100644
--- a/clang/test/Sema/enum.c
+++ b/clang/test/Sema/enum.c
@@ -196,7 +196,7 @@ enum GH59352 { // expected-warning {{enumeration values exceed range of largest
  BigVal = 66666666666666666666wb
 };
 _Static_assert(BigVal == 66666666666666666666wb); /* expected-error {{static assertion failed due to requirement 'BigVal == 66666666666666666666wb'}}
-                                                     expected-note {{expression evaluates to '11326434445538011818 == 66666666666666666666'}}
+                                                     expected-note {{expression evaluates to '11326434445538011818 == 39D2F941E420AAAAA<U+0000><U+0000><U+0000>...<U+0000><U+0000><U+0000>39D2F941E420AAAAA'}}
                                                    */
 _Static_assert(
     _Generic(BigVal,                             // expected-error {{static assertion failed}}
diff --git a/clang/test/SemaCXX/static-assert.cpp b/clang/test/SemaCXX/static-assert.cpp
index bf6a2eeb432a3..4b9d23cb8c808 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -255,6 +255,12 @@ int f() {
 }
 }
 
+namespace GH71675 {
+constexpr unsigned _BitInt(__BITINT_MAXWIDTH__ >> 6) F = ~0; // expected-warning {{Clang extension}}
+static_assert(F == 1,""); // expected-error {{static assertion failed due to requirement 'F == 1'}} \
+                          // expected-note {{expression evaluates to 'FFFFFFFFFFFFFFFFFFFF...FFFFFFFFFFFFFFFFFFFF == 1'}}
+} // namespace GH71675
+
 namespace Diagnostics {
   /// No notes for literals.
   static_assert(false, ""); // expected-error {{failed}}



More information about the cfe-commits mailing list