[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