151 lines · cpp
1// RUN: %clang_cc1 -triple arm64-apple-macosx -std=c++26 -fsyntax-only -verify=expected,clangext %s2// RUN: %clang_cc1 -triple arm64-apple-macosx -std=c++26 -Wno-ext-cxx-type-aware-allocators -fsyntax-only -verify %s3 4namespace std {5 template <class T> struct type_identity {};6 enum class align_val_t : __SIZE_TYPE__ {};7 struct destroying_delete_t { explicit destroying_delete_t() = default; };8}9 10using size_t = __SIZE_TYPE__;11 12// Basic valid declarations13struct S {14 void *operator new(std::type_identity<S>, size_t, std::align_val_t); // #115 void operator delete(std::type_identity<S>, void *, size_t, std::align_val_t); // #216 // clangext-warning@#1 {{type aware allocators are a Clang extension}}17 // clangext-warning@#2 {{type aware allocators are a Clang extension}}18 void operator delete(S *, std::destroying_delete_t);19};20 21template <typename T> struct S2 {22 void *operator new(std::type_identity<S2<T>>, size_t, std::align_val_t); // #323 void operator delete(std::type_identity<S2<T>>, void *, size_t, std::align_val_t); // #424 // clangext-warning@#3 {{type aware allocators are a Clang extension}}25 // clangext-warning@#4 {{type aware allocators are a Clang extension}}26 void operator delete(S2 *, std::destroying_delete_t);27};28 29struct S3 {30 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #531 template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // #632 // clangext-warning@#5 {{type aware allocators are a Clang extension}}33 // clangext-warning@#6 {{type aware allocators are a Clang extension}}34 void operator delete(S3 *, std::destroying_delete_t);35};36 37struct S4 {38 template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #739 template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // #840 template <typename T> void operator delete(std::type_identity<T>, S4 *, std::destroying_delete_t, size_t, std::align_val_t); // #941 // clangext-warning@#7 {{type aware allocators are a Clang extension}}42 // clangext-warning@#8 {{type aware allocators are a Clang extension}}43 // expected-error@#9 {{destroying delete is not permitted to be type aware}}44};45 46struct S5 {47 template <typename T> void operator delete(std::type_identity<T>, T *, size_t, std::align_val_t); // #1048 // expected-error@#10 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}}49 // clangext-warning@#10 {{type aware allocators are a Clang extension}}50};51 52struct S6 {53 template <typename T> void *operator new(std::type_identity<S6>, T, std::align_val_t); // #1154 // expected-error@#11 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter}}55 // clangext-warning@#11 {{type aware allocators are a Clang extension}}56 template <typename T> void operator delete(std::type_identity<S6>, T, size_t, std::align_val_t); // #1257 // expected-error@#12 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}}58 // clangext-warning@#12 {{type aware allocators are a Clang extension}}59};60 61template <typename U>62struct S7 {63 template <typename T> void *operator new(std::type_identity<T>, U, std::align_val_t); // #1364 // expected-error@#13 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}}65 // clangext-warning@#13 {{type aware allocators are a Clang extension}}66 template <typename T> void operator delete(std::type_identity<T>, U, size_t, std::align_val_t); // #1467 // expected-error@#14 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}}68 // clangext-warning@#14 {{type aware allocators are a Clang extension}}69 template <typename T> void operator delete(std::type_identity<T>, S7 *, std::destroying_delete_t, U, std::align_val_t); // #1570 // expected-error@#15 {{destroying delete is not permitted to be type aware}}71 void operator delete(S7 *, std::destroying_delete_t, U); // #1672};73 74void f() {75 S7<int> s;76 // expected-note@-1 {{in instantiation of template class 'S7<int>' requested here}}77 // expected-error@#16 {{destroying operator delete can have only an optional size and optional alignment parameter}}78}79 80struct S8 {81 template <typename T, typename U> void *operator new(std::type_identity<T>, U, std::align_val_t); // #1782 // expected-error@#17 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}}83 // clangext-warning@#17 {{type aware allocators are a Clang extension}}84 template <typename T, typename U> void operator delete(std::type_identity<T>, U, size_t, std::align_val_t); // #1885 // expected-error@#18 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}}86 // clangext-warning@#18 {{type aware allocators are a Clang extension}}87 template <typename T, typename U> void operator delete(std::type_identity<T>, S8 *, std::destroying_delete_t, U, std::align_val_t); // #1988 // expected-error@#19 {{destroying delete is not permitted to be type aware}}89};90 91template <typename T> using Alias = T;92template <typename T> using TypeIdentityAlias = std::type_identity<T>;93typedef std::type_identity<double> TypedefAlias;94using UsingAlias = std::type_identity<float>;95struct S9 {96 void *operator new(Alias<size_t>, std::align_val_t);97 template <typename T> void *operator new(Alias<std::type_identity<T>>, Alias<size_t>, std::align_val_t); // #2098 // clangext-warning@#20 {{type aware allocators are a Clang extension}}99 void *operator new(Alias<std::type_identity<int>>, size_t, std::align_val_t);100 // clangext-warning@-1 {{type aware allocators are a Clang extension}}101 template <typename T> void operator delete(Alias<std::type_identity<T>>, void *, size_t, std::align_val_t); // #21102 // clangext-warning@#21{{type aware allocators are a Clang extension}}103 void operator delete(Alias<std::type_identity<int>>, void *, size_t, std::align_val_t);104 // clangext-warning@-1 {{type aware allocators are a Clang extension}}105};106struct S10 {107 template <typename T> void *operator new(TypeIdentityAlias<T>, size_t, std::align_val_t); // #22108 // clangext-warning@#22 {{type aware allocators are a Clang extension}}109 void *operator new(TypeIdentityAlias<int>, size_t, std::align_val_t);110 // clangext-warning@-1 {{type aware allocators are a Clang extension}}111 template <typename T> void operator delete(TypeIdentityAlias<T>, void *, size_t, std::align_val_t); // #23112 // clangext-warning@-1 {{type aware allocators are a Clang extension}}113 void operator delete(TypeIdentityAlias<int>, void *, size_t, std::align_val_t);114 // clangext-warning@-1 {{type aware allocators are a Clang extension}}115};116 117void test() {118 S9 *s9 = new S9;119 delete s9;120 S10 *s10 = new S10;121 delete s10;122}123 124struct S11 {125 template <typename T> void *operator new(TypedefAlias, size_t, std::align_val_t);126 // clangext-warning@-1 {{type aware allocators are a Clang extension}}127 void *operator new(TypedefAlias, size_t, std::align_val_t);128 // clangext-warning@-1 {{type aware allocators are a Clang extension}}129 template <typename T> void operator delete(TypedefAlias, void *, size_t, std::align_val_t);130 // clangext-warning@-1 {{type aware allocators are a Clang extension}}131 void operator delete(TypedefAlias, void *, size_t, std::align_val_t);132 // clangext-warning@-1 {{type aware allocators are a Clang extension}}133};134struct S12 {135 template <typename T> void *operator new(UsingAlias, size_t, std::align_val_t);136 // clangext-warning@-1 {{type aware allocators are a Clang extension}}137 void *operator new(UsingAlias, size_t, std::align_val_t);138 // clangext-warning@-1 {{type aware allocators are a Clang extension}}139 template <typename T> void operator delete(UsingAlias, void *, size_t, std::align_val_t);140 // clangext-warning@-1 {{type aware allocators are a Clang extension}}141 void operator delete(UsingAlias, void *, size_t, std::align_val_t);142 // clangext-warning@-1 {{type aware allocators are a Clang extension}}143};144 145struct S13 {146 void *operator new(std::type_identity<S13>, size_t, std::align_val_t);147 // clangext-warning@-1 {{type aware allocators are a Clang extension}}148 void operator delete(std::type_identity<S13>, void*, size_t, std::align_val_t);149 // clangext-warning@-1 {{type aware allocators are a Clang extension}}150};151