// RUN: %clang_cc1 -fsyntax-only -Wno-ext-cxx-type-aware-allocators -verify %s -DNO_TADD -std=c++26 -fsized-deallocation -faligned-allocation // RUN: %clang_cc1 -fsyntax-only -Wno-ext-cxx-type-aware-allocators -verify %s -DNO_TADD -std=c++26 -fno-sized-deallocation -faligned-allocation // RUN: %clang_cc1 -fsyntax-only -Wno-ext-cxx-type-aware-allocators -verify %s -DNO_TADD -std=c++26 -fno-sized-deallocation -fno-aligned-allocation // RUN: %clang_cc1 -fsyntax-only -Wno-ext-cxx-type-aware-allocators -verify %s -DNO_TADD -std=c++26 -fsized-deallocation -fno-aligned-allocation namespace std { template struct type_identity { typedef T type; }; enum class align_val_t : __SIZE_TYPE__ {}; struct destroying_delete_t { explicit destroying_delete_t() = default; }; } using size_t = __SIZE_TYPE__; template struct is_const { static const bool value = false; }; template struct is_const { static const bool value = true; }; template struct is_volatile { static const bool value = false; }; template struct is_volatile { static const bool value = true; }; template static const bool is_const_v = is_const::value; template static const bool is_volatile_v = is_volatile::value; struct VerifyQualifiers { template void *operator new(std::type_identity, size_t, std::align_val_t) throw() { static_assert(is_const_v == false); // #1 static_assert(is_volatile_v == false); // #2 return 0; } template void operator delete(std::type_identity, void*, size_t, std::align_val_t) { static_assert(is_const_v == false); // #3 static_assert(is_volatile_v == false); // #4 } template void *operator new(std::type_identity<_Atomic T>, size_t, std::align_val_t) throw() { static_assert(is_const_v == false); static_assert(is_volatile_v == false); } }; void *operator new(std::type_identity type, size_t, std::align_val_t) throw() { // #11 static_assert(is_const_v == false); // #5 static_assert(is_volatile_v == false); // #6 return 0; } void operator delete(std::type_identity type, void*, size_t, std::align_val_t) { static_assert(is_const_v == false); // #7 static_assert(is_volatile_v == false); // #8 } void *operator new(std::type_identity, size_t, std::align_val_t) throw() = delete; // #12 void operator delete(std::type_identity, void*, size_t, std::align_val_t) = delete; struct TestAtomic1 { }; struct TestAtomic2 { }; void *operator new(std::type_identity, size_t, std::align_val_t) throw() = delete; // #13 void operator delete(std::type_identity<_Atomic TestAtomic1>, void*, size_t, std::align_val_t) = delete; // #9 void *operator new(std::type_identity<_Atomic TestAtomic2>, size_t, std::align_val_t) = delete; // #10 void operator delete(std::type_identity, void*, size_t, std::align_val_t) = delete; // Success tests void test_member_allocators() { auto *unqualified_obj = new VerifyQualifiers(); delete unqualified_obj; auto *const_obj = new const VerifyQualifiers(); delete const_obj; auto *volatile_obj = new volatile VerifyQualifiers(); delete volatile_obj; auto *const_volatile_obj = new const volatile VerifyQualifiers(); delete const_volatile_obj; auto *atomic_obj = new _Atomic VerifyQualifiers(); delete atomic_obj; auto *atomic_test1 = new _Atomic TestAtomic1; delete atomic_test1; // expected-error@-1 {{attempt to use a deleted function}} // expected-note@#9 {{'operator delete' has been explicitly marked deleted here}} auto *atomic_test2 = new _Atomic TestAtomic2; // expected-error@-1 {{call to deleted function 'operator new'}} // expected-note@#10 {{candidate function has been explicitly deleted}} // expected-note@#11 {{candidate function not viable}} // expected-note@#12 {{candidate function not viable}} // expected-note@#13 {{candidate function not viable}} delete atomic_test2; } void test_global_allocators() { auto *unqualified_obj = ::new VerifyQualifiers(); ::delete unqualified_obj; auto *const_obj = ::new const VerifyQualifiers(); ::delete const_obj; auto *volatile_obj = ::new volatile VerifyQualifiers(); ::delete volatile_obj; auto *const_volatile_obj = ::new const volatile VerifyQualifiers(); ::delete const_volatile_obj; _Atomic VerifyQualifiers *atomic_obj = ::new _Atomic VerifyQualifiers(); ::delete atomic_obj; _Atomic int *atomic_int = new _Atomic int; delete atomic_int; }