@@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
1944
1944
1945
1945
template <class T , ArithOp Op>
1946
1946
bool OffsetHelper (InterpState &S, CodePtr OpPC, const T &Offset,
1947
- const Pointer &Ptr) {
1947
+ const Pointer &Ptr, bool IsPointerArith = false ) {
1948
1948
// A zero offset does not change the pointer.
1949
1949
if (Offset.isZero ()) {
1950
1950
S.Stk .push <Pointer>(Ptr);
1951
1951
return true ;
1952
1952
}
1953
1953
1954
- if (!CheckNull (S, OpPC, Ptr, CSK_ArrayIndex)) {
1954
+ if (IsPointerArith && !CheckNull (S, OpPC, Ptr, CSK_ArrayIndex)) {
1955
1955
// The CheckNull will have emitted a note already, but we only
1956
1956
// abort in C++, since this is fine in C.
1957
1957
if (S.getLangOpts ().CPlusPlus )
@@ -2063,14 +2063,16 @@ bool AddOffset(InterpState &S, CodePtr OpPC) {
2063
2063
Pointer Ptr = S.Stk .pop <Pointer>();
2064
2064
if (Ptr.isBlockPointer ())
2065
2065
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 );
2067
2068
}
2068
2069
2069
2070
template <PrimType Name, class T = typename PrimConv<Name>::T>
2070
2071
bool SubOffset (InterpState &S, CodePtr OpPC) {
2071
2072
const T &Offset = S.Stk .pop <T>();
2072
2073
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 );
2074
2076
}
2075
2077
2076
2078
template <ArithOp Op>
@@ -2090,7 +2092,7 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,
2090
2092
2091
2093
// Now the current Ptr again and a constant 1.
2092
2094
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 ))
2094
2096
return false ;
2095
2097
2096
2098
// Store the new value.
0 commit comments