aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/InterpBuiltin.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-04-17 17:30:22 +0200
committerGitHub <noreply@github.com>2025-04-17 17:30:22 +0200
commit70e2acf0c5650b8862c41f2697a9e0485ecb17be (patch)
tree816eb115a509a61d8778d77814e60fbb68d40885 /clang/lib/AST/ByteCode/InterpBuiltin.cpp
parentecbd2d5e148cc1f2e5795d13d752e2a1c79cce1a (diff)
downloadllvm-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.cpp35
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>();