@@ -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.
@@ -2816,9 +2818,18 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
28162818 return false ;
28172819}
28182820
2819- inline bool InvalidDeclRef (InterpState &S, CodePtr OpPC,
2820- const DeclRefExpr *DR ) {
2821+ inline bool InvalidDeclRef (InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
2822+ bool InitializerFailed ) {
28212823 assert (DR);
2824+
2825+ if (InitializerFailed) {
2826+ const SourceInfo &Loc = S.Current ->getSource (OpPC);
2827+ const auto *VD = cast<VarDecl>(DR->getDecl ());
2828+ S.FFDiag (Loc, diag::note_constexpr_var_init_non_constant, 1 ) << VD;
2829+ S.Note (VD->getLocation (), diag::note_declared_at);
2830+ return false ;
2831+ }
2832+
28222833 return CheckDeclRef (S, OpPC, DR);
28232834}
28242835
0 commit comments