// RUN: %clang_cc1 -triple arm64-apple-macosx -std=c++26 -fsyntax-only -verify=expected,clangext %s // RUN: %clang_cc1 -triple arm64-apple-macosx -std=c++26 -Wno-ext-cxx-type-aware-allocators -fsyntax-only -verify %s namespace std { template struct type_identity {}; enum class align_val_t : __SIZE_TYPE__ {}; struct destroying_delete_t { explicit destroying_delete_t() = default; }; } using size_t = __SIZE_TYPE__; // Basic valid declarations struct S { void *operator new(std::type_identity, size_t, std::align_val_t); // #1 void operator delete(std::type_identity, void *, size_t, std::align_val_t); // #2 // clangext-warning@#1 {{type aware allocators are a Clang extension}} // clangext-warning@#2 {{type aware allocators are a Clang extension}} void operator delete(S *, std::destroying_delete_t); }; template struct S2 { void *operator new(std::type_identity>, size_t, std::align_val_t); // #3 void operator delete(std::type_identity>, void *, size_t, std::align_val_t); // #4 // clangext-warning@#3 {{type aware allocators are a Clang extension}} // clangext-warning@#4 {{type aware allocators are a Clang extension}} void operator delete(S2 *, std::destroying_delete_t); }; struct S3 { template void *operator new(std::type_identity, size_t, std::align_val_t); // #5 template void operator delete(std::type_identity, void *, size_t, std::align_val_t); // #6 // clangext-warning@#5 {{type aware allocators are a Clang extension}} // clangext-warning@#6 {{type aware allocators are a Clang extension}} void operator delete(S3 *, std::destroying_delete_t); }; struct S4 { template void *operator new(std::type_identity, size_t, std::align_val_t); // #7 template void operator delete(std::type_identity, void *, size_t, std::align_val_t); // #8 template void operator delete(std::type_identity, S4 *, std::destroying_delete_t, size_t, std::align_val_t); // #9 // clangext-warning@#7 {{type aware allocators are a Clang extension}} // clangext-warning@#8 {{type aware allocators are a Clang extension}} // expected-error@#9 {{destroying delete is not permitted to be type aware}} }; struct S5 { template void operator delete(std::type_identity, T *, size_t, std::align_val_t); // #10 // expected-error@#10 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}} // clangext-warning@#10 {{type aware allocators are a Clang extension}} }; struct S6 { template void *operator new(std::type_identity, T, std::align_val_t); // #11 // expected-error@#11 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter}} // clangext-warning@#11 {{type aware allocators are a Clang extension}} template void operator delete(std::type_identity, T, size_t, std::align_val_t); // #12 // expected-error@#12 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}} // clangext-warning@#12 {{type aware allocators are a Clang extension}} }; template struct S7 { template void *operator new(std::type_identity, U, std::align_val_t); // #13 // expected-error@#13 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}} // clangext-warning@#13 {{type aware allocators are a Clang extension}} template void operator delete(std::type_identity, U, size_t, std::align_val_t); // #14 // expected-error@#14 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}} // clangext-warning@#14 {{type aware allocators are a Clang extension}} template void operator delete(std::type_identity, S7 *, std::destroying_delete_t, U, std::align_val_t); // #15 // expected-error@#15 {{destroying delete is not permitted to be type aware}} void operator delete(S7 *, std::destroying_delete_t, U); // #16 }; void f() { S7 s; // expected-note@-1 {{in instantiation of template class 'S7' requested here}} // expected-error@#16 {{destroying operator delete can have only an optional size and optional alignment parameter}} } struct S8 { template void *operator new(std::type_identity, U, std::align_val_t); // #17 // expected-error@#17 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}} // clangext-warning@#17 {{type aware allocators are a Clang extension}} template void operator delete(std::type_identity, U, size_t, std::align_val_t); // #18 // expected-error@#18 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}} // clangext-warning@#18 {{type aware allocators are a Clang extension}} template void operator delete(std::type_identity, S8 *, std::destroying_delete_t, U, std::align_val_t); // #19 // expected-error@#19 {{destroying delete is not permitted to be type aware}} }; template using Alias = T; template using TypeIdentityAlias = std::type_identity; typedef std::type_identity TypedefAlias; using UsingAlias = std::type_identity; struct S9 { void *operator new(Alias, std::align_val_t); template void *operator new(Alias>, Alias, std::align_val_t); // #20 // clangext-warning@#20 {{type aware allocators are a Clang extension}} void *operator new(Alias>, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} template void operator delete(Alias>, void *, size_t, std::align_val_t); // #21 // clangext-warning@#21{{type aware allocators are a Clang extension}} void operator delete(Alias>, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} }; struct S10 { template void *operator new(TypeIdentityAlias, size_t, std::align_val_t); // #22 // clangext-warning@#22 {{type aware allocators are a Clang extension}} void *operator new(TypeIdentityAlias, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} template void operator delete(TypeIdentityAlias, void *, size_t, std::align_val_t); // #23 // clangext-warning@-1 {{type aware allocators are a Clang extension}} void operator delete(TypeIdentityAlias, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} }; void test() { S9 *s9 = new S9; delete s9; S10 *s10 = new S10; delete s10; } struct S11 { template void *operator new(TypedefAlias, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} void *operator new(TypedefAlias, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} template void operator delete(TypedefAlias, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} void operator delete(TypedefAlias, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} }; struct S12 { template void *operator new(UsingAlias, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} void *operator new(UsingAlias, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} template void operator delete(UsingAlias, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} void operator delete(UsingAlias, void *, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} }; struct S13 { void *operator new(std::type_identity, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} void operator delete(std::type_identity, void*, size_t, std::align_val_t); // clangext-warning@-1 {{type aware allocators are a Clang extension}} };