[clang] d25e0aa - [Sema] Fixed faulty shift count warning (#69521)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 00:48:05 PDT 2023


Author: Karl-Johan Karlsson
Date: 2023-10-25T09:48:01+02:00
New Revision: d25e0aac415f45ce98c3700010acb5a98f016cef

URL: https://github.com/llvm/llvm-project/commit/d25e0aac415f45ce98c3700010acb5a98f016cef
DIFF: https://github.com/llvm/llvm-project/commit/d25e0aac415f45ce98c3700010acb5a98f016cef.diff

LOG: [Sema] Fixed faulty shift count warning (#69521)

Constant values of _BitInt have the bitwith to exactly fit the constant
number. This patch fix a problem in Sema when building an APInt where
the supplied bitwidth can become too small and simply truncate the value
leading to a faulty warning.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaExpr.cpp
    clang/test/Sema/c2x-expr-range.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a063733e96cb74c..4cc148905d4e130 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -488,6 +488,9 @@ Bug Fixes in This Version
 - Clang no longer permits using the `_BitInt` types as an underlying type for an
   enumeration as specified in the C23 Standard.
   Fixes (`#69619 <https://github.com/llvm/llvm-project/issues/69619>`_)
+- Fixed an issue when a shift count specified by a small constant ``_BitInt()``,
+  in a left shift operation, could result in a faulty warnings about
+  ``shift count >= width of type``.
 - Clang now accepts anonymous members initialized with designated initializers
   inside templates.
   Fixes (`#65143 <https://github.com/llvm/llvm-project/issues/65143>`_)

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 895b22805860d98..c2772bfb71c77e9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12143,8 +12143,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
     auto FXSema = S.Context.getFixedPointSemantics(LHSExprType);
     LeftSize = FXSema.getWidth() - (unsigned)FXSema.hasUnsignedPadding();
   }
-  llvm::APInt LeftBits(Right.getBitWidth(), LeftSize);
-  if (Right.uge(LeftBits)) {
+  if (Right.uge(LeftSize)) {
     S.DiagRuntimeBehavior(Loc, RHS.get(),
                           S.PDiag(diag::warn_shift_gt_typewidth)
                             << RHS.get()->getSourceRange());
@@ -12186,7 +12185,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
 
   llvm::APInt ResultBits =
       static_cast<llvm::APInt &>(Right) + Left.getSignificantBits();
-  if (LeftBits.uge(ResultBits))
+  if (ResultBits.ule(LeftSize))
     return;
   llvm::APSInt Result = Left.extend(ResultBits.getLimitedValue());
   Result = Result.shl(Right);
@@ -12200,7 +12199,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
   // bugs -- if the result is cast back to an unsigned type, it will have the
   // expected value. Thus we place this behind a 
diff erent warning that can be
   // turned off separately if needed.
-  if (LeftBits == ResultBits - 1) {
+  if (ResultBits - 1 == LeftSize) {
     S.Diag(Loc, diag::warn_shift_result_sets_sign_bit)
         << HexResult << LHSType
         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();

diff  --git a/clang/test/Sema/c2x-expr-range.c b/clang/test/Sema/c2x-expr-range.c
index 73683e6bfe684aa..eff0b7cd4d9f546 100644
--- a/clang/test/Sema/c2x-expr-range.c
+++ b/clang/test/Sema/c2x-expr-range.c
@@ -12,3 +12,15 @@ void test1(int *a) {
 void test2(__uint128_t *a) {
   (void)(*a >> ((__uint128_t)__UINT64_MAX__ + 1) <= 0); // expected-warning {{shift count >= width of type}}
 }
+
+// Regression test for bug where a faulty warning was given. We don't expect to
+// see any warning in this case.
+_BitInt(128) test3(_BitInt(128) a) {
+  return a << 12wb;
+}
+
+// Similar to test3 above, but with a too large shift count. We expect to see a
+// warning in this case.
+_BitInt(128) test4(_BitInt(128) a) {
+  return a << 129wb; // expected-warning {{shift count >= width of type}}
+}


        


More information about the cfe-commits mailing list