Skip to content

Commit 712ab80

Browse files
authored
[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.
1 parent 073b057 commit 712ab80

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,9 +2633,10 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
26332633
ThisPtr.getFieldDesc()->getType()->getAsCXXRecordDecl();
26342634
if (Func->getParentDecl()->isDerivedFrom(ThisFieldDecl)) {
26352635
// If the function we call is further DOWN the hierarchy than the
2636-
// FieldDesc of our pointer, just get the DeclDesc instead, which
2637-
// is the furthest we might go up in the hierarchy.
2638-
ThisPtr = ThisPtr.getDeclPtr();
2636+
// FieldDesc of our pointer, just go up the hierarchy of this field
2637+
// the furthest we can go.
2638+
while (ThisPtr.isBaseClass())
2639+
ThisPtr = ThisPtr.getBase();
26392640
}
26402641
}
26412642

clang/test/AST/Interp/records.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,3 +1572,27 @@ namespace ctorOverrider {
15721572
constexpr Covariant1 cb;
15731573
}
15741574
#endif
1575+
1576+
#if __cplusplus >= 202002L
1577+
namespace VirtDtor {
1578+
struct X { char *p; constexpr ~X() { *p++ = 'X'; } };
1579+
struct Y : X { int y; virtual constexpr ~Y() { *p++ = 'Y'; } };
1580+
struct Z : Y { int z; constexpr ~Z() override { *p++ = 'Z'; } };
1581+
1582+
union VU {
1583+
constexpr VU() : z() {}
1584+
constexpr ~VU() {}
1585+
Z z;
1586+
};
1587+
1588+
constexpr char virt_dtor(int mode, const char *expected) {
1589+
char buff[4] = {};
1590+
VU vu;
1591+
vu.z.p = buff;
1592+
1593+
((Y&)vu.z).~Y();
1594+
return true;
1595+
}
1596+
static_assert(virt_dtor(0, "ZYX"));
1597+
}
1598+
#endif

0 commit comments

Comments
 (0)