Skip to content

Commit edd4bc9

Browse files
committed
Address missed feedback and add test coverage for different compiler allocation modes
Github's UI choices meant I missed some of corentin's feedback. While addressing that feedback I realised some of the code patterns would impact behaviour under different compiler allocation modes (aligned new/delete, sized delete, etc), so updated the tests to cover all of those cases and ensured we do the correct thing for type aware operators.
1 parent deeab0a commit edd4bc9

9 files changed

+82
-38
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9795,9 +9795,9 @@ def err_type_aware_destroying_operator_delete : Error<
97959795
def err_unsupported_type_aware_allocator : Error<
97969796
"type aware allocation operators are disabled, enable with '-fexperimental-cxx-type-aware-allocators'">;
97979797
def err_no_type_aware_cleanup_operator_delete : Error<
9798-
"type aware %0 requires matching cleanup %1 in %2">;
9798+
"type aware %0 requires there to be a corresponding cleanup %1 in %2">;
97999799
def err_type_aware_cleanup_deallocator_context_mismatch : Error<
9800-
"type aware %0 requires matching %1 in %2">;
9800+
"type aware %0 requires there to be a corresponding %1 in %2">;
98019801
def err_type_aware_allocator_missing_matching_operator : Error<
98029802
"declaration of type aware %0 in %1 must have matching type aware %2"
98039803
>;
@@ -9806,7 +9806,7 @@ def note_unmatched_type_aware_allocator_declared : Note<
98069806
def note_type_aware_operator_found : Note<
98079807
"type aware %0 found in %1">;
98089808
def err_mismatching_type_aware_cleanup_deallocator : Error<
9809-
"mismatched type aware allocation operators for constructor cleanup">;
9809+
"type aware allocation requires matching type aware operator new and type aware operator delete for exception cleanup">;
98109810
def note_type_aware_operator_declared : Note<
98119811
"%select{non-|}0type aware %1 declared here">;
98129812
def note_implicit_delete_this_in_destructor_here : Note<

clang/lib/AST/DeclCXX.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,7 +2533,6 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
25332533
getOverloadedOperator() != OO_Array_Delete)
25342534
return false;
25352535

2536-
unsigned NumParams = getNumParams();
25372536
bool IsTypeAware = isTypeAwareOperatorNewOrDelete();
25382537

25392538
// C++ [basic.stc.dynamic.deallocation]p2:
@@ -2551,23 +2550,28 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
25512550
}
25522551

25532552
FunctionDecl *SpecializedDecl = PrimaryTemplate->getTemplatedDecl();
2554-
for (unsigned Idx = 1; Idx < NumParams; ++Idx) {
2553+
// A type aware allocation function template is only valid if the first
2554+
// parameter is dependent
2555+
if (!SpecializedDecl->getParamDecl(0)->getType()->isDependentType())
2556+
return false;
2557+
2558+
// and none of the other parameters are dependent
2559+
for (unsigned Idx = 1; Idx < getNumParams(); ++Idx) {
25552560
if (SpecializedDecl->getParamDecl(Idx)->getType()->isDependentType())
25562561
return false;
25572562
}
25582563
}
25592564

2560-
unsigned UsualParams = 1;
2561-
if (IsTypeAware)
2562-
++UsualParams;
2563-
25642565
// C++ [basic.stc.dynamic.deallocation]p2:
25652566
// If a class T has a member deallocation function named operator delete
2566-
// with exactly one parameter or a type aware operator delete with two
2567-
// arguments, then that function is a usual (non-placement)
2567+
// with exactly one parameter, then that function is a usual (non-placement)
25682568
// deallocation function. [...]
2569-
if (getNumParams() == UsualParams)
2569+
if (getNumParams() == 1)
25702570
return true;
2571+
unsigned UsualParams = 1;
2572+
2573+
if (IsTypeAware)
2574+
++UsualParams;
25712575

25722576
// C++ P0722:
25732577
// A destroying operator delete is a usual deallocation function if
@@ -2606,8 +2610,8 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
26062610
// FIXME(EricWF): Destroying Delete should be a language option. How do we
26072611
// handle when destroying delete is used prior to C++17?
26082612
if (Context.getLangOpts().CPlusPlus17 ||
2609-
Context.getLangOpts().AlignedAllocation ||
2610-
isDestroyingOperatorDelete())
2613+
Context.getLangOpts().AlignedAllocation || isDestroyingOperatorDelete() ||
2614+
IsTypeAware)
26112615
return true;
26122616

26132617
// This function is a usual deallocation function if there are no

clang/test/CodeGenCXX/type-aware-allocators.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
1+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck --check-prefixes=CHECK,CHECK_SIZED_ALIGNED %s
2+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_ALIGNED %s
3+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -fno-aligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_NO_ALIGN %s
4+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -fno-aligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck --check-prefixes=CHECK,CHECK_SIZED_NO_ALIGN %s
25

36

47
namespace std {
@@ -45,15 +48,30 @@ extern "C" void test_no_type_aware_allocator() {
4548
// CHECK: [[ALLOC_RESULT:%.*]] = call {{.*}} @_Znwm(
4649
// CHECK: @_ZN2S1C1Ev({{.*}} [[ALLOC_RESULT]])
4750
// CHECK-NEXT: unwind label %[[S1LPAD:lpad]]
48-
// CHECK: @_ZdlPvm(
49-
// CHECK: [[ALIGNED_ALLOC_RESULT:%.*]] = call {{.*}} @_ZnwmSt11align_val_t(
51+
// CHECK_SIZED_ALIGNED: @_ZdlPvm(
52+
// CHECK_SIZED_NO_ALIGN: @_ZdlPvm(
53+
// CHECK_NO_SIZE_ALIGNED: @_ZdlPv(
54+
// CHECK_NO_SIZE_NO_ALIGN: @_ZdlPv(
55+
// CHECK_SIZED_ALIGNED: [[ALIGNED_ALLOC_RESULT:%.*]] = call {{.*}} @_ZnwmSt11align_val_t(
56+
// CHECK_NO_SIZE_ALIGNED: [[ALIGNED_ALLOC_RESULT:%.*]] = call {{.*}} @_ZnwmSt11align_val_t(
57+
// CHECK_SIZED_NO_ALIGN: [[ALIGNED_ALLOC_RESULT:%.*]] = call {{.*}} @_Znwm(
58+
// CHECK_NO_SIZE_NO_ALIGN: [[ALIGNED_ALLOC_RESULT:%.*]] = call {{.*}} @_Znwm(
5059
// CHECK: _ZN2S2C1Ev({{.*}} [[ALIGNED_ALLOC_RESULT]])
5160
// CHECK-NEXT: unwind label %[[S2LPAD:lpad3]]
52-
// CHECK: _ZdlPvmSt11align_val_t(
61+
// CHECK_SIZED_ALIGNED: _ZdlPvmSt11align_val_t(
62+
// CHECK_NO_SIZE_ALIGNED: _ZdlPvSt11align_val_t(
63+
// CHECK_SIZED_NO_ALIGN: _ZdlPvm(
64+
// CHECK_NO_SIZE_NO_ALIGN: _ZdlPv(
5365
// CHECK: [[S1LPAD]]:{{.*}};
54-
// CHECK: @_ZdlPvm({{.*}}[[ALLOC_RESULT]], {{.*}})
66+
// CHECK_SIZED_ALIGNED: @_ZdlPvm({{.*}}[[ALLOC_RESULT]], {{.*}})
67+
// CHECK_SIZED_NO_ALIGN: @_ZdlPvm({{.*}}[[ALLOC_RESULT]], {{.*}})
68+
// CHECK_NO_SIZE_ALIGNED: @_ZdlPv({{.*}}[[ALLOC_RESULT]])
69+
// CHECK_NO_SIZE_NO_ALIGN: @_ZdlPv({{.*}}[[ALLOC_RESULT]])
5570
// CHECK: [[S2LPAD]]:
56-
// CHECK: _ZdlPvSt11align_val_t({{.*}}[[ALIGNED_ALLOC_RESULT]], {{.*}})
71+
// CHECK_SIZED_ALIGNED: _ZdlPvSt11align_val_t({{.*}}[[ALIGNED_ALLOC_RESULT]], {{.*}})
72+
// CHECK_NO_SIZE_ALIGNED: _ZdlPvSt11align_val_t({{.*}}[[ALIGNED_ALLOC_RESULT]], {{.*}})
73+
// CHECK_SIZED_NO_ALIGN: _ZdlPvm({{.*}}[[ALIGNED_ALLOC_RESULT]], {{.*}})
74+
// CHECK_NO_SIZE_NO_ALIGN: _ZdlPv({{.*}}[[ALIGNED_ALLOC_RESULT]])
5775

5876
template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t);
5977
template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t);
@@ -179,8 +197,8 @@ extern "C" void test_ensure_type_aware_resolution_includes_location() {
179197
}
180198

181199
// CHECK-LABEL: test_ensure_type_aware_resolution_includes_location
182-
// `177` in the next line is the line number from the test line in above
183-
// CHECK: %call = call noundef ptr @_ZN3S12nwIS_EEPvSt13type_identityIT_EmSt11align_val_tj({{.*}}, {{.*}}, {{.*}}, {{.*}} 177)
200+
// `180` in the next line is the line number from the test line in above
201+
// CHECK: %call = call noundef ptr @_ZN3S12nwIS_EEPvSt13type_identityIT_EmSt11align_val_tj({{.*}}, {{.*}}, {{.*}}, {{.*}})
184202

185203
// CHECK-LABEL: @_ZN2S8D0Ev
186204
// CHECK: @_ZN2S8dlEPv(

clang/test/CodeGenCXX/type-aware-new-constexpr.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
1+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
2+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
3+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -fno-aligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
4+
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -fno-aligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - | FileCheck %s
5+
26
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -faligned-allocation -fexperimental-cxx-type-aware-allocators -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fexperimental-new-constant-interpreter -o - | FileCheck %s
37

48
using size_t = __SIZE_TYPE__;

clang/test/SemaCXX/type-aware-new-delete-arrays.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -Wall -Wpedantic
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fsized-deallocation -faligned-allocation -Wall -Wpedantic
2+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -faligned-allocation -Wall -Wpedantic
3+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -fno-aligned-allocation -Wall -Wpedantic
4+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fsized-deallocation -fno-aligned-allocation -Wall -Wpedantic
25

36
namespace std {
47
template <class T> struct type_identity {};

clang/test/SemaCXX/type-aware-new-delete-basic-free-declarations.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators
1+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fsized-deallocation -faligned-allocation
2+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fno-sized-deallocation -faligned-allocation
3+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fno-sized-deallocation -fno-aligned-allocation
4+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fsized-deallocation -fno-aligned-allocation
25
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -DNO_TAA -std=c++23 -fno-experimental-cxx-type-aware-allocators
36

47
namespace std {

clang/test/SemaCXX/type-aware-new-delete-basic-resolution.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions
1+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fsized-deallocation -faligned-allocation
2+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -faligned-allocation
3+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fsized-deallocation -fno-aligned-allocation
4+
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fno-sized-deallocation -fno-aligned-allocation
25
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -DTADD -std=c++23 -fexperimental-cxx-type-aware-allocators -fexperimental-cxx-type-aware-destroying-delete -fexceptions
36

47
namespace std {
@@ -14,6 +17,12 @@ static_assert(__has_feature(cxx_type_aware_destroying_delete));
1417
static_assert(!__has_feature(cxx_type_aware_destroying_delete));
1518
#endif
1619

20+
#if defined(__cpp_aligned_new)
21+
#define ALLOCATION_ALIGNMENT , std::align_val_t
22+
#else
23+
#define ALLOCATION_ALIGNMENT
24+
#endif
25+
1726
using size_t = __SIZE_TYPE__;
1827

1928
void *operator new(size_t);
@@ -36,8 +45,8 @@ void *operator new(std::type_identity<UntypedInclassNewOveraligned_NoAlignedAllo
3645
void operator delete(std::type_identity<UntypedInclassNewOveraligned_NoAlignedAlloc>, void *, size_t, std::align_val_t); // #8
3746

3847
struct __attribute__((aligned(128))) UntypedInclassNewOveraligned_AlignedAlloc {
39-
void *operator new(size_t, std::align_val_t) = delete; // #9
40-
void operator delete(void *, std::align_val_t) = delete; // #10
48+
void *operator new(size_t ALLOCATION_ALIGNMENT) = delete; // #9
49+
void operator delete(void * ALLOCATION_ALIGNMENT) = delete; // #10
4150
};
4251
void *operator new(std::type_identity<UntypedInclassNewOveraligned_AlignedAlloc>, size_t, std::align_val_t); // #11
4352
void operator delete(std::type_identity<UntypedInclassNewOveraligned_AlignedAlloc>, void *, size_t, std::align_val_t); // #12
@@ -327,13 +336,11 @@ void test() {
327336
// expected-error@-1 {{attempt to use a deleted function}}
328337
// expected-note@#33 {{'operator delete' has been explicitly marked deleted here}}
329338

330-
// Are these reasonable? Should we ensure that declaration of new vs delete have consistent type
331-
// semantics? How do we define consistent?
332339
// Constructor clean up invokes untyped delete if untyped delete was used
333340
InclassNew6 *O10 = new InclassNew6;
334341
// expected-error@-1 {{attempt to use a deleted function}}
335342
// expected-note@#36 {{'operator delete' has been explicitly marked deleted here}}
336-
// expected-error@-3 {{mismatched type aware allocation operators for constructor cleanup}}
343+
// expected-error@-3 {{type aware allocation requires matching type aware operator new and type aware operator delete for exception cleanup}}
337344
// expected-note@#34 {{non-type aware 'operator new' declared here}}
338345
// expected-note@#36 {{type aware 'operator delete' declared here}}
339346
delete O10;
@@ -347,13 +354,13 @@ void test() {
347354
// expected-note@#39 {{'operator delete' has been explicitly marked deleted here}}
348355

349356
InclassNew8 *O12 = new InclassNew8;
350-
// expected-error@-1 {{mismatched type aware allocation operators for constructor cleanup}}
357+
// expected-error@-1 {{type aware allocation requires matching type aware operator new and type aware operator delete for exception cleanup}}
351358
// expected-note@#40 {{type aware 'operator new' declared here}}
352359
// expected-note@#41 {{non-type aware 'operator delete' declared here}}
353360
delete O12;
354361

355362
InclassNew9 *O13 = new InclassNew9;
356-
// expected-error@-1 {{type aware 'operator new' requires matching cleanup 'operator delete' in 'InclassNew9'}}
363+
// expected-error@-1 {{type aware 'operator new' requires there to be a corresponding cleanup 'operator delete' in 'InclassNew9'}}
357364

358365
delete O13;
359366

@@ -403,13 +410,13 @@ void test() {
403410
// expected-note@#59 {{member 'operator delete' declared here}}
404411

405412
SubClass6_1 *O22 = new SubClass6_1;
406-
// expected-error@-1 {{type aware 'operator new<SubClass6_1>' requires matching 'operator delete' in 'SubClass6_1'}}
413+
// expected-error@-1 {{type aware 'operator new<SubClass6_1>' requires there to be a corresponding 'operator delete' in 'SubClass6_1'}}
407414
// expected-note@#62 {{type aware 'operator new<SubClass6_1>' found in 'SubClass6_1'}}
408415
// expected-note@#61 {{type aware 'operator delete<SubClass6_1>' found in 'BaseClass6'}}
409416
delete O22;
410417

411418
SubClass6_2 *O23 = new SubClass6_2;
412-
// expected-error@-1 {{type aware 'operator new<SubClass6_2>' requires matching 'operator delete' in 'BaseClass6'}}
419+
// expected-error@-1 {{type aware 'operator new<SubClass6_2>' requires there to be a corresponding 'operator delete' in 'BaseClass6'}}
413420
// expected-note@#60 {{type aware 'operator new<SubClass6_2>' found in 'BaseClass6'}}
414421
// expected-note@#63 {{type aware 'operator delete<SubClass6_2>' found in 'SubClass6_2'}}
415422
delete O23;

clang/test/SemaCXX/type-aware-new-delete-qualifiers.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNO_TADD -std=c++23 -fexperimental-cxx-type-aware-allocators
2-
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNO_TADD -std=c++23 -fexperimental-cxx-type-aware-allocators -fsized-deallocation -faligned-allocation
2+
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNO_TADD -std=c++23 -fexperimental-cxx-type-aware-allocators -fno-sized-deallocation -faligned-allocation
3+
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNO_TADD -std=c++23 -fexperimental-cxx-type-aware-allocators -fno-sized-deallocation -fno-aligned-allocation
4+
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNO_TADD -std=c++23 -fexperimental-cxx-type-aware-allocators -fsized-deallocation -fno-aligned-allocation
35
namespace std {
46
template <class T> struct type_identity {
57
typedef T type;

clang/test/SemaCXX/type-aware-placement-operators.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fcxx-exceptions
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fcxx-exceptions -fsized-deallocation -faligned-allocation
2+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fcxx-exceptions -fno-sized-deallocation -faligned-allocation
3+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fcxx-exceptions -fno-sized-deallocation -fno-aligned-allocation
4+
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++23 -fexperimental-cxx-type-aware-allocators -fexceptions -fcxx-exceptions -fsized-deallocation -fno-aligned-allocation
25

36
namespace std {
47
template <class T> struct type_identity {};

0 commit comments

Comments
 (0)