tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Rename CheckBaseDerived to something more general and call it in GetPtrField() as well, so we don't crash later in Pointer::toAPValue(). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D149149 Files: clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Interp.h clang/test/AST/Interp/records.cpp Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -510,6 +510,12 @@ // expected-note {{cannot access base class of pointer past the end of object}} \ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{cannot access base class of pointer past the end of object}} + + constexpr const int *pn = &(&b + 1)->n; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{cannot access field of pointer past the end of object}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{cannot access field of pointer past the end of object}} + } #if __cplusplus >= 202002L Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -67,9 +67,9 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK); -/// Checks if accessing a base or derived record of the given pointer is valid. -bool CheckBaseDerived(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - CheckSubobjectKind CSK); +/// Checks if Ptr is a one-past-the-end pointer. +bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + CheckSubobjectKind CSK); /// Checks if a pointer points to const storage. bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr); @@ -1039,6 +1039,8 @@ return false; if (!CheckRange(S, OpPC, Ptr, CSK_Field)) return false; + if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) + return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; } @@ -1083,7 +1085,7 @@ const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Derived)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Derived)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived)) return false; S.Stk.push<Pointer>(Ptr.atFieldSub(Off)); return true; @@ -1093,7 +1095,7 @@ const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; @@ -1103,7 +1105,7 @@ const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; Index: clang/lib/AST/Interp/Interp.cpp =================================================================== --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -211,8 +211,8 @@ return false; } -bool CheckBaseDerived(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - CheckSubobjectKind CSK) { +bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + CheckSubobjectKind CSK) { if (!Ptr.isOnePastEnd()) return true;
Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -510,6 +510,12 @@ // expected-note {{cannot access base class of pointer past the end of object}} \ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{cannot access base class of pointer past the end of object}} + + constexpr const int *pn = &(&b + 1)->n; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{cannot access field of pointer past the end of object}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{cannot access field of pointer past the end of object}} + } #if __cplusplus >= 202002L Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -67,9 +67,9 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK); -/// Checks if accessing a base or derived record of the given pointer is valid. -bool CheckBaseDerived(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - CheckSubobjectKind CSK); +/// Checks if Ptr is a one-past-the-end pointer. +bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + CheckSubobjectKind CSK); /// Checks if a pointer points to const storage. bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr); @@ -1039,6 +1039,8 @@ return false; if (!CheckRange(S, OpPC, Ptr, CSK_Field)) return false; + if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) + return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; } @@ -1083,7 +1085,7 @@ const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Derived)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Derived)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived)) return false; S.Stk.push<Pointer>(Ptr.atFieldSub(Off)); return true; @@ -1093,7 +1095,7 @@ const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; @@ -1103,7 +1105,7 @@ const Pointer &Ptr = S.Stk.pop<Pointer>(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; - if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base)) + if (!CheckSubobject(S, OpPC, Ptr, CSK_Base)) return false; S.Stk.push<Pointer>(Ptr.atField(Off)); return true; Index: clang/lib/AST/Interp/Interp.cpp =================================================================== --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -211,8 +211,8 @@ return false; } -bool CheckBaseDerived(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - CheckSubobjectKind CSK) { +bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + CheckSubobjectKind CSK) { if (!Ptr.isOnePastEnd()) return true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits