[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField
Timm Bäder via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 25 05:51:29 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.
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149149.516763.patch
Type: text/x-patch
Size: 3465 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230425/83156536/attachment-0001.bin>
More information about the cfe-commits
mailing list