124a2a48bSEric Fiselier // RUN: %clang_cc1 -fexceptions -std=c++2a -fsized-deallocation -fno-aligned-allocation -verify %s
224a2a48bSEric Fiselier // RUN: %clang_cc1 -fexceptions -std=c++17 -fsized-deallocation -fno-aligned-allocation -verify %s
324a2a48bSEric Fiselier // RUN: %clang_cc1 -fexceptions -std=c++14 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
424a2a48bSEric Fiselier // RUN: %clang_cc1 -fexceptions -std=c++11 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
524a2a48bSEric Fiselier
624a2a48bSEric Fiselier // Test that we handle aligned deallocation, sized deallocation, and destroying
724a2a48bSEric Fiselier // delete as usual deallocation functions even if they are used as extensions
824a2a48bSEric Fiselier // prior to C++17.
924a2a48bSEric Fiselier
1024a2a48bSEric Fiselier namespace std {
1124a2a48bSEric Fiselier using size_t = decltype(sizeof(0));
1224a2a48bSEric Fiselier enum class align_val_t : size_t;
1324a2a48bSEric Fiselier
1424a2a48bSEric Fiselier struct destroying_delete_t {
1524a2a48bSEric Fiselier struct __construct { explicit __construct() = default; };
destroying_delete_tstd::destroying_delete_t1624a2a48bSEric Fiselier explicit destroying_delete_t(__construct) {}
1724a2a48bSEric Fiselier };
1824a2a48bSEric Fiselier
1924a2a48bSEric Fiselier inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
2024a2a48bSEric Fiselier }
2124a2a48bSEric Fiselier
2224a2a48bSEric Fiselier // FIXME: Should destroying delete really be on in all dialects by default?
2324a2a48bSEric Fiselier struct A {
2424a2a48bSEric Fiselier void operator delete(void*) = delete;
2524a2a48bSEric Fiselier void operator delete(A*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
2624a2a48bSEric Fiselier };
ATest(A * a)2724a2a48bSEric Fiselier void ATest(A* a) { delete a; } // expected-error {{deleted}}
2824a2a48bSEric Fiselier
2924a2a48bSEric Fiselier struct B {
3024a2a48bSEric Fiselier void operator delete(void*) = delete; // expected-note {{deleted}}
3124a2a48bSEric Fiselier void operator delete(void*, std::size_t) = delete;
3224a2a48bSEric Fiselier };
BTest(B * b)3324a2a48bSEric Fiselier void BTest(B *b) { delete b; }// expected-error {{deleted}}
3424a2a48bSEric Fiselier
3524a2a48bSEric Fiselier
36*365e164fSEric Fiselier struct alignas(128) C {
3724a2a48bSEric Fiselier #ifndef HAS_ALIGN
3824a2a48bSEric Fiselier // expected-note@+2 {{deleted}}
3924a2a48bSEric Fiselier #endif
4024a2a48bSEric Fiselier void operator delete(void*) = delete;
4124a2a48bSEric Fiselier #ifdef HAS_ALIGN
4224a2a48bSEric Fiselier // expected-note@+2 {{deleted}}
4324a2a48bSEric Fiselier #endif
4424a2a48bSEric Fiselier void operator delete(void*, std::align_val_t) = delete;
4524a2a48bSEric Fiselier };
CTest(C * c)4624a2a48bSEric Fiselier void CTest(C *c) { delete c; } // expected-error {{deleted}}
4724a2a48bSEric Fiselier
4824a2a48bSEric Fiselier struct D {
4924a2a48bSEric Fiselier void operator delete(void*) = delete;
5024a2a48bSEric Fiselier void operator delete(D*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
5124a2a48bSEric Fiselier void operator delete(D*, std::destroying_delete_t, std::size_t) = delete;
5224a2a48bSEric Fiselier void operator delete(D*, std::destroying_delete_t, std::align_val_t) = delete;
5324a2a48bSEric Fiselier void operator delete(D*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
5424a2a48bSEric Fiselier };
DTest(D * d)5524a2a48bSEric Fiselier void DTest(D *d) { delete d; } // expected-error {{deleted}}
5624a2a48bSEric Fiselier
57*365e164fSEric Fiselier struct alignas(128) E {
5824a2a48bSEric Fiselier void operator delete(void*) = delete;
5924a2a48bSEric Fiselier void operator delete(E*, std::destroying_delete_t) = delete;
6024a2a48bSEric Fiselier void operator delete(E*, std::destroying_delete_t, std::size_t) = delete;
6124a2a48bSEric Fiselier void operator delete(E*, std::destroying_delete_t, std::align_val_t) = delete;
6224a2a48bSEric Fiselier void operator delete(E*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
6324a2a48bSEric Fiselier #ifdef HAS_ALIGN
6424a2a48bSEric Fiselier // expected-note@-3 {{deleted}}
6524a2a48bSEric Fiselier #else
6624a2a48bSEric Fiselier // expected-note@-7 {{deleted}}
6724a2a48bSEric Fiselier #endif
6824a2a48bSEric Fiselier };
ETest(E * e)6924a2a48bSEric Fiselier void ETest(E *e) { delete e; } // expected-error {{deleted}}
70