[clang] 7d2b569 - [Sema] Handle large shift counts in GetExprRange (#68590)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 10 01:25:07 PDT 2023


Author: Björn Pettersson
Date: 2023-10-10T10:25:01+02:00
New Revision: 7d2b569cc42487c85982aa3ebc8243204042d2ce

URL: https://github.com/llvm/llvm-project/commit/7d2b569cc42487c85982aa3ebc8243204042d2ce
DIFF: https://github.com/llvm/llvm-project/commit/7d2b569cc42487c85982aa3ebc8243204042d2ce.diff

LOG: [Sema] Handle large shift counts in GetExprRange (#68590)

GetExprRange did not expect that very large shift counts when
narrowing the range based on logical right shifts. So with inputs
such as
    *a >> 123456789012345678901uwb
it would hit assertions about trying to convert a too large APInt
into uint64_t.
This patch fixes that by using the APInt value when determining if
we should reduce the range by the shift count or not.

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

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaChecking.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9c320bc8b35d23d..2d918967e7f0b02 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 <https://github.com/llvm/llvm-project/issues/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 446e35218bff0ad..2594a8f97f7d94e 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<llvm::APSInt> 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 000000000000000..73683e6bfe684aa
--- /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}}
+}


        


More information about the cfe-commits mailing list