Skip to content

Commit cecae35

Browse files
committed
Cap IntRange::Width to the expression's type size
This commit addresses a fallout introduced by #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 the size of the expression's type. rdar://149444029
1 parent 3dc9f2d commit cecae35

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10808,7 +10808,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1080810808
// sign bit. If the range was not non-negative, we need an extra bit
1080910809
// because the negation of the most-negative value is one bit wider than
1081010810
// that value.
10811-
return IntRange(SubRange->Width + 1, false);
10811+
return IntRange(std::min(SubRange->Width + 1, MaxWidth), false);
1081210812
}
1081310813

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

1082610826
// The width increments by 1 if the sub-expression cannot be negative
1082710827
// since it now can be.
10828-
return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);
10828+
return IntRange(
10829+
std::min(SubRange->Width + (int)SubRange->NonNegative, MaxWidth),
10830+
false);
1082910831
}
1083010832

1083110833
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)