Skip to content

Commit 9387fd9

Browse files
authored
[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
1 parent c837f57 commit 9387fd9

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,34 +1564,38 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
15641564
bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E) {
15651565
assert(E);
15661566

1567-
if (S.getLangOpts().CPlusPlus26)
1568-
return true;
1569-
1570-
const auto &Loc = S.Current->getSource(OpPC);
1571-
15721567
if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) {
15731568
const FunctionDecl *OperatorNew = NewExpr->getOperatorNew();
15741569

1575-
if (!S.getLangOpts().CPlusPlus26 && NewExpr->getNumPlacementArgs() > 0) {
1570+
if (NewExpr->getNumPlacementArgs() > 0) {
15761571
// This is allowed pre-C++26, but only an std function.
1577-
if (S.Current->isStdFunction())
1572+
if (S.getLangOpts().CPlusPlus26 || S.Current->isStdFunction())
15781573
return true;
1579-
S.FFDiag(Loc, diag::note_constexpr_new_placement)
1574+
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement)
15801575
<< /*C++26 feature*/ 1 << E->getSourceRange();
1581-
} else if (NewExpr->getNumPlacementArgs() == 1 &&
1582-
!OperatorNew->isReservedGlobalPlacementOperator()) {
1583-
S.FFDiag(Loc, diag::note_constexpr_new_placement)
1584-
<< /*Unsupported*/ 0 << E->getSourceRange();
15851576
} else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) {
1586-
S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable)
1577+
S.FFDiag(S.Current->getSource(OpPC),
1578+
diag::note_constexpr_new_non_replaceable)
15871579
<< isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
1580+
return false;
1581+
} else if (!S.getLangOpts().CPlusPlus26 &&
1582+
NewExpr->getNumPlacementArgs() == 1 &&
1583+
!OperatorNew->isReservedGlobalPlacementOperator()) {
1584+
if (!S.getLangOpts().CPlusPlus26) {
1585+
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement)
1586+
<< /*Unsupported*/ 0 << E->getSourceRange();
1587+
return false;
1588+
}
1589+
return true;
15881590
}
15891591
} else {
15901592
const auto *DeleteExpr = cast<CXXDeleteExpr>(E);
15911593
const FunctionDecl *OperatorDelete = DeleteExpr->getOperatorDelete();
15921594
if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) {
1593-
S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable)
1595+
S.FFDiag(S.Current->getSource(OpPC),
1596+
diag::note_constexpr_new_non_replaceable)
15941597
<< isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
1598+
return false;
15951599
}
15961600
}
15971601

clang/test/AST/ByteCode/cxx26.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
// RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=ref,both %s
22
// RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter
33

4-
// both-no-diagnostics
4+
namespace std {
5+
using size_t = decltype(sizeof(0));
6+
}
57

68
namespace VoidCast {
79
constexpr void* p = nullptr;
810
constexpr int* q = static_cast<int*>(p);
911
static_assert(q == nullptr);
1012
}
13+
14+
namespace ReplaceableAlloc {
15+
struct F {
16+
static void* operator new(std::size_t n) {
17+
return nullptr; // both-warning {{should not return a null pointer}}
18+
}
19+
};
20+
21+
constexpr F *createF() {
22+
return new F(); // both-note {{call to class-specific 'operator new'}}
23+
}
24+
25+
constexpr bool foo() {
26+
F *f = createF(); // both-note {{in call to}}
27+
28+
delete f;
29+
return true;
30+
}
31+
static_assert(foo()); // both-error {{not an integral constant expression}} \
32+
// both-note {{in call to}}
33+
}

0 commit comments

Comments
 (0)