https://github.com/VachanVY updated 
https://github.com/llvm/llvm-project/pull/211785

>From 5116d7949696f434790773fa95831cff75cf4852 Mon Sep 17 00:00:00 2001
From: Vachan V Y <[email protected]>
Date: Fri, 24 Jul 2026 18:36:19 +0530
Subject: [PATCH] [Clang] Add thousands-separator to "cannot allocate array;
 evaluated array bound [...] exceeds the limit" diagnostic

---
 clang/docs/ReleaseNotes.md                      |  5 +++++
 clang/include/clang/Basic/DiagnosticASTKinds.td |  2 +-
 clang/lib/AST/ByteCode/InterpHelpers.h          | 17 ++++++++++++++++-
 clang/lib/AST/ExprConstant.cpp                  | 17 ++++++++++++++++-
 clang/test/AST/ByteCode/dynalloc-limits.cpp     |  4 ++--
 .../SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp |  4 ++--
 6 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 052838ef0af0d..634adef8a947e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -123,6 +123,11 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 
 ### Improvements to Clang's diagnostics
 
+- The diagnostic emitted when a constant-evaluated array allocation exceeds the
+  limit now formats the evaluated bound and the limit with thousands separators
+  and uses the clearer wording "exceeds the limit of" (e.g. "evaluated array
+  bound 1,048,577 exceeds the limit of 1,048,576"). (#GH211770)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index f86f0157b2b1f..658750d25251a 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -355,7 +355,7 @@ def note_constexpr_new_negative : Note<
 def note_constexpr_new_too_large : Note<
   "cannot allocate array; evaluated array bound %0 is too large">;
 def note_constexpr_new_exceeds_limits : Note<
-  "cannot allocate array; evaluated array bound %0 exceeds the limit (%1); "
+  "cannot allocate array; evaluated array bound %0 exceeds the limit of %1; "
   "use '-fconstexpr-steps' to increase this limit">;
 def note_constexpr_new_too_small : Note<
   "cannot allocate array; evaluated array bound %0 is too small to hold "
diff --git a/clang/lib/AST/ByteCode/InterpHelpers.h 
b/clang/lib/AST/ByteCode/InterpHelpers.h
index 4d908d1e44546..960801ad891f1 100644
--- a/clang/lib/AST/ByteCode/InterpHelpers.h
+++ b/clang/lib/AST/ByteCode/InterpHelpers.h
@@ -90,12 +90,27 @@ bool handleOverflow(InterpState &S, CodePtr OpPC, const T 
&SrcValue) {
   return S.noteUndefinedBehavior();
 }
 
+/// Format an integer with a thousands separator (',') for use in diagnostics,
+inline std::string toStringWithThousandsSeparator(uint64_t Value) {
+  std::string Digits = std::to_string(Value);
+  std::string Result;
+  size_t Len = Digits.size();
+  Result.reserve(Len + (Len - 1) / 3);
+  for (size_t I = 0; I < Len; ++I) {
+    if (I != 0 && (Len - I) % 3 == 0)
+      Result.push_back(',');
+    Result.push_back(Digits[I]);
+  }
+  return Result;
+}
+
 inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) {
   uint64_t Limit = S.getLangOpts().ConstexprStepLimit;
   if (Limit != 0 && NumElems > Limit) {
     S.FFDiag(S.Current->getSource(OpPC),
              diag::note_constexpr_new_exceeds_limits)
-        << NumElems << Limit;
+        << toStringWithThousandsSeparator(NumElems)
+        << toStringWithThousandsSeparator(Limit);
     return false;
   }
   return true;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 574dd8b04e779..cebb84965f081 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -79,6 +79,20 @@ using llvm::APSInt;
 using llvm::APFloat;
 using llvm::FixedPointSemantics;
 
+/// Format an integer with a thousands separator (',') for use in diagnostics,
+static std::string toStringWithThousandsSeparator(uint64_t Value) {
+  std::string Digits = std::to_string(Value);
+  std::string Result;
+  size_t Len = Digits.size();
+  Result.reserve(Len + (Len - 1) / 3);
+  for (size_t I = 0; I < Len; ++I) {
+    if (I != 0 && (Len - I) % 3 == 0)
+      Result.push_back(',');
+    Result.push_back(Digits[I]);
+  }
+  return Result;
+}
+
 namespace {
   struct LValue;
   class CallStackFrame;
@@ -976,7 +990,8 @@ namespace {
       if (Limit != 0 && ElemCount > Limit) {
         if (Diag)
           FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
-              << ElemCount << Limit;
+              << toStringWithThousandsSeparator(ElemCount)
+              << toStringWithThousandsSeparator(Limit);
         return false;
       }
       return true;
diff --git a/clang/test/AST/ByteCode/dynalloc-limits.cpp 
b/clang/test/AST/ByteCode/dynalloc-limits.cpp
index ed2d4faf974b1..decf1e2b24c3d 100644
--- a/clang/test/AST/ByteCode/dynalloc-limits.cpp
+++ b/clang/test/AST/ByteCode/dynalloc-limits.cpp
@@ -54,7 +54,7 @@ constexpr std::size_t s = S<std::size_t>(~0UL)[42]; // 
both-error {{constexpr va
 constexpr std::size_t ssmall = S<std::size_t>(100)[42];
 
 constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // both-error {{constexpr 
variable 's5' must be initialized by a constant expression}} \
-                                   // both-note@#alloc {{cannot allocate 
array; evaluated array bound 1025 exceeds the limit (1024); use 
'-fconstexpr-steps' to increase this limit}} \
+                                   // both-note@#alloc {{cannot allocate 
array; evaluated array bound 1,025 exceeds the limit of 1,024; use 
'-fconstexpr-steps' to increase this limit}} \
                                    // both-note@#call {{in call to 
'this->alloc.allocate(1025)'}} \
                                    // both-note {{in call}}
 
@@ -62,7 +62,7 @@ constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // 
both-error {{constexpr v
 
 template <auto N>
 constexpr int stack_array() {
-    [[maybe_unused]] char BIG[N] = {1};  // both-note {{cannot allocate array; 
evaluated array bound 1025 exceeds the limit (1024)}}
+    [[maybe_unused]] char BIG[N] = {1};  // both-note {{cannot allocate array; 
evaluated array bound 1,025 exceeds the limit of 1,024}}
     return BIG[N-1];
 }
 
diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp 
b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp
index 8bcb4d45d4af8..dd133ca4b14e0 100644
--- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp
+++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp
@@ -65,7 +65,7 @@ constexpr std::size_t s4 = S<std::size_t>(1024)[42]; // 
expected-error {{constex
 
 
 constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // 
expected-error{{constexpr variable 's5' must be initialized by a constant 
expression}} \
-                                   // expected-note@#alloc {{cannot allocate 
array; evaluated array bound 1025 exceeds the limit (1024); use 
'-fconstexpr-steps' to increase this limit}} \
+                                   // expected-note@#alloc {{cannot allocate 
array; evaluated array bound 1,025 exceeds the limit of 1,024; use 
'-fconstexpr-steps' to increase this limit}} \
                                    // expected-note@#call {{in call to 
'this->alloc.allocate(1025)'}} \
                                    // expected-note {{in call}}
 
@@ -75,7 +75,7 @@ constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // 
expected-error{{constexp
 
 template <auto N>
 constexpr int stack_array() {
-    [[maybe_unused]] char BIG[N] = {1};  // expected-note  3{{cannot allocate 
array; evaluated array bound 1025 exceeds the limit (1024); use 
'-fconstexpr-steps' to increase this limit}}
+    [[maybe_unused]] char BIG[N] = {1};  // expected-note  3{{cannot allocate 
array; evaluated array bound 1,025 exceeds the limit of 1,024; use 
'-fconstexpr-steps' to increase this limit}}
     return BIG[N-1];
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to