[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)
Atousa Duprat via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 4 09:41:33 PST 2024
https://github.com/Atousa updated https://github.com/llvm/llvm-project/pull/80939
>From ac75fc2873fc7b8eec6c24ba97f4673e94457c8e Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Tue, 6 Feb 2024 21:02:05 -0800
Subject: [PATCH 1/8] [clang] Use separator for large numeric values in
overflow diagnostic
Add functionality to APInt::toString() that allows it to insert
separators between groups of digits, using the C++ litteral
separator ' between groups.
Fixes issue #58228
---
clang/lib/AST/ExprConstant.cpp | 6 +-
clang/test/AST/Interp/c.c | 4 +-
clang/test/C/drs/dr0xx.c | 2 +-
clang/test/C/drs/dr2xx.c | 2 +-
clang/test/Sema/integer-overflow.c | 100 ++++++++---------
clang/test/Sema/switch-1.c | 6 +-
clang/test/SemaCXX/enum.cpp | 4 +-
clang/test/SemaCXX/integer-overflow.cpp | 112 ++++++++++----------
clang/test/SemaObjC/integer-overflow.m | 4 +-
clang/test/SemaObjC/objc-literal-nsnumber.m | 2 +-
llvm/include/llvm/ADT/APInt.h | 3 +-
llvm/include/llvm/ADT/StringExtras.h | 5 +-
llvm/lib/Support/APInt.cpp | 24 ++++-
llvm/unittests/ADT/APIntTest.cpp | 35 ++++++
14 files changed, 185 insertions(+), 124 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 089bc2094567f7..d9037072c6767f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2774,7 +2774,8 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
- << toString(Result, 10) << E->getType() << E->getSourceRange();
+ << toString(Result, 10, Result.isSigned(), false, true, true)
+ << E->getType() << E->getSourceRange();
return HandleOverflow(Info, E, Value, E->getType());
}
return true;
@@ -13852,7 +13853,8 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
- << toString(Value, 10) << E->getType() << E->getSourceRange();
+ << toString(Value, 10, Value.isSigned(), false, true, true)
+ << E->getType() << E->getSourceRange();
if (!HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
E->getType()))
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index 9ab271a82aeef9..aa067b0bc74831 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -109,9 +109,9 @@ int somefunc(int i) {
// pedantic-expected-warning {{left operand of comma operator has no effect}} \
// pedantic-expected-warning {{overflow in expression; result is 131073}} \
// ref-warning {{left operand of comma operator has no effect}} \
- // ref-warning {{overflow in expression; result is 131073}} \
+ // ref-warning {{overflow in expression; result is 131'073}} \
// pedantic-ref-warning {{left operand of comma operator has no effect}} \
- // pedantic-ref-warning {{overflow in expression; result is 131073}}
+ // pedantic-ref-warning {{overflow in expression; result is 131'073}}
}
diff --git a/clang/test/C/drs/dr0xx.c b/clang/test/C/drs/dr0xx.c
index d9c1fbe4ee40ab..c93cfb63d604cf 100644
--- a/clang/test/C/drs/dr0xx.c
+++ b/clang/test/C/drs/dr0xx.c
@@ -214,7 +214,7 @@ _Static_assert(__builtin_types_compatible_p(struct S { int a; }, union U { int a
*/
void dr031(int i) {
switch (i) {
- case __INT_MAX__ + 1: break; /* expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} */
+ case __INT_MAX__ + 1: break; /* expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}} */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch"
/* Silence the targets which issue:
diff --git a/clang/test/C/drs/dr2xx.c b/clang/test/C/drs/dr2xx.c
index 9c8d77518ab55e..1b68b65acca6af 100644
--- a/clang/test/C/drs/dr2xx.c
+++ b/clang/test/C/drs/dr2xx.c
@@ -277,7 +277,7 @@ void dr258(void) {
void dr261(void) {
/* This is still an integer constant expression despite the overflow. */
enum e1 {
- ex1 = __INT_MAX__ + 1 /* expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} */
+ ex1 = __INT_MAX__ + 1 /* expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}} */
};
/* This is not an integer constant expression, because of the comma operator,
diff --git a/clang/test/Sema/integer-overflow.c b/clang/test/Sema/integer-overflow.c
index cf822f346e8b29..220fc1bed515a1 100644
--- a/clang/test/Sema/integer-overflow.c
+++ b/clang/test/Sema/integer-overflow.c
@@ -11,169 +11,169 @@ uint64_t f0(uint64_t);
uint64_t f1(uint64_t, uint32_t);
uint64_t f2(uint64_t, ...);
-static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
+static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t check_integer_overflows(int i) {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t overflow = 4608 * 1024 * 1024,
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow2 = (uint64_t)(4608 * 1024 * 1024),
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;
uint64_t not_overflow = 4608 * 1024 * 1024ULL;
uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 0 ? 0 : 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (4608 * 1024 * 1024)
return 0;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 1;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 2;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024 * i))
return 3;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
return 4;
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
return 5;
switch (i) {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case 4608 * 1024 * 1024:
return 6;
-// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case (uint64_t)(4609 * 1024 * 1024):
return 7;
// expected-error at +1 {{expression is not an integer constant expression}}
case ((uint64_t)(4608 * 1024 * 1024 * i)):
return 8;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
return 9;
-// expected-warning at +2 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning at +1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
return 10;
}
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = 4608 * 1024 * 1024;
(uint64_t)(4608 * 1024 * 1024);
i += (uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
_Complex long long x = 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__real__ x) = 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__imag__ x) = 4608 * 1024 * 1024;
-// expected-warning at +4 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +4 {{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning at +3 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}}
// expected-note at +1 {{array 'a' declared here}}
uint64_t a[10];
a[4608 * 1024 * 1024] = 1i;
-// expected-warning at +2 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t *b;
uint64_t b2 = b[4608 * 1024 * 1024] + 1;
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
(void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
}
void check_integer_overflows_in_function_calls(void) {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f0(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t x = f0(4608 * 1024 * 1024);
-// expected-warning at +2 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t (*f0_ptr)(uint64_t) = &f0;
(void)(*f0_ptr)(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f2(0, f0(4608 * 1024 * 1024));
}
void check_integer_overflows_in_array_size(void) {
- int arr[4608 * 1024 * 1024]; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
+ int arr[4608 * 1024 * 1024]; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}
}
struct s {
diff --git a/clang/test/Sema/switch-1.c b/clang/test/Sema/switch-1.c
index 95e64748fb1fbf..09221990ac11d3 100644
--- a/clang/test/Sema/switch-1.c
+++ b/clang/test/Sema/switch-1.c
@@ -7,7 +7,7 @@ int f(int i) {
switch (i) {
case 2147483647 + 2:
#if (__cplusplus <= 199711L) // C or C++03 or earlier modes
- // expected-warning at -2 {{overflow in expression; result is -2147483647 with type 'int'}}
+ // expected-warning at -2 {{overflow in expression; result is -2'147'483'647 with type 'int'}}
#else
// expected-error at -4 {{case value is not a constant expression}} \
// expected-note at -4 {{value 2147483649 is outside the range of representable values of type 'int'}}
@@ -23,7 +23,7 @@ int f(int i) {
return 2;
case (123456 *789012) + 1:
#if (__cplusplus <= 199711L)
- // expected-warning at -2 {{overflow in expression; result is -1375982336 with type 'int'}}
+ // expected-warning at -2 {{overflow in expression; result is -1'375'982'336 with type 'int'}}
#else
// expected-error at -4 {{case value is not a constant expression}} \
// expected-note at -4 {{value 97408265472 is outside the range of representable values of type 'int'}}
@@ -47,7 +47,7 @@ int f(int i) {
case 2147483647:
return 0;
}
- return (i, 65537) * 65537; // expected-warning {{overflow in expression; result is 131073 with type 'int'}} \
+ return (i, 65537) * 65537; // expected-warning {{overflow in expression; result is 131'073 with type 'int'}} \
// expected-warning {{left operand of comma operator has no effect}}
}
diff --git a/clang/test/SemaCXX/enum.cpp b/clang/test/SemaCXX/enum.cpp
index fc65fd16f8c302..c482b3c571ab4a 100644
--- a/clang/test/SemaCXX/enum.cpp
+++ b/clang/test/SemaCXX/enum.cpp
@@ -103,7 +103,7 @@ enum { overflow = 123456 * 234567 };
// expected-warning at -2 {{not an integral constant expression}}
// expected-note at -3 {{value 28958703552 is outside the range of representable values}}
#else
-// expected-warning at -5 {{overflow in expression; result is -1106067520 with type 'int'}}
+// expected-warning at -5 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
#endif
// FIXME: This is not consistent with the above case.
@@ -112,7 +112,7 @@ enum NoFold : int { overflow2 = 123456 * 234567 };
// expected-error at -2 {{enumerator value is not a constant expression}}
// expected-note at -3 {{value 28958703552 is outside the range of representable values}}
#else
-// expected-warning at -5 {{overflow in expression; result is -1106067520 with type 'int'}}
+// expected-warning at -5 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
// expected-warning at -6 {{extension}}
#endif
diff --git a/clang/test/SemaCXX/integer-overflow.cpp b/clang/test/SemaCXX/integer-overflow.cpp
index 0e8ad050aa14d8..6049458b93bbd0 100644
--- a/clang/test/SemaCXX/integer-overflow.cpp
+++ b/clang/test/SemaCXX/integer-overflow.cpp
@@ -13,157 +13,157 @@ uint64_t f0(uint64_t);
uint64_t f1(uint64_t, uint32_t);
uint64_t f2(uint64_t, ...);
-static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536870912 with type 'int'}}
+static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-warning {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t check_integer_overflows(int i) { //expected-note 0+{{declared here}}
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t overflow = 4608 * 1024 * 1024,
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow2 = (uint64_t)(4608 * 1024 * 1024),
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow3 = (uint64_t)(4608 * 1024 * 1024 * i),
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL),
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow5 = static_cast<uint64_t>(4608 * 1024 * 1024),
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
multi_overflow = (uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow += overflow2 = overflow3 = static_cast<uint64_t>(4608 * 1024 * 1024);
uint64_t not_overflow = 4608 * 1024 * 1024ULL;
uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
overflow = 0 ? 0 : 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (4608 * 1024 * 1024)
return 0;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 1;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if (static_cast<uint64_t>(4608 * 1024 * 1024))
return 1;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024))
return 2;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)(4608 * 1024 * 1024 * i))
return 3;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL))
return 4;
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
if ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)))
return 5;
#if __cplusplus < 201103L
switch (i) {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case 4608 * 1024 * 1024:
return 6;
-// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case (uint64_t)(4609 * 1024 * 1024):
return 7;
-// expected-warning at +1 {{overflow in expression; result is 537919488 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 537'919'488 with type 'int'}}
case 1 + static_cast<uint64_t>(4609 * 1024 * 1024):
return 7;
// expected-error at +1 {{expression is not an integral constant expression}}
case ((uint64_t)(4608 * 1024 * 1024 * i)):
return 8;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
return 9;
-// expected-warning at +2 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 2{{overflow in expression; result is 536'870'912 with type 'int'}}
// expected-warning at +1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
return 10;
}
#endif
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while (static_cast<uint64_t>(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while (static_cast<uint64_t>(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL));
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
do { } while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = 4608 * 1024 * 1024;
(uint64_t)(4608 * 1024 * 1024);
i += (uint64_t)(4608 * 1024 * 1024 * i));
-// expected-warning at +3 {{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
-// expected-warning at +3 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +3 {{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
+// expected-warning at +3 2{{overflow in expression; result is 536'870'912 with type 'int'}}
for (uint64_t i = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL);
((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
i = ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024))));
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
_Complex long long x = 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__real__ x) = 4608 * 1024 * 1024;
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(__imag__ x) = 4608 * 1024 * 1024;
-// expected-warning at +2 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t a[10];
a[4608 * 1024 * 1024] = 1;
#if __cplusplus < 201103L
@@ -171,22 +171,22 @@ uint64_t check_integer_overflows(int i) { //expected-note 0+{{declared here}}
// expected-note at -4 {{array 'a' declared here}}
#endif
-// expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 2{{overflow in expression; result is 536'870'912 with type 'int'}}
return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
}
void check_integer_overflows_in_function_calls() {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f0(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t x = f0(4608 * 1024 * 1024);
-// expected-warning at +2 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +2 {{overflow in expression; result is 536'870'912 with type 'int'}}
uint64_t (*f0_ptr)(uint64_t) = &f0;
(void)(*f0_ptr)(4608 * 1024 * 1024);
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)f2(0, f0(4608 * 1024 * 1024));
}
@@ -211,7 +211,7 @@ namespace EvaluationCrashes {
namespace GH31643 {
void f() {
- int a = -(1<<31); // expected-warning {{overflow in expression; result is -2147483648 with type 'int'}}
+ int a = -(1<<31); // expected-warning {{overflow in expression; result is -2'147'483'648 with type 'int'}}
}
}
@@ -237,8 +237,8 @@ u_ptr<bool> Wrap(int64_t x) {
int64_t Pass(int64_t x) { return x; }
int m() {
- int64_t x = Pass(30 * 24 * 60 * 59 * 1000); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}}
- auto r = Wrap(Pass(30 * 24 * 60 * 59 * 1000)); // expected-warning {{overflow in expression; result is -1746167296 with type 'int'}}
+ int64_t x = Pass(30 * 24 * 60 * 59 * 1000); // expected-warning {{overflow in expression; result is -1'746'167'296 with type 'int'}}
+ auto r = Wrap(Pass(30 * 24 * 60 * 59 * 1000)); // expected-warning {{overflow in expression; result is -1'746'167'296 with type 'int'}}
return 0;
}
}
diff --git a/clang/test/SemaObjC/integer-overflow.m b/clang/test/SemaObjC/integer-overflow.m
index 6d82e2951c1e65..255142729f8d56 100644
--- a/clang/test/SemaObjC/integer-overflow.m
+++ b/clang/test/SemaObjC/integer-overflow.m
@@ -9,10 +9,10 @@ - (int)add:(int)a with:(int)b {
}
- (void)testIntegerOverflows {
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)[self add:0 with:4608 * 1024 * 1024];
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
+// expected-warning at +1 {{overflow in expression; result is 536'870'912 with type 'int'}}
(void)[self add:0 with:[self add:4608 * 1024 * 1024 with:0]];
}
@end
diff --git a/clang/test/SemaObjC/objc-literal-nsnumber.m b/clang/test/SemaObjC/objc-literal-nsnumber.m
index aa7dc955fb5feb..a6c098947b0b2a 100644
--- a/clang/test/SemaObjC/objc-literal-nsnumber.m
+++ b/clang/test/SemaObjC/objc-literal-nsnumber.m
@@ -64,7 +64,7 @@ int main(void) {
@-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
@+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
NSNumber *av = @(1391126400000);
- NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443003904 with type 'int'}}
+ NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443'003'904 with type 'int'}}
NSNumber *cv = @(big * thousand);
}
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 6f2f25548cc84b..dd6d71b93334bb 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -1626,7 +1626,8 @@ class [[nodiscard]] APInt {
/// SmallString. If Radix > 10, UpperCase determine the case of letter
/// digits.
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
- bool formatAsCLiteral = false, bool UpperCase = true) const;
+ bool formatAsCLiteral = false, bool UpperCase = true,
+ bool insertSeparators = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 16, or 36.
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index a24368924bc90a..32f5828c92d05c 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -329,9 +329,10 @@ inline std::string itostr(int64_t X) {
}
inline std::string toString(const APInt &I, unsigned Radix, bool Signed,
- bool formatAsCLiteral = false) {
+ bool formatAsCLiteral = false,
+ bool upperCase = true, bool addSeparators = false) {
SmallString<40> S;
- I.toString(S, Radix, Signed, formatAsCLiteral);
+ I.toString(S, Radix, Signed, formatAsCLiteral, upperCase, addSeparators);
return std::string(S);
}
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 05b1526da95ff7..a186b81bc6797f 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2161,7 +2161,8 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
}
void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
- bool formatAsCLiteral, bool UpperCase) const {
+ bool formatAsCLiteral, bool UpperCase,
+ bool insertSeparators) const {
assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||
Radix == 36) &&
"Radix should be 2, 8, 10, 16, or 36!");
@@ -2187,6 +2188,12 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
}
}
+ // Number of digits in a group between separators
+ int Grouping = 4;
+ if (Radix == 8 || Radix == 10) {
+ Grouping = 3;
+ }
+
// First, check for a zero value and just short circuit the logic below.
if (isZero()) {
while (*Prefix) {
@@ -2223,9 +2230,14 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
++Prefix;
};
+ int Pos = 0;
while (N) {
+ if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ *--BufPtr = '\'';
+ }
*--BufPtr = Digits[N % Radix];
N /= Radix;
+ Pos++;
}
Str.append(BufPtr, std::end(Buffer));
return;
@@ -2257,17 +2269,27 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
unsigned MaskAmt = Radix - 1;
+ int Pos = 0;
while (Tmp.getBoolValue()) {
unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
+ if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ Str.push_back('\'');
+ }
Str.push_back(Digits[Digit]);
Tmp.lshrInPlace(ShiftAmt);
+ Pos++;
}
} else {
+ int Pos = 0;
while (Tmp.getBoolValue()) {
uint64_t Digit;
udivrem(Tmp, Radix, Tmp, Digit);
assert(Digit < Radix && "divide failed");
+ if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ Str.push_back('\'');
+ }
Str.push_back(Digits[Digit]);
+ Pos++;
}
}
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 3b909f8f7d14e2..e3e7e1e7bac65d 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -1379,6 +1379,23 @@ TEST(APIntTest, toString) {
EXPECT_EQ(std::string(S), "0");
S.clear();
+ // with separators
+ APInt(64, 140).toString(S, 2, false, true, false, true);
+ EXPECT_EQ(std::string(S), "0b1000'1100");
+ S.clear();
+ APInt(64, 1024).toString(S, 8, false, true, false, true);
+ EXPECT_EQ(std::string(S), "02'000");
+ S.clear();
+ APInt(64, 1000000).toString(S, 10, false, true, false, true);
+ EXPECT_EQ(std::string(S), "1'000'000");
+ S.clear();
+ APInt(64, 1000000).toString(S, 16, false, true, true, true);
+ EXPECT_EQ(std::string(S), "0xF'4240");
+ S.clear();
+ APInt(64, 1'000'000'000).toString(S, 36, false, false, false, true);
+ EXPECT_EQ(std::string(S), "gj'dgxs");
+ S.clear();
+
isSigned = false;
APInt(8, 255, isSigned).toString(S, 2, isSigned, true);
EXPECT_EQ(std::string(S), "0b11111111");
@@ -1415,6 +1432,24 @@ TEST(APIntTest, toString) {
APInt(8, 255, isSigned).toString(S, 36, isSigned, false);
EXPECT_EQ(std::string(S), "-1");
S.clear();
+
+ // negative with separators
+ APInt(64, -140, isSigned).toString(S, 2, isSigned, true, false, true);
+ EXPECT_EQ(std::string(S), "-0b1000'1100");
+ S.clear();
+ APInt(64, -1024, isSigned).toString(S, 8, isSigned, true, false, true);
+ EXPECT_EQ(std::string(S), "-02'000");
+ S.clear();
+ APInt(64, -1000000, isSigned).toString(S, 10, isSigned, true, false, true);
+ EXPECT_EQ(std::string(S), "-1'000'000");
+ S.clear();
+ APInt(64, -1000000, isSigned).toString(S, 16, isSigned, true, true, true);
+ EXPECT_EQ(std::string(S), "-0xF'4240");
+ S.clear();
+ APInt(64, -1'000'000'000, isSigned)
+ .toString(S, 36, isSigned, false, false, true);
+ EXPECT_EQ(std::string(S), "-gj'dgxs");
+ S.clear();
}
TEST(APIntTest, Log2) {
>From 4f2509a845f819899c8d9c6e2077c4c3e5db98aa Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Mon, 12 Feb 2024 12:50:13 -0800
Subject: [PATCH 2/8] Update clang/lib/AST/ExprConstant.cpp
Co-authored-by: Timm Baeder <tbaeder at redhat.com>
---
clang/lib/AST/ExprConstant.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index cb2f372311826a..1ae1c99b31d4b0 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2774,7 +2774,7 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
- << toString(Result, 10, Result.isSigned(), false, true, true)
+ << toString(Result, 10, Result.isSigned(), /*formatAsCLiteral=*/false, /*upperCase=*/true, /*insertSeparators=*/true)
<< E->getType() << E->getSourceRange();
return HandleOverflow(Info, E, Value, E->getType());
}
>From ba7bb34c90a8b28ac14779283793eea2c3792d6a Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Mon, 12 Feb 2024 12:50:23 -0800
Subject: [PATCH 3/8] Update llvm/lib/Support/APInt.cpp
Co-authored-by: Timm Baeder <tbaeder at redhat.com>
---
llvm/lib/Support/APInt.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index a186b81bc6797f..1087fa13a9a276 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2188,7 +2188,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
}
}
- // Number of digits in a group between separators
+ // Number of digits in a group between separators.
int Grouping = 4;
if (Radix == 8 || Radix == 10) {
Grouping = 3;
>From 9632dcb3737216f569374ec6cf1ca1bb7b237c2b Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Mon, 12 Feb 2024 12:51:29 -0800
Subject: [PATCH 4/8] Update llvm/lib/Support/APInt.cpp
Co-authored-by: Timm Baeder <tbaeder at redhat.com>
---
llvm/lib/Support/APInt.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 1087fa13a9a276..65f265a667f93b 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2189,7 +2189,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
}
// Number of digits in a group between separators.
- int Grouping = 4;
+ unsigned Grouping = (Radix == 8 || Radix == 10) ? 3 : 4;
if (Radix == 8 || Radix == 10) {
Grouping = 3;
}
>From 30ed47b6c5ff2d29e24d2d3b8054b75983040252 Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Tue, 13 Feb 2024 21:19:25 -0800
Subject: [PATCH 5/8] Update printing APInt numbers with separators
The new constant interpreter can also emit integer constant overflow
warnings. The code was updated to also print these with separators.
---
clang/lib/AST/ExprConstant.cpp | 6 ++++--
clang/lib/AST/Interp/Interp.h | 12 +++++++++---
clang/test/AST/Interp/c.c | 2 +-
llvm/lib/Support/APInt.cpp | 3 ---
4 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index ce44a8a968cf5a..9ef60f79ea9e6a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2778,7 +2778,8 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
- << toString(Result, 10, Result.isSigned(), /*formatAsCLiteral=*/false, /*upperCase=*/true, /*insertSeparators=*/true)
+ << toString(Result, 10, Result.isSigned(), /*formatAsCLiteral=*/false,
+ /*upperCase=*/true, /*insertSeparators=*/true)
<< E->getType() << E->getSourceRange();
return HandleOverflow(Info, E, Value, E->getType());
}
@@ -13858,7 +13859,8 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
- << toString(Value, 10, Value.isSigned(), false, true, true)
+ << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false,
+ /*upperCase=*/true, /*insertSeparators=*/true)
<< E->getType() << E->getSourceRange();
if (!HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index e2fda18e3f44d4..c265171d58215d 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -285,7 +285,9 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS,
QualType Type = E->getType();
if (S.checkingForUndefinedBehavior()) {
SmallString<32> Trunc;
- Value.trunc(Result.bitWidth()).toString(Trunc, 10);
+ Value.trunc(Result.bitWidth())
+ .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false,
+ /*upperCase=*/true, /*insertSeparators=*/true);
auto Loc = E->getExprLoc();
S.report(Loc, diag::warn_integer_constant_overflow)
<< Trunc << Type << E->getSourceRange();
@@ -497,7 +499,9 @@ bool Neg(InterpState &S, CodePtr OpPC) {
if (S.checkingForUndefinedBehavior()) {
SmallString<32> Trunc;
- NegatedValue.trunc(Result.bitWidth()).toString(Trunc, 10);
+ NegatedValue.trunc(Result.bitWidth())
+ .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false,
+ /*upperCase=*/true, /*insertSeparators=*/true);
auto Loc = E->getExprLoc();
S.report(Loc, diag::warn_integer_constant_overflow)
<< Trunc << Type << E->getSourceRange();
@@ -554,7 +558,9 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
QualType Type = E->getType();
if (S.checkingForUndefinedBehavior()) {
SmallString<32> Trunc;
- APResult.trunc(Result.bitWidth()).toString(Trunc, 10);
+ APResult.trunc(Result.bitWidth())
+ .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false,
+ /*upperCase=*/true, /*insertSeparators=*/true);
auto Loc = E->getExprLoc();
S.report(Loc, diag::warn_integer_constant_overflow)
<< Trunc << Type << E->getSourceRange();
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index 532e1c7369e58e..02a031da7e105c 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -91,7 +91,7 @@ int chooseexpr[__builtin_choose_expr(1, 1, expr)];
int somefunc(int i) {
return (i, 65537) * 65537; // all-warning {{left operand of comma operator has no effect}} \
- // all-warning {{overflow in expression; result is 131'073}}
+ // all-warning {{overflow in expression; result is 131'073 with type 'int'}}
}
/// FIXME: The following test is incorrect in the new interpreter.
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 65f265a667f93b..9206997924ba3a 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2190,9 +2190,6 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
// Number of digits in a group between separators.
unsigned Grouping = (Radix == 8 || Radix == 10) ? 3 : 4;
- if (Radix == 8 || Radix == 10) {
- Grouping = 3;
- }
// First, check for a zero value and just short circuit the logic below.
if (isZero()) {
>From 5ff2197dee2fdc043697b5cecbeaebe011cf4147 Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Fri, 1 Mar 2024 13:01:40 -0800
Subject: [PATCH 6/8] [clang][NFC] Update code style conventions
---
clang/docs/ReleaseNotes.rst | 3 +++
llvm/include/llvm/ADT/APInt.h | 2 +-
llvm/include/llvm/ADT/StringExtras.h | 4 ++--
llvm/lib/Support/APInt.cpp | 13 ++++++-------
4 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 402a2f8687386c..579664238d5dce 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -156,6 +156,9 @@ Improvements to Clang's diagnostics
- The ``-Wshorten-64-to-32`` diagnostic is now grouped under ``-Wimplicit-int-conversion`` instead
of ``-Wconversion``. Fixes `#69444 <https://github.com/llvm/llvm-project/issues/69444>`_.
+- Clang now uses thousand separators when printing large numbers in integer overflow diagnostics.
+ Fixes `#80939 <https://github.com/llvm/llvm-project/issues/80939>`_.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index dd6d71b93334bb..7795e2625f9346 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -1627,7 +1627,7 @@ class [[nodiscard]] APInt {
/// digits.
void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
bool formatAsCLiteral = false, bool UpperCase = true,
- bool insertSeparators = false) const;
+ bool InsertSeparators = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 16, or 36.
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 32f5828c92d05c..9e44b155c09355 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -330,9 +330,9 @@ inline std::string itostr(int64_t X) {
inline std::string toString(const APInt &I, unsigned Radix, bool Signed,
bool formatAsCLiteral = false,
- bool upperCase = true, bool addSeparators = false) {
+ bool UpperCase = true, bool InsertSeparators = false) {
SmallString<40> S;
- I.toString(S, Radix, Signed, formatAsCLiteral, upperCase, addSeparators);
+ I.toString(S, Radix, Signed, formatAsCLiteral, UpperCase, InsertSeparators);
return std::string(S);
}
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 9206997924ba3a..2464db5a48215e 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2162,7 +2162,7 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
bool formatAsCLiteral, bool UpperCase,
- bool insertSeparators) const {
+ bool InsertSeparators) const {
assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||
Radix == 36) &&
"Radix should be 2, 8, 10, 16, or 36!");
@@ -2229,9 +2229,8 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
int Pos = 0;
while (N) {
- if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
*--BufPtr = '\'';
- }
*--BufPtr = Digits[N % Radix];
N /= Radix;
Pos++;
@@ -2269,9 +2268,9 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
int Pos = 0;
while (Tmp.getBoolValue()) {
unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
- if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
Str.push_back('\'');
- }
+
Str.push_back(Digits[Digit]);
Tmp.lshrInPlace(ShiftAmt);
Pos++;
@@ -2282,9 +2281,9 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
uint64_t Digit;
udivrem(Tmp, Radix, Tmp, Digit);
assert(Digit < Radix && "divide failed");
- if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+ if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
Str.push_back('\'');
- }
+
Str.push_back(Digits[Digit]);
Pos++;
}
>From ec25d26f9dd2da903b261f66031d20731314b12b Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Fri, 1 Mar 2024 13:01:40 -0800
Subject: [PATCH 7/8] [clang][NFC] Update code style conventions
---
llvm/include/llvm/ADT/StringExtras.h | 3 ++-
llvm/lib/Support/APInt.cpp | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 9e44b155c09355..20e6ad1f68f996 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -330,7 +330,8 @@ inline std::string itostr(int64_t X) {
inline std::string toString(const APInt &I, unsigned Radix, bool Signed,
bool formatAsCLiteral = false,
- bool UpperCase = true, bool InsertSeparators = false) {
+ bool UpperCase = true,
+ bool InsertSeparators = false) {
SmallString<40> S;
I.toString(S, Radix, Signed, formatAsCLiteral, UpperCase, InsertSeparators);
return std::string(S);
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 2464db5a48215e..e686b976523302 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2229,7 +2229,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
int Pos = 0;
while (N) {
- if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
+ if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
*--BufPtr = '\'';
*--BufPtr = Digits[N % Radix];
N /= Radix;
@@ -2268,7 +2268,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
int Pos = 0;
while (Tmp.getBoolValue()) {
unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
- if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
+ if (InsertSeparators && Pos % Grouping == 0 && Pos > 0)
Str.push_back('\'');
Str.push_back(Digits[Digit]);
>From 3a6522185722eec51742b976ffeae06d06422209 Mon Sep 17 00:00:00 2001
From: Atousa Duprat <atousa.p at gmail.com>
Date: Mon, 4 Mar 2024 09:41:17 -0800
Subject: [PATCH 8/8] [clang][NFC] Update code style conventions
---
clang/lib/AST/ExprConstant.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 312e097509fa7a..4b6ccafbb7f0ed 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2779,7 +2779,7 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
<< toString(Result, 10, Result.isSigned(), /*formatAsCLiteral=*/false,
- /*upperCase=*/true, /*insertSeparators=*/true)
+ /*UpperCase=*/true, /*InsertSeparators=*/true)
<< E->getType() << E->getSourceRange();
return HandleOverflow(Info, E, Value, E->getType());
}
@@ -13913,7 +13913,7 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
<< toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false,
- /*upperCase=*/true, /*insertSeparators=*/true)
+ /*UpperCase=*/true, /*InsertSeparators=*/true)
<< E->getType() << E->getSourceRange();
if (!HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
More information about the cfe-commits
mailing list