diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 69276ce418fa6..ea7872f309e2a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -10805,10 +10805,9 @@ static std::optional TryGetExprRange(ASTContext &C, const Expr *E, return std::nullopt; // If the range was previously non-negative, we need an extra bit for the - // sign bit. If the range was not non-negative, we need an extra bit - // because the negation of the most-negative value is one bit wider than - // that value. - return IntRange(SubRange->Width + 1, false); + // sign bit. Otherwise, we need an extra bit because the negation of the + // most-negative value is one bit wider than that value. + return IntRange(std::min(SubRange->Width + 1, MaxWidth), false); } case UO_Not: { @@ -10825,7 +10824,9 @@ static std::optional TryGetExprRange(ASTContext &C, const Expr *E, // The width increments by 1 if the sub-expression cannot be negative // since it now can be. - return IntRange(SubRange->Width + (int)SubRange->NonNegative, false); + return IntRange( + std::min(SubRange->Width + (int)SubRange->NonNegative, MaxWidth), + false); } default: diff --git a/clang/test/Sema/implicit-int-conversion-on-int.c b/clang/test/Sema/implicit-int-conversion-on-int.c index f555893d9e17a..3b1d81cd6a9ab 100644 --- a/clang/test/Sema/implicit-int-conversion-on-int.c +++ b/clang/test/Sema/implicit-int-conversion-on-int.c @@ -48,3 +48,11 @@ unsigned long long test_ull(unsigned long long x) { unsigned _BitInt(16) test_unsigned_bit_int(unsigned _BitInt(16) x) { return -x; } + +unsigned test_shift_minus(int i) { + return -(1 << i); +} + +unsigned test_shift_not(int i) { + return ~(1 << i); +}