[clang] 3efa479 - [clang][Interp] Support AddOffset with 128bit offsets (#68679)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 13 05:47:52 PDT 2023


Author: Timm Baeder
Date: 2023-10-13T14:47:46+02:00
New Revision: 3efa4794ecd5ca6235f9f7e3fc83a8d9e59b66c9

URL: https://github.com/llvm/llvm-project/commit/3efa4794ecd5ca6235f9f7e3fc83a8d9e59b66c9
DIFF: https://github.com/llvm/llvm-project/commit/3efa4794ecd5ca6235f9f7e3fc83a8d9e59b66c9.diff

LOG: [clang][Interp] Support AddOffset with 128bit offsets (#68679)

We do a similar thing a few lines above for `Index`:

```c++
  // Get a version of the index comparable to the type.
  T Index = T::from(Ptr.getIndex(), Offset.bitWidth());
```

Added: 
    

Modified: 
    clang/lib/AST/Interp/Boolean.h
    clang/lib/AST/Interp/Integral.h
    clang/lib/AST/Interp/IntegralAP.h
    clang/lib/AST/Interp/Interp.h
    clang/test/AST/Interp/intap.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h
index c3ed3d61f76ca1c..336f7941dfc479d 100644
--- a/clang/lib/AST/Interp/Boolean.h
+++ b/clang/lib/AST/Interp/Boolean.h
@@ -42,6 +42,7 @@ class Boolean final {
   bool operator>(unsigned RHS) const { return static_cast<unsigned>(V) > RHS; }
 
   Boolean operator-() const { return Boolean(V); }
+  Boolean operator-(const Boolean &Other) const { return Boolean(V - Other.V); }
   Boolean operator~() const { return Boolean(true); }
 
   explicit operator int8_t() const { return V; }

diff  --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h
index 4dbe9c9bcb14b43..cc1cab8f39fb1e5 100644
--- a/clang/lib/AST/Interp/Integral.h
+++ b/clang/lib/AST/Interp/Integral.h
@@ -88,6 +88,9 @@ template <unsigned Bits, bool Signed> class Integral final {
   }
 
   Integral operator-() const { return Integral(-V); }
+  Integral operator-(const Integral &Other) const {
+    return Integral(V - Other.V);
+  }
   Integral operator~() const { return Integral(~V); }
 
   template <unsigned DstBits, bool DstSign>

diff  --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h
index f9a33bbcd7bd7fa..f17fb8e484415d2 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -59,6 +59,9 @@ template <bool Signed> class IntegralAP final {
   IntegralAP() : V(APSInt::getMaxValue(1024, Signed)) {}
 
   IntegralAP operator-() const { return IntegralAP(-V); }
+  IntegralAP operator-(const IntegralAP &Other) const {
+    return IntegralAP(V - Other.V);
+  }
   bool operator>(IntegralAP RHS) const { return V > RHS.V; }
   bool operator>=(IntegralAP RHS) const { return V >= RHS.V; }
   bool operator<(IntegralAP RHS) const { return V < RHS.V; }

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 1ad3b8bfc7711d3..e3e6a4cec63b194 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1421,7 +1421,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   // Get a version of the index comparable to the type.
   T Index = T::from(Ptr.getIndex(), Offset.bitWidth());
   // Compute the largest index into the array.
-  unsigned MaxIndex = Ptr.getNumElems();
+  T MaxIndex = T::from(Ptr.getNumElems(), Offset.bitWidth());
 
   // Helper to report an invalid offset, computed as APSInt.
   auto InvalidOffset = [&]() {
@@ -1437,7 +1437,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
     return false;
   };
 
-  unsigned MaxOffset = MaxIndex - Ptr.getIndex();
+  T MaxOffset = T::from(MaxIndex - Index, Offset.bitWidth());
   if constexpr (Op == ArithOp::Add) {
     // If the new offset would be negative, bail out.
     if (Offset.isNegative() && (Offset.isMin() || -Offset > Index))

diff  --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 8fe65a69a4fee8d..f9cbc698a3290d8 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -90,4 +90,14 @@ namespace i128 {
                                            // expected-error {{must be initialized by a constant expression}} \
                                            // expected-note {{is outside the range of representable values of type}}
 }
+
+namespace AddSubOffset {
+  constexpr __int128 A = 1;
+  constexpr int arr[] = {1,2,3};
+  constexpr const int *P = arr + A;
+  static_assert(*P == 2, "");
+  constexpr const int *P2 = P - A;
+  static_assert(*P2 == 1,"");
+}
+
 #endif


        


More information about the cfe-commits mailing list