Author: Timm Baeder Date: 2024-07-30T13:38:15+02:00 New Revision: c39daa6e19800d9a1b20ec6e04b2a68149dcf89c
URL: https://github.com/llvm/llvm-project/commit/c39daa6e19800d9a1b20ec6e04b2a68149dcf89c DIFF: https://github.com/llvm/llvm-project/commit/c39daa6e19800d9a1b20ec6e04b2a68149dcf89c.diff LOG: [clang][Interp] Pick right dynamic type when doing virtual calls (#101166) 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 22a86abf38225..d128988a480e1 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2588,12 +2588,20 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, size_t ThisOffset = ArgSize - (Func->hasRVO() ? primSize(PT_Ptr) : 0); Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset); - QualType DynamicType = ThisPtr.getDeclDesc()->getType(); - const CXXRecordDecl *DynamicDecl; - if (DynamicType->isPointerType() || DynamicType->isReferenceType()) - DynamicDecl = DynamicType->getPointeeCXXRecordDecl(); - else - DynamicDecl = ThisPtr.getDeclDesc()->getType()->getAsCXXRecordDecl(); + const CXXRecordDecl *DynamicDecl = nullptr; + { + Pointer TypePtr = ThisPtr; + while (TypePtr.isBaseClass()) + TypePtr = TypePtr.getBase(); + + QualType DynamicType = TypePtr.getType(); + if (DynamicType->isPointerType() || DynamicType->isReferenceType()) + DynamicDecl = DynamicType->getPointeeCXXRecordDecl(); + else + DynamicDecl = DynamicType->getAsCXXRecordDecl(); + } + assert(DynamicDecl); + const auto *StaticDecl = cast<CXXRecordDecl>(Func->getParentDecl()); const auto *InitialFunction = cast<CXXMethodDecl>(Func->getDecl()); const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction( diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 9551630caf3d6..479c0487fecae 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1560,3 +1560,19 @@ namespace ArrayInitChain { static_assert(A[1].Width == 12, ""); static_assert(A[1].Mask == 13, ""); } + +#if __cplusplus >= 202002L +namespace ctorOverrider { + // Ensure that we pick the right final overrider during construction. + struct A { + virtual constexpr char f() const { return 'A'; } + char a = f(); + }; + + struct Covariant1 { + A d; + }; + + constexpr Covariant1 cb; +} +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits