Author: Timm Baeder Date: 2025-02-23T11:44:37+01:00 New Revision: 8102fec00bb90969eee1c2160829866aa5c8a32f
URL: https://github.com/llvm/llvm-project/commit/8102fec00bb90969eee1c2160829866aa5c8a32f DIFF: https://github.com/llvm/llvm-project/commit/8102fec00bb90969eee1c2160829866aa5c8a32f.diff LOG: [clang][bytecode] Reject calls to pure virtual functions (#128412) Added: Modified: clang/lib/AST/ByteCode/Interp.cpp clang/test/AST/ByteCode/cxx2a.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index b494fb44b0dcb..31126e48c7cd7 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1382,6 +1382,18 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, size_t ArgSize = Func->getArgSize() + VarArgSize; size_t ThisOffset = ArgSize - (Func->hasRVO() ? primSize(PT_Ptr) : 0); Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset); + const FunctionDecl *Callee = Func->getDecl(); + + // C++2a [class.abstract]p6: + // the effect of making a virtual call to a pure virtual function [...] is + // undefined + if (Callee->isPureVirtual()) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_pure_virtual_call, + 1) + << Callee; + S.Note(Callee->getLocation(), diag::note_declared_at); + return false; + } const CXXRecordDecl *DynamicDecl = nullptr; { @@ -1398,7 +1410,7 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, assert(DynamicDecl); const auto *StaticDecl = cast<CXXRecordDecl>(Func->getParentDecl()); - const auto *InitialFunction = cast<CXXMethodDecl>(Func->getDecl()); + const auto *InitialFunction = cast<CXXMethodDecl>(Callee); const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction( DynamicDecl, StaticDecl, InitialFunction); diff --git a/clang/test/AST/ByteCode/cxx2a.cpp b/clang/test/AST/ByteCode/cxx2a.cpp index 72ef58ca0b1d1..d9541aca225b9 100644 --- a/clang/test/AST/ByteCode/cxx2a.cpp +++ b/clang/test/AST/ByteCode/cxx2a.cpp @@ -177,3 +177,13 @@ consteval int f(int i) { return 2 * i; } static_assert(test(42)); + +namespace PureVirtual { + struct Abstract { + constexpr virtual void f() = 0; // both-note {{declared here}} + constexpr Abstract() { do_it(); } // both-note {{in call to}} + constexpr void do_it() { f(); } // both-note {{pure virtual function 'PureVirtual::Abstract::f' called}} + }; + struct PureVirtualCall : Abstract { void f(); }; // both-note {{in call to 'Abstract}} + constexpr PureVirtualCall pure_virtual_call; // both-error {{constant expression}} both-note {{in call to 'PureVirtualCall}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits