[clang] [clang] Emit bad shift warnings (PR #70307)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 8 23:41:26 PDT 2024


================
@@ -11444,9 +11444,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
   llvm::APSInt Right = RHSResult.Val.getInt();
 
   if (Right.isNegative()) {
-    S.DiagRuntimeBehavior(Loc, RHS.get(),
-                          S.PDiag(diag::warn_shift_negative)
-                            << RHS.get()->getSourceRange());
+    if (S.ExprEvalContexts.back().isConstantEvaluated())
+      S.Diag(Loc, diag::warn_shift_negative) << RHS.get()->getSourceRange();
+    else
+      S.DiagRuntimeBehavior(Loc, RHS.get(),
+                            S.PDiag(diag::warn_shift_negative)
+                              << RHS.get()->getSourceRange());
----------------
tbaederr wrote:

The constant interpreter already diagnoses this:
https://github.com/llvm/llvm-project/blob/51089e360e37962c7841fe0a494ba9fb5368bab2/clang/lib/AST/ExprConstant.cpp#L2850-L2851

and for the test case with the `(-1 << 29)` enum value, this is evaluated in `Sema::VerifyIntegerConstantExpresssion()` and it's also diagnosed here:
https://github.com/llvm/llvm-project/blob/51089e360e37962c7841fe0a494ba9fb5368bab2/clang/lib/Sema/SemaExpr.cpp#L18158-L18159

But the diagnostic doesn't show up. Not sure why. If I modify the constant interpreter to `return false` in the negative LHS case, I get the expected diagnostic:
```console
/home/tbaeder/test.cpp:2:9: error: expression is not an integral constant expression
    2 |     X = (-1<<29) // expected-warning {{shifting a negative signed value is undefined}}
      |         ^~~~~~~~
/home/tbaeder/test.cpp:2:12: note: left shift of negative value -1
    2 |     X = (-1<<29) // expected-warning {{shifting a negative signed value is undefined}}
      |            ^
```


https://github.com/llvm/llvm-project/pull/70307


More information about the cfe-commits mailing list