llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> This is only permitted in a std::allocator::deallocate frame. --- Full diff: https://github.com/llvm/llvm-project/pull/136141.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+35) - (modified) clang/test/AST/ByteCode/new-delete.cpp (+12) ``````````diff diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 31d97d9060142..34553301ef630 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>(); diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index 5ddd7070f6710..e1b81e9a7963e 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -992,6 +992,18 @@ namespace ZeroSizeSub { // both-note {{in call to}} } +namespace WrongFrame { + constexpr int foo() { + int *p = nullptr; + __builtin_operator_delete(p); // both-note {{subexpression not valid in a constant expression}} + + return 1; + } + static_assert(foo()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +} + #else /// Make sure we reject this prior to C++20 constexpr int a() { // both-error {{never produces a constant expression}} `````````` </details> https://github.com/llvm/llvm-project/pull/136141 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits