Skip to content

Commit 031101c

Browse files
authored
[clang][bytecode] Diagnose delete of non-heap-allocated blocks (#137475)
With std::allocator::deallocate() calls
1 parent 2e230f5 commit 031101c

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,13 @@ static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC,
16411641

16421642
Source = Ptr.getDeclDesc()->asExpr();
16431643
BlockToDelete = Ptr.block();
1644+
1645+
if (!BlockToDelete->isDynamic()) {
1646+
S.FFDiag(Call, diag::note_constexpr_delete_not_heap_alloc)
1647+
<< Ptr.toDiagnosticString(S.getASTContext());
1648+
if (const auto *D = Ptr.getFieldDesc()->asDecl())
1649+
S.Note(D->getLocation(), diag::note_declared_at);
1650+
}
16441651
}
16451652
assert(BlockToDelete);
16461653

clang/test/AST/ByteCode/new-delete.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,8 @@ namespace std {
610610
}
611611
constexpr void deallocate(void *p) {
612612
__builtin_operator_delete(p); // both-note 2{{std::allocator<...>::deallocate' used to delete pointer to object allocated with 'new'}} \
613-
// both-note {{used to delete a null pointer}}
613+
// both-note {{used to delete a null pointer}} \
614+
// both-note {{delete of pointer '&no_deallocate_nonalloc' that does not point to a heap-allocated object}}
614615
}
615616
};
616617
template<typename T, typename ...Args>
@@ -1004,6 +1005,10 @@ namespace WrongFrame {
10041005

10051006
}
10061007

1008+
constexpr int no_deallocate_nonalloc = (std::allocator<int>().deallocate((int*)&no_deallocate_nonalloc), 1); // both-error {{constant expression}} \
1009+
// both-note {{in call}} \
1010+
// both-note {{declared here}}
1011+
10071012
#else
10081013
/// Make sure we reject this prior to C++20
10091014
constexpr int a() { // both-error {{never produces a constant expression}}

0 commit comments

Comments
 (0)