Skip to content

Commit

Permalink
[clang][Interp] Support AddOffset with 128bit offsets (#68679)
Browse files Browse the repository at this point in the history
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());
```
  • Loading branch information
tbaederr committed Oct 13, 2023
1 parent 8d59fc5 commit 3efa479
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 2 deletions.
1 change: 1 addition & 0 deletions clang/lib/AST/Interp/Boolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Integral.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/IntegralAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [&]() {
Expand All @@ -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))
Expand Down
10 changes: 10 additions & 0 deletions clang/test/AST/Interp/intap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 3efa479

Please sign in to comment.