https://github.com/budimirarandjelovicsyrmia updated https://github.com/llvm/llvm-project/pull/70307
From 0ed347381cdd9e639ab5026dcf244ca4d7fcb6e3 Mon Sep 17 00:00:00 2001 From: budimirarandjelovicsyrmia <budimir.arandjelo...@syrmia.com> Date: Thu, 26 Oct 2023 10:39:52 +0200 Subject: [PATCH] [clang] Emit bad shift warnings --- clang/lib/AST/ExprConstant.cpp | 7 +++++++ clang/lib/Sema/SemaExpr.cpp | 17 +++++++++++++---- clang/test/C/drs/dr0xx.c | 2 +- clang/test/Sema/shift-count-negative.c | 10 ++++++++++ clang/test/Sema/shift-count-overflow.c | 7 +++++++ clang/test/Sema/shift-negative-value.c | 10 ++++++++++ clang/test/Sema/vla-2.c | 6 ++++-- clang/test/SemaCXX/shift.cpp | 1 - 8 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 clang/test/Sema/shift-count-negative.c create mode 100644 clang/test/Sema/shift-count-overflow.c create mode 100644 clang/test/Sema/shift-negative-value.c diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index af1f18aa8ef24..0926bcf258f58 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2856,6 +2856,9 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, else if (LHS.countl_zero() < SA) Info.CCEDiag(E, diag::note_constexpr_lshift_discards); } + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + Info.getLangOpts().CPlusPlus) + return false; Result = LHS << SA; return true; } @@ -2879,6 +2882,10 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, if (SA != RHS) Info.CCEDiag(E, diag::note_constexpr_large_shift) << RHS << E->getType() << LHS.getBitWidth(); + + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + Info.getLangOpts().CPlusPlus) + return false; Result = LHS >> SA; return true; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 44f886bf54e3a..c77a0e511a3a8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11246,7 +11246,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (Right.isNegative()) { S.DiagRuntimeBehavior(Loc, RHS.get(), S.PDiag(diag::warn_shift_negative) - << RHS.get()->getSourceRange()); + << RHS.get()->getSourceRange()); return; } @@ -11261,7 +11261,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (Right.uge(LeftSize)) { S.DiagRuntimeBehavior(Loc, RHS.get(), S.PDiag(diag::warn_shift_gt_typewidth) - << RHS.get()->getSourceRange()); + << RHS.get()->getSourceRange()); return; } @@ -11294,7 +11294,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (Left.isNegative()) { S.DiagRuntimeBehavior(Loc, LHS.get(), S.PDiag(diag::warn_shift_lhs_negative) - << LHS.get()->getSourceRange()); + << LHS.get()->getSourceRange()); return; } @@ -17130,11 +17130,20 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { + SmallVector<PartialDiagnosticAt, 8> Notes; if (Result) - *Result = E->EvaluateKnownConstIntCheckOverflow(Context); + *Result = E->EvaluateKnownConstIntCheckOverflow(Context, &Notes); if (!isa<ConstantExpr>(E)) E = Result ? ConstantExpr::Create(Context, E, APValue(*Result)) : ConstantExpr::Create(Context, E); + + if (Notes.size() && !Diagnoser.Suppress) { + Diagnoser.diagnoseNotICE(*this, DiagLoc) << E->getSourceRange(); + for (const PartialDiagnosticAt &Note : Notes) + Diag(Note.first, Note.second); + return ExprError(); + } + return E; } diff --git a/clang/test/C/drs/dr0xx.c b/clang/test/C/drs/dr0xx.c index 36de32a93da95..05045344efd91 100644 --- a/clang/test/C/drs/dr0xx.c +++ b/clang/test/C/drs/dr0xx.c @@ -430,7 +430,7 @@ void dr081(void) { /* Demonstrate that we don't crash when left shifting a signed value; that's * implementation defined behavior. */ - _Static_assert(-1 << 1 == -2, "fail"); /* Didn't shift a zero into the "sign bit". */ + _Static_assert(-1 << 1 == -2, "fail"); /* Undefined behavior since C99 */ _Static_assert(1 << 3 == 1u << 3u, "fail"); /* Shift of a positive signed value does sensible things. */ } diff --git a/clang/test/Sema/shift-count-negative.c b/clang/test/Sema/shift-count-negative.c new file mode 100644 index 0000000000000..34d51294b43d4 --- /dev/null +++ b/clang/test/Sema/shift-count-negative.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wshift-count-negative %s +// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wall %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wshift-count-negative %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wall %s + +enum shiftof { + X = (1<<-29) // c-error {{expression is not an integer constant expression}} + // cpp-error@-1 {{expression is not an integral constant expression}} + // expected-note@-2 {{negative shift count -29}} +}; diff --git a/clang/test/Sema/shift-count-overflow.c b/clang/test/Sema/shift-count-overflow.c new file mode 100644 index 0000000000000..77dd4b3c6a401 --- /dev/null +++ b/clang/test/Sema/shift-count-overflow.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wshift-count-overflow %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s + +enum shiftof { + X = (1<<32) // expected-error {{expression is not an integer constant expression}} + // expected-note@-1 {{shift count 32 >= width of type 'int'}} +}; diff --git a/clang/test/Sema/shift-negative-value.c b/clang/test/Sema/shift-negative-value.c new file mode 100644 index 0000000000000..0394c00e00d0f --- /dev/null +++ b/clang/test/Sema/shift-negative-value.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wshift-negative-value %s +// RUN: %clang_cc1 -x c -fsyntax-only -verify=expected,c -Wall %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wshift-negative-value %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cpp -Wall %s + +enum shiftof { + X = (-1<<29) // c-error {{expression is not an integer constant expression}} + // cpp-error@-1 {{expression is not an integral constant expression}} + // expected-note@-2 {{left shift of negative value -1}} +}; diff --git a/clang/test/Sema/vla-2.c b/clang/test/Sema/vla-2.c index 316931f270607..577407e15b479 100644 --- a/clang/test/Sema/vla-2.c +++ b/clang/test/Sema/vla-2.c @@ -4,11 +4,13 @@ // a different codepath when we have already emitted an error.) int PotentiallyEvaluatedSizeofWarn(int n) { - return (int)sizeof *(0 << 32,(int(*)[n])0); // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}} + return (int)sizeof *(0 << 32,(int(*)[n])0); /* expected-warning {{shift count >= width of type}} + expected-warning {{left operand of comma operator has no effect}} */ } void PotentiallyEvaluatedTypeofWarn(int n) { - __typeof(*(0 << 32,(int(*)[n])0)) x; // expected-warning {{left operand of comma operator has no effect}} expected-warning {{shift count >= width of type}} + __typeof(*(0 << 32,(int(*)[n])0)) x; /* expected-warning {{shift count >= width of type}} + expected-warning {{left operand of comma operator has no effect}} */ (void)x; } diff --git a/clang/test/SemaCXX/shift.cpp b/clang/test/SemaCXX/shift.cpp index 89a98791d3eba..c3249b124e926 100644 --- a/clang/test/SemaCXX/shift.cpp +++ b/clang/test/SemaCXX/shift.cpp @@ -22,7 +22,6 @@ void test() { c = 1 << -1; // expected-warning {{shift count is negative}} c = 1 >> -1; // expected-warning {{shift count is negative}} c = 1 << (unsigned)-1; // expected-warning {{shift count >= width of type}} - // expected-warning@-1 {{implicit conversion}} c = 1 >> (unsigned)-1; // expected-warning {{shift count >= width of type}} c = 1 << c; c <<= 0; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits