Skip to content

Commit 66e6df2

Browse files
committed
[clang][Interp] Fix one-past-end pointers going back into the block
1 parent 634128b commit 66e6df2

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,15 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
18441844
else
18451845
Result = WideIndex - WideOffset;
18461846

1847+
// When the pointer is one-past-end, going back to index 0 is the only
1848+
// useful thing we can do. Any other index has been diagnosed before and
1849+
// we don't get here.
1850+
if (Result == 0 && Ptr.isOnePastEnd()) {
1851+
S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee,
1852+
Ptr.asBlockPointer().Base);
1853+
return true;
1854+
}
1855+
18471856
S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
18481857
return true;
18491858
}

clang/test/AST/Interp/records.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,3 +1500,15 @@ namespace LocalWithThisPtrInit {
15001500
}
15011501
static_assert(foo() == 2, "");
15021502
}
1503+
1504+
namespace OnePastEndAndBack {
1505+
struct Base {
1506+
constexpr Base() {}
1507+
int n = 0;
1508+
};
1509+
1510+
constexpr Base a;
1511+
constexpr const Base *c = &a + 1;
1512+
constexpr const Base *d = c - 1;
1513+
static_assert(d == &a, "");
1514+
}

0 commit comments

Comments
 (0)