Skip to content

Commit 923b8ee

Browse files
authored
[clang][bytecode] Allow ArrayElemPtr ops on null pointers (#113132)
This regresses one of the _Complex test cases a bit, but since the diagnostic output wasn't very good here in the first place, let's ignore it.
1 parent 3c5cea6 commit 923b8ee

File tree

2 files changed

+8
-7
lines changed

2 files changed

+8
-7
lines changed

clang/lib/AST/ByteCode/Interp.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
19441944

19451945
template <class T, ArithOp Op>
19461946
bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
1947-
const Pointer &Ptr) {
1947+
const Pointer &Ptr, bool IsPointerArith = false) {
19481948
// A zero offset does not change the pointer.
19491949
if (Offset.isZero()) {
19501950
S.Stk.push<Pointer>(Ptr);
19511951
return true;
19521952
}
19531953

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

20692070
template <PrimType Name, class T = typename PrimConv<Name>::T>
20702071
bool SubOffset(InterpState &S, CodePtr OpPC) {
20712072
const T &Offset = S.Stk.pop<T>();
20722073
const Pointer &Ptr = S.Stk.pop<Pointer>();
2073-
return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr);
2074+
return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr,
2075+
/*IsPointerArith=*/true);
20742076
}
20752077

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

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

20962098
// Store the new value.

clang/test/AST/ByteCode/complex.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,7 @@ namespace ComplexConstexpr {
407407
// ref-note {{cannot access real component of null}} \
408408
// expected-note {{read of dereferenced null pointer}}
409409
constexpr float pi = __imag *p; // both-error {{constant expr}} \
410-
// ref-note {{cannot access imaginary component of null}} \
411-
// expected-note {{cannot perform pointer arithmetic on null pointer}}
410+
// ref-note {{cannot access imaginary component of null}}
412411
constexpr const _Complex double *q = &test3 + 1;
413412
constexpr double qr = __real *q; // ref-error {{constant expr}} \
414413
// ref-note {{cannot access real component of pointer past the end}}

0 commit comments

Comments
 (0)