[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