@@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
19441944
19451945template <class T , ArithOp Op>
19461946bool 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
20692070template <PrimType Name, class T = typename PrimConv<Name>::T>
20702071bool 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
20762078template <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.
0 commit comments