Skip to content

[clang][bytecode] Allow ArrayElemPtr ops on null pointers #113132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {

template <class T, ArithOp Op>
bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
const Pointer &Ptr) {
const Pointer &Ptr, bool IsPointerArith = false) {
// A zero offset does not change the pointer.
if (Offset.isZero()) {
S.Stk.push<Pointer>(Ptr);
return true;
}

if (!CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
if (IsPointerArith && !CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
// The CheckNull will have emitted a note already, but we only
// abort in C++, since this is fine in C.
if (S.getLangOpts().CPlusPlus)
Expand Down Expand Up @@ -2063,14 +2063,16 @@ bool AddOffset(InterpState &S, CodePtr OpPC) {
Pointer Ptr = S.Stk.pop<Pointer>();
if (Ptr.isBlockPointer())
Ptr = Ptr.expand();
return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr);
return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr,
/*IsPointerArith=*/true);
}

template <PrimType Name, class T = typename PrimConv<Name>::T>
bool SubOffset(InterpState &S, CodePtr OpPC) {
const T &Offset = S.Stk.pop<T>();
const Pointer &Ptr = S.Stk.pop<Pointer>();
return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr);
return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr,
/*IsPointerArith=*/true);
}

template <ArithOp Op>
Expand All @@ -2090,7 +2092,7 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,

// Now the current Ptr again and a constant 1.
OneT One = OneT::from(1);
if (!OffsetHelper<OneT, Op>(S, OpPC, One, P))
if (!OffsetHelper<OneT, Op>(S, OpPC, One, P, /*IsPointerArith=*/true))
return false;

// Store the new value.
Expand Down
3 changes: 1 addition & 2 deletions clang/test/AST/ByteCode/complex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,7 @@ namespace ComplexConstexpr {
// ref-note {{cannot access real component of null}} \
// expected-note {{read of dereferenced null pointer}}
constexpr float pi = __imag *p; // both-error {{constant expr}} \
// ref-note {{cannot access imaginary component of null}} \
// expected-note {{cannot perform pointer arithmetic on null pointer}}
// ref-note {{cannot access imaginary component of null}}
constexpr const _Complex double *q = &test3 + 1;
constexpr double qr = __real *q; // ref-error {{constant expr}} \
// ref-note {{cannot access real component of pointer past the end}}
Expand Down
Loading