Skip to content

Commit 7f0bbbb

Browse files
committed
[clang][Interp] Change array index types in OffsetHelper
This is closer to that the current interpreter does. It also fixes diagnostics in a case I was looking into. Unfortunately, this is not possible to test right now since it requires a large array and we don't implement array fillers yet.
1 parent efe0a2e commit 7f0bbbb

File tree

1 file changed

+13
-12
lines changed

1 file changed

+13
-12
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,17 +1548,16 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
15481548
if (!CheckArray(S, OpPC, Ptr))
15491549
return false;
15501550

1551-
// Get a version of the index comparable to the type.
1552-
T Index = T::from(Ptr.getIndex(), Offset.bitWidth());
1553-
// Compute the largest index into the array.
1554-
T MaxIndex = T::from(Ptr.getNumElems(), Offset.bitWidth());
1551+
uint64_t Index = Ptr.getIndex();
1552+
uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());
15551553

15561554
bool Invalid = false;
15571555
// Helper to report an invalid offset, computed as APSInt.
15581556
auto DiagInvalidOffset = [&]() -> void {
15591557
const unsigned Bits = Offset.bitWidth();
1560-
APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), false);
1561-
APSInt APIndex(Index.toAPSInt().extend(Bits + 2), false);
1558+
APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), /*IsUnsigend=*/false);
1559+
APSInt APIndex(APInt(Bits + 2, Index, /*IsSigned=*/true),
1560+
/*IsUnsigned=*/false);
15621561
APSInt NewIndex =
15631562
(Op == ArithOp::Add) ? (APIndex + APOffset) : (APIndex - APOffset);
15641563
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
@@ -1569,22 +1568,24 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
15691568
};
15701569

15711570
if (Ptr.isBlockPointer()) {
1572-
T MaxOffset = T::from(MaxIndex - Index, Offset.bitWidth());
1571+
uint64_t IOffset = static_cast<uint64_t>(Offset);
1572+
uint64_t MaxOffset = MaxIndex - Index;
1573+
15731574
if constexpr (Op == ArithOp::Add) {
15741575
// If the new offset would be negative, bail out.
1575-
if (Offset.isNegative() && (Offset.isMin() || -Offset > Index))
1576+
if (Offset.isNegative() && (Offset.isMin() || -IOffset > Index))
15761577
DiagInvalidOffset();
15771578

15781579
// If the new offset would be out of bounds, bail out.
1579-
if (Offset.isPositive() && Offset > MaxOffset)
1580+
if (Offset.isPositive() && IOffset > MaxOffset)
15801581
DiagInvalidOffset();
15811582
} else {
15821583
// If the new offset would be negative, bail out.
1583-
if (Offset.isPositive() && Index < Offset)
1584+
if (Offset.isPositive() && Index < IOffset)
15841585
DiagInvalidOffset();
15851586

15861587
// If the new offset would be out of bounds, bail out.
1587-
if (Offset.isNegative() && (Offset.isMin() || -Offset > MaxOffset))
1588+
if (Offset.isNegative() && (Offset.isMin() || -IOffset > MaxOffset))
15881589
DiagInvalidOffset();
15891590
}
15901591
}
@@ -1601,7 +1602,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
16011602
else
16021603
Result = WideIndex - WideOffset;
16031604

1604-
S.Stk.push<Pointer>(Ptr.atIndex(static_cast<unsigned>(Result)));
1605+
S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
16051606
return true;
16061607
}
16071608

0 commit comments

Comments
 (0)