[clang] 943ef06 - [clang][Interp] Check This pointer without creating InterpFrame

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 31 07:18:36 PDT 2023


Author: Timm Bäder
Date: 2023-03-31T16:18:15+02:00
New Revision: 943ef06420105cad23e3caea24d6a274cdb0316f

URL: https://github.com/llvm/llvm-project/commit/943ef06420105cad23e3caea24d6a274cdb0316f
DIFF: https://github.com/llvm/llvm-project/commit/943ef06420105cad23e3caea24d6a274cdb0316f.diff

LOG: [clang][Interp] Check This pointer without creating InterpFrame

The InterpFrame was only created so early so we could use getThis().
However, we need to know the Function when creating the InterpFrame and
in the case of virtual functions, we need to determine what function to
call at interpretation time.

Get the This pointer ourselves and just create the InterpFrame later.

Differential Revision: https://reviews.llvm.org/D142617

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/InterpStack.cpp
    clang/lib/AST/Interp/InterpStack.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index bb34737e018b..afc5f24baf73 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1492,10 +1492,11 @@ inline bool CheckGlobalCtor(InterpState &S, CodePtr &PC) {
 }
 
 inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
-  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
-  Pointer ThisPtr;
   if (Func->hasThisPointer()) {
-    ThisPtr = NewFrame->getThis();
+    size_t ThisOffset =
+        Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+    const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
+
     if (!CheckInvoke(S, PC, ThisPtr))
       return false;
 
@@ -1506,6 +1507,7 @@ inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
   if (!CheckCallable(S, PC, Func))
     return false;
 
+  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 

diff  --git a/clang/lib/AST/Interp/InterpStack.cpp b/clang/lib/AST/Interp/InterpStack.cpp
index 7fe678e62192..63a088be6705 100644
--- a/clang/lib/AST/Interp/InterpStack.cpp
+++ b/clang/lib/AST/Interp/InterpStack.cpp
@@ -46,7 +46,7 @@ void *InterpStack::grow(size_t Size) {
   return Object;
 }
 
-void *InterpStack::peek(size_t Size) const {
+void *InterpStack::peekData(size_t Size) const {
   assert(Chunk && "Stack is empty!");
 
   StackChunk *Ptr = Chunk;

diff  --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h
index e625ffd8e421..435120d0e441 100644
--- a/clang/lib/AST/Interp/InterpStack.h
+++ b/clang/lib/AST/Interp/InterpStack.h
@@ -64,11 +64,16 @@ class InterpStack final {
 
   /// Returns a reference to the value on the top of the stack.
   template <typename T> T &peek() const {
-    return *reinterpret_cast<T *>(peek(aligned_size<T>()));
+    return *reinterpret_cast<T *>(peekData(aligned_size<T>()));
+  }
+
+  template <typename T> T &peek(size_t Offset) const {
+    assert(aligned(Offset));
+    return *reinterpret_cast<T *>(peekData(Offset));
   }
 
   /// Returns a pointer to the top object.
-  void *top() const { return Chunk ? peek(0) : nullptr; }
+  void *top() const { return Chunk ? peekData(0) : nullptr; }
 
   /// Returns the size of the stack in bytes.
   size_t size() const { return StackSize; }
@@ -90,7 +95,7 @@ class InterpStack final {
   /// Grows the stack to accommodate a value and returns a pointer to it.
   void *grow(size_t Size);
   /// Returns a pointer from the top of the stack.
-  void *peek(size_t Size) const;
+  void *peekData(size_t Size) const;
   /// Shrinks the stack.
   void shrink(size_t Size);
 


        


More information about the cfe-commits mailing list