[clang] [clang][Interp] Fix stack peek offset for This ptr (PR #70663)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 30 23:20:27 PDT 2023


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/70663

>From dabbb865b01c823dba1cd532ee06e03e7e78631b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 30 Oct 2023 15:32:17 +0100
Subject: [PATCH] [clang][Interp] Fix stack peek offset for This ptr

Function::getArgSize() include both the instance and the RVO pointer, so
we need to subtract here.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 28 +++++++-----------------
 clang/lib/AST/Interp/ByteCodeExprGen.h   |  1 -
 clang/lib/AST/Interp/Interp.h            |  4 ++--
 clang/test/AST/Interp/literals.cpp       |  8 +++++++
 4 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 195af664c13dafc..ccfd35b4171b600 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2263,13 +2263,17 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
       }
     } else {
       assert(Initializing);
-      if (!isa<CXXMemberCallExpr>(E)) {
-        if (!this->emitDupPtr(E))
-          return false;
-      }
+      if (!this->emitDupPtr(E))
+        return false;
     }
   }
 
+  // Add the (optional, implicit) This pointer.
+  if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
+    if (!this->visit(MC->getImplicitObjectArgument()))
+      return false;
+  }
+
   // Put arguments on the stack.
   for (const auto *Arg : E->arguments()) {
     if (!this->visit(Arg))
@@ -2326,22 +2330,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
   return true;
 }
 
-template <class Emitter>
-bool ByteCodeExprGen<Emitter>::VisitCXXMemberCallExpr(
-    const CXXMemberCallExpr *E) {
-  if (Initializing) {
-    // If we're initializing, the current stack top is the pointer to
-    // initialize, so dup that so this call has its own version.
-    if (!this->emitDupPtr(E))
-      return false;
-  }
-
-  if (!this->visit(E->getImplicitObjectArgument()))
-    return false;
-
-  return VisitCallExpr(E);
-}
-
 template <class Emitter>
 bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr(
     const CXXDefaultInitExpr *E) {
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..7f832d93e3a2fe7 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -68,7 +68,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
   bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
   bool VisitCallExpr(const CallExpr *E);
   bool VisitBuiltinCallExpr(const CallExpr *E);
-  bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *E);
   bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E);
   bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
   bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7dd415d6e460536..a133318cab50b25 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1855,7 +1855,7 @@ inline bool CheckGlobalCtor(InterpState &S, CodePtr OpPC) {
 inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) {
   if (Func->hasThisPointer()) {
     size_t ThisOffset =
-        Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+        Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
 
     const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
 
@@ -1904,7 +1904,7 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func) {
   assert(Func->hasThisPointer());
   assert(Func->isVirtual());
   size_t ThisOffset =
-      Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+      Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
   Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
 
   const CXXRecordDecl *DynamicDecl =
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index ba24955d14503be..68833ec2dc48adf 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -1062,6 +1062,14 @@ namespace DiscardExprs {
   }
   static_assert(foo<3>() == 3, "");
 
+  struct ATemp {
+    consteval ATemp ret_a() const { return ATemp{}; }
+  };
+
+  void test() {
+    int k = (ATemp().ret_a(), 0);
+  }
+
 #pragma clang diagnostic pop
 }
 #endif



More information about the cfe-commits mailing list