Skip to content

Commit

Permalink
[clang][Interp] Fix one-past-end pointers going back into the block
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Jul 13, 2024
1 parent 634128b commit 66e6df2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
9 changes: 9 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,15 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
else
Result = WideIndex - WideOffset;

// When the pointer is one-past-end, going back to index 0 is the only
// useful thing we can do. Any other index has been diagnosed before and
// we don't get here.
if (Result == 0 && Ptr.isOnePastEnd()) {
S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee,
Ptr.asBlockPointer().Base);
return true;
}

S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
return true;
}
Expand Down
12 changes: 12 additions & 0 deletions clang/test/AST/Interp/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,3 +1500,15 @@ namespace LocalWithThisPtrInit {
}
static_assert(foo() == 2, "");
}

namespace OnePastEndAndBack {
struct Base {
constexpr Base() {}
int n = 0;
};

constexpr Base a;
constexpr const Base *c = &a + 1;
constexpr const Base *d = c - 1;
static_assert(d == &a, "");
}

0 comments on commit 66e6df2

Please sign in to comment.