[clang] [clang] Ensure type aware allocators handle transparent decl contexts (PR #138616)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Mon May 5 21:42:23 PDT 2025
https://github.com/ojhunt updated https://github.com/llvm/llvm-project/pull/138616
>From b12d78087c521d61f3e078d5a0d79889b17fbde9 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Mon, 5 May 2025 16:17:15 -0700
Subject: [PATCH 1/2] [clang] Ensure type aware allocators handle transparent
decl contexts
We were testing the immediate DeclContext for found new and delete
operators, which is incorrect if the declarations are contained by
a transparent decl as can be induced with extern or export statements.
---
clang/lib/Sema/SemaExprCXX.cpp | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 235ea1529b0b8..5bfd608afba04 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3070,10 +3070,16 @@ bool Sema::FindAllocationFunctions(
Filter.done();
}
+ auto GetRedeclContext = [](Decl *D) {
+ return D->getDeclContext()->getRedeclContext();
+ };
+
+ DeclContext *OperatorNewContext = GetRedeclContext(OperatorNew);
+
bool FoundGlobalDelete = FoundDelete.empty();
bool IsClassScopedTypeAwareNew =
isTypeAwareAllocation(IAP.PassTypeIdentity) &&
- OperatorNew->getDeclContext()->isRecord();
+ OperatorNewContext->isRecord();
auto DiagnoseMissingTypeAwareCleanupOperator = [&](bool IsPlacementOperator) {
assert(isTypeAwareAllocation(IAP.PassTypeIdentity));
if (Diagnose) {
@@ -3081,7 +3087,7 @@ bool Sema::FindAllocationFunctions(
<< OperatorNew->getDeclName() << IsPlacementOperator << DeleteName;
Diag(OperatorNew->getLocation(), diag::note_type_aware_operator_declared)
<< OperatorNew->isTypeAwareOperatorNewOrDelete()
- << OperatorNew->getDeclName() << OperatorNew->getDeclContext();
+ << OperatorNew->getDeclName() << OperatorNewContext;
}
};
if (IsClassScopedTypeAwareNew && FoundDelete.empty()) {
@@ -3224,6 +3230,7 @@ bool Sema::FindAllocationFunctions(
// deallocation function will be called.
if (Matches.size() == 1) {
OperatorDelete = Matches[0].second;
+ DeclContext *OperatorDeleteContext = GetRedeclContext(OperatorDelete);
bool FoundTypeAwareOperator =
OperatorDelete->isTypeAwareOperatorNewOrDelete() ||
OperatorNew->isTypeAwareOperatorNewOrDelete();
@@ -3231,8 +3238,7 @@ bool Sema::FindAllocationFunctions(
bool MismatchedTypeAwareness =
OperatorDelete->isTypeAwareOperatorNewOrDelete() !=
OperatorNew->isTypeAwareOperatorNewOrDelete();
- bool MismatchedContext =
- OperatorDelete->getDeclContext() != OperatorNew->getDeclContext();
+ bool MismatchedContext = OperatorDeleteContext != OperatorNewContext;
if (MismatchedTypeAwareness || MismatchedContext) {
FunctionDecl *Operators[] = {OperatorDelete, OperatorNew};
bool TypeAwareOperatorIndex =
@@ -3241,16 +3247,15 @@ bool Sema::FindAllocationFunctions(
<< Operators[TypeAwareOperatorIndex]->getDeclName()
<< isPlacementNew
<< Operators[!TypeAwareOperatorIndex]->getDeclName()
- << Operators[TypeAwareOperatorIndex]->getDeclContext();
+ << GetRedeclContext(Operators[TypeAwareOperatorIndex]);
Diag(OperatorNew->getLocation(),
diag::note_type_aware_operator_declared)
<< OperatorNew->isTypeAwareOperatorNewOrDelete()
- << OperatorNew->getDeclName() << OperatorNew->getDeclContext();
+ << OperatorNew->getDeclName() << OperatorNewContext;
Diag(OperatorDelete->getLocation(),
diag::note_type_aware_operator_declared)
<< OperatorDelete->isTypeAwareOperatorNewOrDelete()
- << OperatorDelete->getDeclName()
- << OperatorDelete->getDeclContext();
+ << OperatorDelete->getDeclName() << OperatorDeleteContext;
}
}
>From 98aca41a545cdffe756faac4a9e57b3886938e0a Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Mon, 5 May 2025 21:42:08 -0700
Subject: [PATCH 2/2] Sigh, actually add the test
---
...-aware-new-delete-transparent-contexts.cpp | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp
diff --git a/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp b/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp
new file mode 100644
index 0000000000000..7c0b967a3c03f
--- /dev/null
+++ b/clang/test/SemaCXX/type-aware-new-delete-transparent-contexts.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=0
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=1
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=2
+
+// expected-no-diagnostics
+#if TRANSPARENT_DECL==2
+export module Testing;
+#endif
+
+namespace std {
+ template <class T> struct type_identity {};
+ using size_t = __SIZE_TYPE__;
+ enum class align_val_t : size_t {};
+ struct destroying_delete_t { explicit destroying_delete_t() = default; };
+}
+
+#if TRANSPARENT_DECL==0
+#define BEGIN_TRANSPARENT_DECL extern "C" {
+#define END_TRANSPARENT_DECL }
+#elif TRANSPARENT_DECL==1
+#define BEGIN_TRANSPARENT_DECL extern "C++" {
+#define END_TRANSPARENT_DECL }
+#elif TRANSPARENT_DECL==2
+#define BEGIN_TRANSPARENT_DECL export {
+#define END_TRANSPARENT_DECL }
+#else
+#error unexpected decl kind
+#endif
+
+BEGIN_TRANSPARENT_DECL
+ void *operator new(std::type_identity<int>, std::size_t, std::align_val_t);
+ void operator delete[](std::type_identity<int>, void*, std::size_t, std::align_val_t);
+END_TRANSPARENT_DECL
+
+void *operator new[](std::type_identity<int>, std::size_t, std::align_val_t);
+void operator delete(std::type_identity<int>, void*, std::size_t, std::align_val_t);
+
+void foo() {
+ int *iptr = new int;
+ delete iptr;
+ int *iarray = new int[5];
+ delete [] iarray;
+}
More information about the cfe-commits
mailing list