Skip to content

Commit 9604e5c

Browse files
committed
[clang][Interp] Allow stepping back from a one-past-the-end pointer
... back into range of the array.
1 parent c912f0e commit 9604e5c

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,8 +1555,12 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
15551555
if (!CheckArray(S, OpPC, Ptr))
15561556
return false;
15571557

1558-
uint64_t Index = Ptr.getIndex();
15591558
uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());
1559+
uint64_t Index;
1560+
if (Ptr.isOnePastEnd())
1561+
Index = MaxIndex;
1562+
else
1563+
Index = Ptr.getIndex();
15601564

15611565
bool Invalid = false;
15621566
// Helper to report an invalid offset, computed as APSInt.

clang/lib/AST/Interp/Pointer.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,9 +537,6 @@ class Pointer {
537537
if (isZero())
538538
return 0;
539539

540-
if (isElementPastEnd())
541-
return 1;
542-
543540
// narrow()ed element in a composite array.
544541
if (asBlockPointer().Base > sizeof(InlineDescriptor) &&
545542
asBlockPointer().Base == Offset)

clang/test/AST/Interp/arrays.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ constexpr int derefPtr(const int *d) {
5454
}
5555
static_assert(derefPtr(data) == 5, "");
5656

57+
/// Make sure we can refer to the one-past-the-end element
58+
/// and then return back to the end of the array.
59+
static_assert((&data[5])[-1] == 1, "");
60+
5761
constexpr int storePtr() {
5862
int b[] = {1,2,3,4};
5963
int *c = b;

0 commit comments

Comments
 (0)