Author: Timm Baeder Date: 2025-02-11T16:51:21+01:00 New Revision: 9387fd96314c59fc9aff1a82e478f9b89a97c20a
URL: https://github.com/llvm/llvm-project/commit/9387fd96314c59fc9aff1a82e478f9b89a97c20a DIFF: https://github.com/llvm/llvm-project/commit/9387fd96314c59fc9aff1a82e478f9b89a97c20a.diff LOG: [clang][bytecode] Fix diagnosing replaceable global allocator functions (#126717) Don't return true here in InvalidNewDeleteExpr just because we are in C++26 mode. This invalid there as well. Testcase reduced from libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.pass.cpp Added: Modified: clang/lib/AST/ByteCode/Interp.cpp clang/test/AST/ByteCode/cxx26.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index bf48139f57c0f09..c80be094856b086 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1564,34 +1564,38 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E, bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E) { assert(E); - if (S.getLangOpts().CPlusPlus26) - return true; - - const auto &Loc = S.Current->getSource(OpPC); - if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) { const FunctionDecl *OperatorNew = NewExpr->getOperatorNew(); - if (!S.getLangOpts().CPlusPlus26 && NewExpr->getNumPlacementArgs() > 0) { + if (NewExpr->getNumPlacementArgs() > 0) { // This is allowed pre-C++26, but only an std function. - if (S.Current->isStdFunction()) + if (S.getLangOpts().CPlusPlus26 || S.Current->isStdFunction()) return true; - S.FFDiag(Loc, diag::note_constexpr_new_placement) + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement) << /*C++26 feature*/ 1 << E->getSourceRange(); - } else if (NewExpr->getNumPlacementArgs() == 1 && - !OperatorNew->isReservedGlobalPlacementOperator()) { - S.FFDiag(Loc, diag::note_constexpr_new_placement) - << /*Unsupported*/ 0 << E->getSourceRange(); } else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) { - S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable) + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_new_non_replaceable) << isa<CXXMethodDecl>(OperatorNew) << OperatorNew; + return false; + } else if (!S.getLangOpts().CPlusPlus26 && + NewExpr->getNumPlacementArgs() == 1 && + !OperatorNew->isReservedGlobalPlacementOperator()) { + if (!S.getLangOpts().CPlusPlus26) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement) + << /*Unsupported*/ 0 << E->getSourceRange(); + return false; + } + return true; } } else { const auto *DeleteExpr = cast<CXXDeleteExpr>(E); const FunctionDecl *OperatorDelete = DeleteExpr->getOperatorDelete(); if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) { - S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable) + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_new_non_replaceable) << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete; + return false; } } diff --git a/clang/test/AST/ByteCode/cxx26.cpp b/clang/test/AST/ByteCode/cxx26.cpp index 0b0e2b21e8201e7..cd6b5330650100e 100644 --- a/clang/test/AST/ByteCode/cxx26.cpp +++ b/clang/test/AST/ByteCode/cxx26.cpp @@ -1,10 +1,33 @@ // RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=ref,both %s // RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter -// both-no-diagnostics +namespace std { + using size_t = decltype(sizeof(0)); +} namespace VoidCast { constexpr void* p = nullptr; constexpr int* q = static_cast<int*>(p); static_assert(q == nullptr); } + +namespace ReplaceableAlloc { + struct F { + static void* operator new(std::size_t n) { + return nullptr; // both-warning {{should not return a null pointer}} + } + }; + + constexpr F *createF() { + return new F(); // both-note {{call to class-specific 'operator new'}} + } + + constexpr bool foo() { + F *f = createF(); // both-note {{in call to}} + + delete f; + return true; + } + static_assert(foo()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits