Skip to content

Commit 5bbe153

Browse files
authored
Cap IntRange::Width to MaxWidth (llvm#145356)
This commit addresses a fallout introduced by llvm#126846. Previously, TryGetExprRange would return an IntRange that has an active range exceeding the maximum representable range for the expression's underlying type. This led to clang erroneously issuing warnings about implicit conversions losing integer precision. This commit fixes the bug by capping IntRange::Width to MaxWidth. rdar://149444029
1 parent 0f87c78 commit 5bbe153

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10805,10 +10805,9 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1080510805
return std::nullopt;
1080610806

1080710807
// If the range was previously non-negative, we need an extra bit for the
10808-
// sign bit. If the range was not non-negative, we need an extra bit
10809-
// because the negation of the most-negative value is one bit wider than
10810-
// that value.
10811-
return IntRange(SubRange->Width + 1, false);
10808+
// sign bit. Otherwise, we need an extra bit because the negation of the
10809+
// most-negative value is one bit wider than that value.
10810+
return IntRange(std::min(SubRange->Width + 1, MaxWidth), false);
1081210811
}
1081310812

1081410813
case UO_Not: {
@@ -10825,7 +10824,9 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1082510824

1082610825
// The width increments by 1 if the sub-expression cannot be negative
1082710826
// since it now can be.
10828-
return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);
10827+
return IntRange(
10828+
std::min(SubRange->Width + (int)SubRange->NonNegative, MaxWidth),
10829+
false);
1082910830
}
1083010831

1083110832
default:

clang/test/Sema/implicit-int-conversion-on-int.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ unsigned long long test_ull(unsigned long long x) {
4848
unsigned _BitInt(16) test_unsigned_bit_int(unsigned _BitInt(16) x) {
4949
return -x;
5050
}
51+
52+
unsigned test_shift_minus(int i) {
53+
return -(1 << i);
54+
}
55+
56+
unsigned test_shift_not(int i) {
57+
return ~(1 << i);
58+
}

0 commit comments

Comments
 (0)