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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits