Skip to content

Commit d25e0aa

Browse files
authored
[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.
1 parent 8a1ce2d commit d25e0aa

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,9 @@ Bug Fixes in This Version
488488
- Clang no longer permits using the `_BitInt` types as an underlying type for an
489489
enumeration as specified in the C23 Standard.
490490
Fixes (`#69619 <https://github.com/llvm/llvm-project/issues/69619>`_)
491+
- Fixed an issue when a shift count specified by a small constant ``_BitInt()``,
492+
in a left shift operation, could result in a faulty warnings about
493+
``shift count >= width of type``.
491494
- Clang now accepts anonymous members initialized with designated initializers
492495
inside templates.
493496
Fixes (`#65143 <https://github.com/llvm/llvm-project/issues/65143>`_)

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12143,8 +12143,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1214312143
auto FXSema = S.Context.getFixedPointSemantics(LHSExprType);
1214412144
LeftSize = FXSema.getWidth() - (unsigned)FXSema.hasUnsignedPadding();
1214512145
}
12146-
llvm::APInt LeftBits(Right.getBitWidth(), LeftSize);
12147-
if (Right.uge(LeftBits)) {
12146+
if (Right.uge(LeftSize)) {
1214812147
S.DiagRuntimeBehavior(Loc, RHS.get(),
1214912148
S.PDiag(diag::warn_shift_gt_typewidth)
1215012149
<< RHS.get()->getSourceRange());
@@ -12186,7 +12185,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1218612185

1218712186
llvm::APInt ResultBits =
1218812187
static_cast<llvm::APInt &>(Right) + Left.getSignificantBits();
12189-
if (LeftBits.uge(ResultBits))
12188+
if (ResultBits.ule(LeftSize))
1219012189
return;
1219112190
llvm::APSInt Result = Left.extend(ResultBits.getLimitedValue());
1219212191
Result = Result.shl(Right);
@@ -12200,7 +12199,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
1220012199
// bugs -- if the result is cast back to an unsigned type, it will have the
1220112200
// expected value. Thus we place this behind a different warning that can be
1220212201
// turned off separately if needed.
12203-
if (LeftBits == ResultBits - 1) {
12202+
if (ResultBits - 1 == LeftSize) {
1220412203
S.Diag(Loc, diag::warn_shift_result_sets_sign_bit)
1220512204
<< HexResult << LHSType
1220612205
<< LHS.get()->getSourceRange() << RHS.get()->getSourceRange();

clang/test/Sema/c2x-expr-range.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ void test1(int *a) {
1212
void test2(__uint128_t *a) {
1313
(void)(*a >> ((__uint128_t)__UINT64_MAX__ + 1) <= 0); // expected-warning {{shift count >= width of type}}
1414
}
15+
16+
// Regression test for bug where a faulty warning was given. We don't expect to
17+
// see any warning in this case.
18+
_BitInt(128) test3(_BitInt(128) a) {
19+
return a << 12wb;
20+
}
21+
22+
// Similar to test3 above, but with a too large shift count. We expect to see a
23+
// warning in this case.
24+
_BitInt(128) test4(_BitInt(128) a) {
25+
return a << 129wb; // expected-warning {{shift count >= width of type}}
26+
}

0 commit comments

Comments
 (0)