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

via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 11 00:40:04 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/102800.diff


2 Files Affected:

- (modified) clang/lib/AST/Interp/Interp.h (+4-3) 
- (modified) clang/test/AST/Interp/records.cpp (+24) 


``````````diff
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

``````````

</details>


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


More information about the cfe-commits mailing list