[clang] [Sema] Fixed faulty shift count warning (PR #69521)
Karl-Johan Karlsson via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 24 23:26:48 PDT 2023
https://github.com/karka228 updated https://github.com/llvm/llvm-project/pull/69521
>From a4a9fb73de9319acd26290ef31d1e17b127c0c3b Mon Sep 17 00:00:00 2001
From: Karl-Johan Karlsson <karl-johan.karlsson at ericsson.com>
Date: Wed, 18 Oct 2023 16:40:53 +0200
Subject: [PATCH] [Sema] Fixed faulty shift count warning
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.
---
clang/docs/ReleaseNotes.rst | 3 +++
clang/lib/Sema/SemaExpr.cpp | 7 +++----
clang/test/Sema/c2x-expr-range.c | 12 ++++++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cdef43f2011bc98..05bb069fe709700 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -403,6 +403,9 @@ Bug Fixes in This Version
operator in C. No longer issuing a confusing diagnostic along the lines of
"incompatible operand types ('foo' and 'foo')" with extensions such as matrix
types. Fixes (`#69008 <https://github.com/llvm/llvm-project/issues/69008>`_)
+- 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``.
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index aa30a3a03887558..c00178ee1835e00 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12120,8 +12120,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());
@@ -12163,7 +12162,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);
@@ -12177,7 +12176,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 different 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