[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / cxx2a-destroying-delete.cpp
blob349e6e9538a4cfef1393d1cdde302caca5fed6fd
1 // RUN: %clang_cc1 -std=c++2a -fexceptions -verify %s
2 // RUN: %clang_cc1 -std=c++2a -verify %s
4 namespace std {
5 using size_t = decltype(sizeof(0));
6 enum class align_val_t : size_t;
8 struct destroying_delete_t {
9 struct __construct { explicit __construct() = default; };
10 explicit destroying_delete_t(__construct) {}
13 inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
16 void operator delete(void*, std::destroying_delete_t); // ok, just a placement delete
18 struct A;
19 void operator delete(A*, std::destroying_delete_t); // expected-error {{first parameter of 'operator delete' must have type 'void *'}}
21 struct A {
22 void operator delete(A*, std::destroying_delete_t);
23 void operator delete(A*, std::destroying_delete_t, std::size_t);
24 void operator delete(A*, std::destroying_delete_t, std::align_val_t);
25 void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t);
26 void operator delete(A*, std::destroying_delete_t, int); // expected-error {{destroying operator delete can have only an optional size and optional alignment parameter}}
27 // FIXME: It's probably a language defect that we permit usual operator delete to be variadic.
28 void operator delete(A*, std::destroying_delete_t, std::size_t, ...);
30 void operator delete(struct X*, std::destroying_delete_t, std::size_t, ...); // expected-error {{first parameter of 'operator delete' must have type 'A *'}}
32 void operator delete(void*, std::size_t);
35 void delete_A(A *a) { delete a; }
37 namespace convert_param {
38 struct A {
39 void operator delete(
40 A*,
41 std::destroying_delete_t);
43 struct B : private A { using A::operator delete; }; // expected-note 2{{declared private here}}
44 struct C : B {};
45 void delete_C(C *c) { delete c; } // expected-error {{cannot cast 'C' to its private base class 'A'}}
47 // expected-error@-7 {{cannot cast 'convert_param::D' to its private base class 'A'}}
48 struct D : B { virtual ~D() {} }; // expected-note {{while checking implicit 'delete this' for virtual destructor}}
51 namespace delete_selection {
52 struct B {
53 void operator delete(void*) = delete;
54 void operator delete(B *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
56 void delete_B(B *b) { delete b; } // expected-error {{deleted}}
58 struct C {
59 C();
60 void *operator new(std::size_t);
61 void operator delete(void*) = delete; // expected-note 0-1 {{deleted here}}
62 void operator delete(C *, std::destroying_delete_t) = delete;
64 // TODO: We only diagnose the use of a deleted operator delete when exceptions
65 // are enabled. Otherwise we don't bother doing the lookup.
66 #ifdef __EXCEPTIONS
67 // expected-error@+2 {{attempt to use a deleted function}}
68 #endif
69 C *new_C() { return new C; }
71 struct D {
72 void operator delete(D *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
73 void operator delete(D *, std::destroying_delete_t, std::align_val_t) = delete;
75 void delete_D(D *d) { delete d; } // expected-error {{deleted}}
77 struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) E {
78 void operator delete(E *, std::destroying_delete_t) = delete;
79 void operator delete(E *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
81 void delete_E(E *e) { delete e; } // expected-error {{deleted}}
83 struct F {
84 void operator delete(F *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
85 void operator delete(F *, std::destroying_delete_t, std::size_t) = delete;
87 void delete_F(F *f) { delete f; } // expected-error {{deleted}}
89 struct G {
90 void operator delete(G *, std::destroying_delete_t, std::align_val_t) = delete;
91 void operator delete(G *, std::destroying_delete_t, std::size_t) = delete; // expected-note {{deleted}}
93 void delete_G(G *g) { delete g; } // expected-error {{deleted}}
95 struct H {
96 void operator delete(H *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
97 void operator delete(H *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
99 void delete_H(H *h) { delete h; } // expected-error {{deleted}}
101 struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) I {
102 void operator delete(I *, std::destroying_delete_t, std::size_t) = delete;
103 void operator delete(I *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; // expected-note {{deleted}}
105 void delete_I(I *i) { delete i; } // expected-error {{deleted}}
108 namespace first_param_conversion {
109 struct A {
110 void operator delete(A *, std::destroying_delete_t);
112 void f(const volatile A *a) {
113 delete a; // ok
116 struct B {
117 void operator delete(B *, std::destroying_delete_t);
119 struct C : B {};
120 struct D : B {};
121 struct E : C, D {};
122 void g(E *e) {
123 delete e; // expected-error {{ambiguous conversion from derived class 'E' to base class 'B':}}
127 namespace templated {
128 template<typename T> using id_alias = T;
129 template<typename T> struct id_struct { using type = T; };
131 template<typename T> struct A {
132 void operator delete(A *, std::destroying_delete_t);
134 template<typename T> struct B {
135 void operator delete(B<T> *, std::destroying_delete_t);
137 template<typename T> struct C {
138 void operator delete(id_alias<C> *, std::destroying_delete_t);
140 template<typename T> struct D {
141 void operator delete(typename id_struct<D>::type *, std::destroying_delete_t); // expected-error {{use 'D<T> *'}}
145 namespace dtor_access {
146 struct S {
147 void operator delete(S *p, std::destroying_delete_t);
148 private:
149 ~S(); // expected-note {{here}}
152 // FIXME: PR47474: GCC accepts this, and it seems somewhat reasonable to
153 // allow, even though [expr.delete]p12 says this is ill-formed.
154 void f() { delete new S; } // expected-error {{calling a private destructor}}
156 struct T {
157 void operator delete(T *, std::destroying_delete_t);
158 protected:
159 virtual ~T(); // expected-note {{here}}
162 struct U : T {
163 void operator delete(void *);
164 private:
165 ~U() override;
168 void g() { delete (T *)new U; } // expected-error {{calling a protected destructor}}
171 namespace delete_from_new {
172 struct A {
173 A(); // might throw
174 void operator delete(A *, std::destroying_delete_t) = delete;
176 struct B {
177 B(); // might throw
178 void operator delete(void *) = delete; // #member-delete-from-new
179 void operator delete(B *, std::destroying_delete_t) = delete;
181 void f() {
182 new A; // calls ::operator delete
183 new B; // calls B::operator delete
184 #ifdef __EXCEPTIONS
185 // expected-error@-2 {{attempt to use a deleted function}}
186 // expected-note@#member-delete-from-new {{deleted here}}
187 #endif