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 <atous...@gmail.com> Date: Tue, 6 Feb 2024 21:02:05 -0800 Subject: [PATCH 1/5] [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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} uint64_t overflow = 4608 * 1024 * 1024, -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow2 = (uint64_t)(4608 * 1024 * 1024), -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow3 = (uint64_t)(4608 * 1024 * 1024 * i), -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL), -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}} overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow = 0 ? 0 : 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if (4608 * 1024 * 1024) return 0; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024)) return 1; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024)) return 2; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024 * i)) return 3; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)) return 4; -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} case 4608 * 1024 * 1024: return 6; -// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 537'919'488 with type 'int'}} case (uint64_t)(4609 * 1024 * 1024): return 7; // expected-error@+1 {{expression is not an integer constant expression}} case ((uint64_t)(4608 * 1024 * 1024 * i)): return 8; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)): return 9; -// expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+2 2{{overflow in expression; result is 536'870'912 with type 'int'}} // expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while (4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024 * i)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while (4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024 * i)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+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@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} _Complex long long x = 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (__real__ x) = 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (__imag__ x) = 4608 * 1024 * 1024; -// expected-warning@+4 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+4 {{overflow in expression; result is 536'870'912 with type 'int'}} // expected-warning@+3 {{array index 536870912 is past the end of the array (that has type 'uint64_t[10]' (aka 'unsigned long long[10]'))}} // expected-note@+1 {{array 'a' declared here}} uint64_t a[10]; a[4608 * 1024 * 1024] = 1i; -// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}} (void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (void)f0(4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} uint64_t x = f0(4608 * 1024 * 1024); -// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@-2 {{overflow in expression; result is -2147483647 with type 'int'}} + // expected-warning@-2 {{overflow in expression; result is -2'147'483'647 with type 'int'}} #else // expected-error@-4 {{case value is not a constant expression}} \ // expected-note@-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@-2 {{overflow in expression; result is -1375982336 with type 'int'}} + // expected-warning@-2 {{overflow in expression; result is -1'375'982'336 with type 'int'}} #else // expected-error@-4 {{case value is not a constant expression}} \ // expected-note@-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@-2 {{not an integral constant expression}} // expected-note@-3 {{value 28958703552 is outside the range of representable values}} #else -// expected-warning@-5 {{overflow in expression; result is -1106067520 with type 'int'}} +// expected-warning@-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@-2 {{enumerator value is not a constant expression}} // expected-note@-3 {{value 28958703552 is outside the range of representable values}} #else -// expected-warning@-5 {{overflow in expression; result is -1106067520 with type 'int'}} +// expected-warning@-5 {{overflow in expression; result is -1'106'067'520 with type 'int'}} // expected-warning@-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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} uint64_t overflow = 4608 * 1024 * 1024, -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow2 = (uint64_t)(4608 * 1024 * 1024), -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow3 = (uint64_t)(4608 * 1024 * 1024 * i), -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow4 = (1ULL * ((4608) * ((1024) * (1024))) + 2ULL), -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow5 = static_cast<uint64_t>(4608 * 1024 * 1024), -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow += overflow2 = overflow3 = (uint64_t)(4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow += overflow2 = overflow3 = 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 2{{overflow in expression; result is 536'870'912 with type 'int'}} overflow = 4608 * 1024 * 1024 ? 4608 * 1024 * 1024 : 0; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} overflow = 0 ? 0 : 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if (4608 * 1024 * 1024) return 0; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024)) return 1; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if (static_cast<uint64_t>(4608 * 1024 * 1024)) return 1; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024)) return 2; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((uint64_t)(4608 * 1024 * 1024 * i)) return 3; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} if ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)) return 4; -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} case 4608 * 1024 * 1024: return 6; -// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 537'919'488 with type 'int'}} case (uint64_t)(4609 * 1024 * 1024): return 7; -// expected-warning@+1 {{overflow in expression; result is 537919488 with type 'int'}} +// expected-warning@+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@+1 {{expression is not an integral constant expression}} case ((uint64_t)(4608 * 1024 * 1024 * i)): return 8; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)): return 9; -// expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+2 2{{overflow in expression; result is 536'870'912 with type 'int'}} // expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while (4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while (static_cast<uint64_t>(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((uint64_t)(4608 * 1024 * 1024 * i)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while (4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while (static_cast<uint64_t>(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((uint64_t)(4608 * 1024 * 1024 * i)); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} do { } while ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+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@+3 {{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} -// expected-warning@+3 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+3 {{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+3 2{{overflow in expression; result is 536'870'912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} _Complex long long x = 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (__real__ x) = 4608 * 1024 * 1024; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (__imag__ x) = 4608 * 1024 * 1024; -// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@-4 {{array 'a' declared here}} #endif -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (void)f0(4608 * 1024 * 1024); -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} uint64_t x = f0(4608 * 1024 * 1024); -// expected-warning@+2 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+1 {{overflow in expression; result is 536'870'912 with type 'int'}} (void)[self add:0 with:4608 * 1024 * 1024]; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} +// expected-warning@+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 <atous...@gmail.com> Date: Mon, 12 Feb 2024 12:50:13 -0800 Subject: [PATCH 2/5] Update clang/lib/AST/ExprConstant.cpp Co-authored-by: Timm Baeder <tbae...@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 <atous...@gmail.com> Date: Mon, 12 Feb 2024 12:50:23 -0800 Subject: [PATCH 3/5] Update llvm/lib/Support/APInt.cpp Co-authored-by: Timm Baeder <tbae...@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 <atous...@gmail.com> Date: Mon, 12 Feb 2024 12:51:29 -0800 Subject: [PATCH 4/5] Update llvm/lib/Support/APInt.cpp Co-authored-by: Timm Baeder <tbae...@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 <atous...@gmail.com> Date: Tue, 13 Feb 2024 21:19:25 -0800 Subject: [PATCH 5/5] 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()) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits