[clang] [clang][Interp] Properly adjust instance pointer in virtual calls (PR #102800)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 11 00:39:33 PDT 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/102800

None

>From 623d80c732da293e8696dbb77cb617b42a49e684 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sun, 11 Aug 2024 09:36:55 +0200
Subject: [PATCH] [clang][Interp] Properly adjust instance pointer in virtual
 calls

---
 clang/lib/AST/Interp/Interp.h     |  7 ++++---
 clang/test/AST/Interp/records.cpp | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index af33d507ef8d7..67b3fc5064509 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2633,9 +2633,10 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
         ThisPtr.getFieldDesc()->getType()->getAsCXXRecordDecl();
     if (Func->getParentDecl()->isDerivedFrom(ThisFieldDecl)) {
       // If the function we call is further DOWN the hierarchy than the
-      // FieldDesc of our pointer, just get the DeclDesc instead, which
-      // is the furthest we might go up in the hierarchy.
-      ThisPtr = ThisPtr.getDeclPtr();
+      // FieldDesc of our pointer, just go up the hierarchy of this field
+      // the furthest we can go.
+      while (ThisPtr.isBaseClass())
+        ThisPtr = ThisPtr.getBase();
     }
   }
 
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index 343665003c23e..e620bf9e0e041 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1572,3 +1572,27 @@ namespace ctorOverrider {
   constexpr Covariant1 cb;
 }
 #endif
+
+#if __cplusplus >= 202002L
+namespace VirtDtor {
+  struct X { char *p; constexpr ~X() { *p++ = 'X'; } };
+  struct Y : X { int y; virtual constexpr ~Y() { *p++ = 'Y'; } };
+  struct Z : Y { int z; constexpr ~Z() override { *p++ = 'Z'; } };
+
+  union VU {
+    constexpr VU() : z() {}
+    constexpr ~VU() {}
+    Z z;
+  };
+
+  constexpr char virt_dtor(int mode, const char *expected) {
+    char buff[4] = {};
+    VU vu;
+    vu.z.p = buff;
+
+    ((Y&)vu.z).~Y();
+    return true;
+  }
+  static_assert(virt_dtor(0, "ZYX"));
+}
+#endif



More information about the cfe-commits mailing list