diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9c320bc8b35d23..2d918967e7f0b0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -378,6 +378,10 @@ Bug Fixes in This Version - Fix crash in evaluating ``constexpr`` value for invalid template function. Fixes (`#68542 `_) +- Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right + shift operation, could result in missing warnings about + ``shift count >= width of type`` or internal compiler error. + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 446e35218bff0a..2594a8f97f7d94 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -13596,11 +13596,10 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, if (std::optional shift = BO->getRHS()->getIntegerConstantExpr(C)) { if (shift->isNonNegative()) { - unsigned zext = shift->getZExtValue(); - if (zext >= L.Width) + if (shift->uge(L.Width)) L.Width = (L.NonNegative ? 0 : 1); else - L.Width -= zext; + L.Width -= shift->getZExtValue(); } } diff --git a/clang/test/Sema/c2x-expr-range.c b/clang/test/Sema/c2x-expr-range.c new file mode 100644 index 00000000000000..73683e6bfe684a --- /dev/null +++ b/clang/test/Sema/c2x-expr-range.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -std=c2x -triple=x86_64-unknown-linux %s + +// Regression test for bug where we used to hit an assertion due to shift amount +// being larger than 64 bits. We want to see a warning about too large shift +// amount. +void test1(int *a) { + (void)(*a >> 123456789012345678901uwb <= 0); // expected-warning {{shift count >= width of type}} +} + +// Similar to test1 above, but using __uint128_t instead of __BitInt. +// We want to see a warning about too large shift amount. +void test2(__uint128_t *a) { + (void)(*a >> ((__uint128_t)__UINT64_MAX__ + 1) <= 0); // expected-warning {{shift count >= width of type}} +}