[clang] 712ab80 - [clang][Interp] Properly adjust instance pointer in virtual calls (#102800)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 11 01:09:06 PDT 2024
Author: Timm Baeder
Date: 2024-08-11T10:09:03+02:00
New Revision: 712ab805140068a7b4719a38de3fee904841dbb3
URL: https://github.com/llvm/llvm-project/commit/712ab805140068a7b4719a38de3fee904841dbb3
DIFF: https://github.com/llvm/llvm-project/commit/712ab805140068a7b4719a38de3fee904841dbb3.diff
LOG: [clang][Interp] Properly adjust instance pointer in virtual calls (#102800)
`getDeclPtr()` will not just return what we want, but in this case a
pointer to the `vu` local variable.
Added:
Modified:
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/records.cpp
Removed:
################################################################################
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