[PATCH] D149013: [clang][Interp] Check pointers when accessing base class
Timm Bäder via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 23 01:19:33 PDT 2023
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.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D149013
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
@@ -497,6 +497,21 @@
//static_assert(b.a.f == 100, "");
}
+namespace PointerArith {
+ struct A {};
+ struct B : A { int n; };
+
+ B b = {};
+ constexpr A *a1 = &b;
+ constexpr B *b1 = &b + 1;
+ constexpr B *b2 = &b + 0;
+
+ constexpr A *a2 = &b + 1; // expected-error {{must be initialized by a constant expression}} \
+ // 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}}
+}
+
#if __cplusplus >= 202002L
namespace VirtualCalls {
namespace Obvious {
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -67,6 +67,9 @@
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
CheckSubobjectKind CSK);
+/// Checks if accessing a base of the given pointer is valid.
+bool CheckBase(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
+
/// Checks if a pointer points to const storage.
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
@@ -1079,6 +1082,8 @@
const Pointer &Ptr = S.Stk.peek<Pointer>();
if (!CheckNull(S, OpPC, Ptr, CSK_Base))
return false;
+ if (!CheckBase(S, OpPC, Ptr))
+ return false;
S.Stk.push<Pointer>(Ptr.atField(Off));
return true;
}
@@ -1087,6 +1092,8 @@
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (!CheckNull(S, OpPC, Ptr, CSK_Base))
return false;
+ if (!CheckBase(S, OpPC, Ptr))
+ 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,6 +211,15 @@
return false;
}
+bool CheckBase(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
+ if (!Ptr.isOnePastEnd())
+ return true;
+
+ const SourceInfo &Loc = S.Current->getSource(OpPC);
+ S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) << CSK_Base;
+ return false;
+}
+
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
assert(Ptr.isLive() && "Pointer is not live");
if (!Ptr.isConst())
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149013.516130.patch
Type: text/x-patch
Size: 2574 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230423/73b74eaf/attachment-0001.bin>
More information about the cfe-commits
mailing list