Author: Shafik Yaghmour Date: 2023-01-31T09:35:12-08:00 New Revision: 67ee18cc7a308ae8418689c4f03a1be73b8b874a
URL: https://github.com/llvm/llvm-project/commit/67ee18cc7a308ae8418689c4f03a1be73b8b874a DIFF: https://github.com/llvm/llvm-project/commit/67ee18cc7a308ae8418689c4f03a1be73b8b874a.diff LOG: [Clang] Add machinery to catch overflow in unary minus outside of a constant expression context We provide several diagnostics for various undefined behaviors due to signed integer overflow outside of a constant expression context. We were missing the machinery to catch overflows due to unary minus. Fixes: https://github.com/llvm/llvm-project/issues/31643 Differential Revision: https://reviews.llvm.org/D142867 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/lib/Sema/SemaChecking.cpp clang/test/CXX/expr/expr.const/p2-0x.cpp clang/test/SemaCXX/integer-overflow.cpp clang/unittests/Support/TimeProfilerTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index efa9fe076b41f..0a1197044a71a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -63,6 +63,9 @@ Bug Fixes Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- We now generate a diagnostic for signed integer overflow due to unary minus + in a non-constant expression context. This fixes + `Issue 31643 <https://github.com/llvm/llvm-project/issues/31643>`_ Non-comprehensive list of changes in this release ------------------------------------------------- diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e4c47b8b8b02f..3e2164c4eebc8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13502,10 +13502,16 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { return false; if (!Result.isInt()) return Error(E); const APSInt &Value = Result.getInt(); - if (Value.isSigned() && Value.isMinSignedValue() && E->canOverflow() && - !HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1), - E->getType())) - return false; + if (Value.isSigned() && Value.isMinSignedValue() && E->canOverflow()) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_integer_constant_overflow) + << toString(Value, 10) << E->getType(); + + if (!HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1), + E->getType())) + return false; + } return Success(-Value, E); } case UO_Not: { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index da4ec30b65302..4602284309491 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14876,7 +14876,7 @@ void Sema::CheckForIntOverflow (Expr *E) { Expr *OriginalE = Exprs.pop_back_val(); Expr *E = OriginalE->IgnoreParenCasts(); - if (isa<BinaryOperator>(E)) { + if (isa<BinaryOperator, UnaryOperator>(E)) { E->EvaluateForOverflow(Context); continue; } diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index a8dece1b90d5a..9044844607e05 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -146,6 +146,7 @@ namespace UndefinedBehavior { constexpr int int_min = ~0x7fffffff; constexpr int minus_int_min = -int_min; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} + constexpr int minus_int_min_from_shift = -(1<<31); // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}} constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}} constexpr int int_min_div_minus_1 = int_min / -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} diff --git a/clang/test/SemaCXX/integer-overflow.cpp b/clang/test/SemaCXX/integer-overflow.cpp index 2d8b7455f95f5..870fbeb73cc1f 100644 --- a/clang/test/SemaCXX/integer-overflow.cpp +++ b/clang/test/SemaCXX/integer-overflow.cpp @@ -208,3 +208,9 @@ namespace EvaluationCrashes { } } } + +namespace GH31643 { +void f() { + int a = -(1<<31); // expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} +} +} diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index 566cc6786461f..fdfbbfe4e3a9d 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -179,6 +179,7 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line Frontend | EvaluateAsRValue (<test.cc:8:21>) | EvaluateForOverflow (<test.cc:8:21, col:25>) +| EvaluateForOverflow (<test.cc:8:30, col:32>) | EvaluateAsRValue (<test.cc:9:14>) | EvaluateForOverflow (<test.cc:9:9, col:14>) | isPotentialConstantExpr (slow_namespace::slow_func) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits