summaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-10-28 08:35:48 +0100
committerGitHub <noreply@github.com>2025-10-28 08:35:48 +0100
commitf49cd170c0a05875542d4e042265b05312fa00ef (patch)
tree9a864b56b16a99a5c46fde71c559719c87b9072c /clang/lib/AST/ByteCode/Interp.cpp
parent6bf948999fa7dcf86b3f564827168616321ebd72 (diff)
[clang][bytecode] Check overrider for pure virtual (#165262)
Instead of checking the initial callee, check the callee after the virtual dispatch. This means we need to check whether we're in a ctor to not regress existing tests. Fixes https://github.com/llvm/llvm-project/issues/165234
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp32
1 files changed, 15 insertions, 17 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index d640be032b4f..a2fb0fb331f8 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1651,8 +1651,8 @@ static bool GetDynamicDecl(InterpState &S, CodePtr OpPC, Pointer TypePtr,
QualType DynamicType = TypePtr.getType();
if (TypePtr.isStatic() || TypePtr.isConst()) {
- const VarDecl *VD = TypePtr.getDeclDesc()->asVarDecl();
- if (!VD->isConstexpr()) {
+ if (const VarDecl *VD = TypePtr.getDeclDesc()->asVarDecl();
+ VD && !VD->isConstexpr()) {
const Expr *E = S.Current->getExpr(OpPC);
APValue V = TypePtr.toAPValue(S.getASTContext());
QualType TT = S.getASTContext().getLValueReferenceType(DynamicType);
@@ -1683,20 +1683,6 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
const FunctionDecl *Callee = Func->getDecl();
- if (!Func->isFullyCompiled())
- compileFunction(S, Func);
-
- // 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;
if (!GetDynamicDecl(S, OpPC, ThisPtr, DynamicDecl))
return false;
@@ -1706,7 +1692,8 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
const auto *InitialFunction = cast<CXXMethodDecl>(Callee);
const CXXMethodDecl *Overrider;
- if (StaticDecl != DynamicDecl) {
+ if (StaticDecl != DynamicDecl &&
+ !llvm::is_contained(S.InitializingBlocks, ThisPtr.block())) {
if (!DynamicDecl->isDerivedFrom(StaticDecl))
return false;
Overrider = S.getContext().getOverridingFunction(DynamicDecl, StaticDecl,
@@ -1716,6 +1703,17 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
Overrider = InitialFunction;
}
+ // C++2a [class.abstract]p6:
+ // the effect of making a virtual call to a pure virtual function [...] is
+ // undefined
+ if (Overrider->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;
+ }
+
if (Overrider != InitialFunction) {
// DR1872: An instantiated virtual constexpr function can't be called in a
// constant expression (prior to C++20). We can still constant-fold such a