Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f1985d5

Browse filesBrowse files
authored
[clang] Ensure type aware allocators handle transparent decl contexts (#138616)
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.
1 parent ffc5f79 commit f1985d5
Copy full SHA for f1985d5

File tree

Expand file treeCollapse file tree

2 files changed

+56
-8
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+56
-8
lines changed

‎clang/lib/Sema/SemaExprCXX.cpp

Copy file name to clipboardExpand all lines: clang/lib/Sema/SemaExprCXX.cpp
+13-8Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,18 +3070,24 @@ bool Sema::FindAllocationFunctions(
30703070
Filter.done();
30713071
}
30723072

3073+
auto GetRedeclContext = [](Decl *D) {
3074+
return D->getDeclContext()->getRedeclContext();
3075+
};
3076+
3077+
DeclContext *OperatorNewContext = GetRedeclContext(OperatorNew);
3078+
30733079
bool FoundGlobalDelete = FoundDelete.empty();
30743080
bool IsClassScopedTypeAwareNew =
30753081
isTypeAwareAllocation(IAP.PassTypeIdentity) &&
3076-
OperatorNew->getDeclContext()->isRecord();
3082+
OperatorNewContext->isRecord();
30773083
auto DiagnoseMissingTypeAwareCleanupOperator = [&](bool IsPlacementOperator) {
30783084
assert(isTypeAwareAllocation(IAP.PassTypeIdentity));
30793085
if (Diagnose) {
30803086
Diag(StartLoc, diag::err_mismatching_type_aware_cleanup_deallocator)
30813087
<< OperatorNew->getDeclName() << IsPlacementOperator << DeleteName;
30823088
Diag(OperatorNew->getLocation(), diag::note_type_aware_operator_declared)
30833089
<< OperatorNew->isTypeAwareOperatorNewOrDelete()
3084-
<< OperatorNew->getDeclName() << OperatorNew->getDeclContext();
3090+
<< OperatorNew->getDeclName() << OperatorNewContext;
30853091
}
30863092
};
30873093
if (IsClassScopedTypeAwareNew && FoundDelete.empty()) {
@@ -3224,15 +3230,15 @@ bool Sema::FindAllocationFunctions(
32243230
// deallocation function will be called.
32253231
if (Matches.size() == 1) {
32263232
OperatorDelete = Matches[0].second;
3233+
DeclContext *OperatorDeleteContext = GetRedeclContext(OperatorDelete);
32273234
bool FoundTypeAwareOperator =
32283235
OperatorDelete->isTypeAwareOperatorNewOrDelete() ||
32293236
OperatorNew->isTypeAwareOperatorNewOrDelete();
32303237
if (Diagnose && FoundTypeAwareOperator) {
32313238
bool MismatchedTypeAwareness =
32323239
OperatorDelete->isTypeAwareOperatorNewOrDelete() !=
32333240
OperatorNew->isTypeAwareOperatorNewOrDelete();
3234-
bool MismatchedContext =
3235-
OperatorDelete->getDeclContext() != OperatorNew->getDeclContext();
3241+
bool MismatchedContext = OperatorDeleteContext != OperatorNewContext;
32363242
if (MismatchedTypeAwareness || MismatchedContext) {
32373243
FunctionDecl *Operators[] = {OperatorDelete, OperatorNew};
32383244
bool TypeAwareOperatorIndex =
@@ -3241,16 +3247,15 @@ bool Sema::FindAllocationFunctions(
32413247
<< Operators[TypeAwareOperatorIndex]->getDeclName()
32423248
<< isPlacementNew
32433249
<< Operators[!TypeAwareOperatorIndex]->getDeclName()
3244-
<< Operators[TypeAwareOperatorIndex]->getDeclContext();
3250+
<< GetRedeclContext(Operators[TypeAwareOperatorIndex]);
32453251
Diag(OperatorNew->getLocation(),
32463252
diag::note_type_aware_operator_declared)
32473253
<< OperatorNew->isTypeAwareOperatorNewOrDelete()
3248-
<< OperatorNew->getDeclName() << OperatorNew->getDeclContext();
3254+
<< OperatorNew->getDeclName() << OperatorNewContext;
32493255
Diag(OperatorDelete->getLocation(),
32503256
diag::note_type_aware_operator_declared)
32513257
<< OperatorDelete->isTypeAwareOperatorNewOrDelete()
3252-
<< OperatorDelete->getDeclName()
3253-
<< OperatorDelete->getDeclContext();
3258+
<< OperatorDelete->getDeclName() << OperatorDeleteContext;
32543259
}
32553260
}
32563261

+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=0
2+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=1
3+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -fexceptions -DTRANSPARENT_DECL=2
4+
5+
// expected-no-diagnostics
6+
#if TRANSPARENT_DECL==2
7+
export module Testing;
8+
#endif
9+
10+
namespace std {
11+
template <class T> struct type_identity {};
12+
using size_t = __SIZE_TYPE__;
13+
enum class align_val_t : size_t {};
14+
struct destroying_delete_t { explicit destroying_delete_t() = default; };
15+
}
16+
17+
#if TRANSPARENT_DECL==0
18+
#define BEGIN_TRANSPARENT_DECL extern "C" {
19+
#define END_TRANSPARENT_DECL }
20+
#elif TRANSPARENT_DECL==1
21+
#define BEGIN_TRANSPARENT_DECL extern "C++" {
22+
#define END_TRANSPARENT_DECL }
23+
#elif TRANSPARENT_DECL==2
24+
#define BEGIN_TRANSPARENT_DECL export {
25+
#define END_TRANSPARENT_DECL }
26+
#else
27+
#error unexpected decl kind
28+
#endif
29+
30+
BEGIN_TRANSPARENT_DECL
31+
void *operator new(std::type_identity<int>, std::size_t, std::align_val_t);
32+
void operator delete[](std::type_identity<int>, void*, std::size_t, std::align_val_t);
33+
END_TRANSPARENT_DECL
34+
35+
void *operator new[](std::type_identity<int>, std::size_t, std::align_val_t);
36+
void operator delete(std::type_identity<int>, void*, std::size_t, std::align_val_t);
37+
38+
void foo() {
39+
int *iptr = new int;
40+
delete iptr;
41+
int *iarray = new int[5];
42+
delete [] iarray;
43+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.