[clang][bytecode] Reject calls to pure virtual functions (#128412)
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user