diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-04-17 17:30:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-17 17:30:22 +0200 |
commit | 70e2acf0c5650b8862c41f2697a9e0485ecb17be (patch) | |
tree | 816eb115a509a61d8778d77814e60fbb68d40885 /clang/lib/AST/ByteCode/InterpBuiltin.cpp | |
parent | ecbd2d5e148cc1f2e5795d13d752e2a1c79cce1a (diff) | |
download | llvm-70e2acf0c5650b8862c41f2697a9e0485ecb17be.zip llvm-70e2acf0c5650b8862c41f2697a9e0485ecb17be.tar.gz llvm-70e2acf0c5650b8862c41f2697a9e0485ecb17be.tar.bz2 |
[clang][bytecode] Check if operator delete calls are in the right frame (#136141)
This is only permitted in a std::allocator::deallocate frame.
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 31d97d9..3455330 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -1651,6 +1651,41 @@ static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC, const Expr *Source = nullptr; const Block *BlockToDelete = nullptr; + if (S.checkingPotentialConstantExpression()) + return false; + + // This is permitted only within a call to std::allocator<T>::deallocate. + bool DeallocateFrameFound = false; + for (const InterpFrame *F = Frame; F; F = F->Caller) { + const Function *Func = F->getFunction(); + if (!Func) + continue; + const auto *MD = dyn_cast_if_present<CXXMethodDecl>(Func->getDecl()); + if (!MD) + continue; + const IdentifierInfo *FnII = MD->getIdentifier(); + if (!FnII || !FnII->isStr("deallocate")) + continue; + + const auto *CTSD = + dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent()); + if (!CTSD) + continue; + + const IdentifierInfo *ClassII = CTSD->getIdentifier(); + const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); + if (CTSD->isInStdNamespace() && ClassII && ClassII->isStr("allocator") && + TAL.size() >= 1 && TAL[0].getKind() == TemplateArgument::Type) { + DeallocateFrameFound = true; + break; + } + } + + if (!DeallocateFrameFound) { + S.FFDiag(Call); + return true; + } + { const Pointer &Ptr = S.Stk.peek<Pointer>(); |