1 // RUN: %clang_cc1 -std=c++2a -fexceptions -verify %s
2 // RUN: %clang_cc1 -std=c++2a -verify %s
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
19 void operator delete(A
*, std::destroying_delete_t
); // expected-error {{first parameter of 'operator delete' must have type 'void *'}}
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
{
41 std::destroying_delete_t
);
43 struct B
: private A
{ using A::operator delete; }; // expected-note 2{{declared private here}}
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
{
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}}
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.
67 // expected-error@+2 {{attempt to use a deleted function}}
69 C
*new_C() { return new C
; }
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}}
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}}
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}}
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
{
110 void operator delete(A
*, std::destroying_delete_t
);
112 void f(const volatile A
*a
) {
117 void operator delete(B
*, std::destroying_delete_t
);
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
{
147 void operator delete(S
*p
, std::destroying_delete_t
);
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}}
157 void operator delete(T
*, std::destroying_delete_t
);
159 virtual ~T(); // expected-note {{here}}
163 void operator delete(void *);
168 void g() { delete (T
*)new U
; } // expected-error {{calling a protected destructor}}
171 namespace delete_from_new
{
174 void operator delete(A
*, std::destroying_delete_t
) = delete;
178 void operator delete(void *) = delete; // #member-delete-from-new
179 void operator delete(B
*, std::destroying_delete_t
) = delete;
182 new A
; // calls ::operator delete
183 new B
; // calls B::operator delete
185 // expected-error@-2 {{attempt to use a deleted function}}
186 // expected-note@#member-delete-from-new {{deleted here}}