blob: a085c11c26f57a0bf25fb509a36ed73317fa650d [file] [log] [blame]
Richard Smith5b349582017-10-13 01:55:36 +00001// RUN: %clang_cc1 -std=c++2a -verify %s
2
3namespace std {
4 using size_t = decltype(sizeof(0));
5 enum class align_val_t : size_t;
6
7 struct destroying_delete_t {
8 struct __construct { explicit __construct() = default; };
9 explicit destroying_delete_t(__construct) {}
10 };
11
12 inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
13}
14
15void operator delete(void*, std::destroying_delete_t); // ok, just a placement delete
16
17struct A;
18void operator delete(A*, std::destroying_delete_t); // expected-error {{first parameter of 'operator delete' must have type 'void *'}}
19
20struct A {
21 void operator delete(A*, std::destroying_delete_t);
22 void operator delete(A*, std::destroying_delete_t, std::size_t);
23 void operator delete(A*, std::destroying_delete_t, std::align_val_t);
24 void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t);
25 void operator delete(A*, std::destroying_delete_t, int); // expected-error {{destroying operator delete can have only an optional size and optional alignment parameter}}
26 // FIXME: It's probably a language defect that we permit usual operator delete to be variadic.
27 void operator delete(A*, std::destroying_delete_t, std::size_t, ...);
28
29 void operator delete(struct X*, std::destroying_delete_t, std::size_t, ...); // expected-error {{first parameter of 'operator delete' must have type 'A *'}}
30
31 void operator delete(void*, std::size_t);
32};
33
34void delete_A(A *a) { delete a; }
35
36namespace convert_param {
37 struct A {
38 void operator delete(
39 A*,
40 std::destroying_delete_t);
41 };
42 struct B : private A { using A::operator delete; }; // expected-note 2{{declared private here}}
43 struct C : B {};
44 void delete_C(C *c) { delete c; } // expected-error {{cannot cast 'convert_param::C' to its private base class 'convert_param::A'}}
45
46 // expected-error@-7 {{cannot cast 'convert_param::D' to its private base class 'convert_param::A'}}
47 struct D : B { virtual ~D() {} }; // expected-note {{while checking implicit 'delete this' for virtual destructor}}
48}
49
50namespace delete_selection {
51 struct B {
52 void operator delete(void*) = delete;
53 void operator delete(B *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
54 };
55 void delete_B(B *b) { delete b; } // expected-error {{deleted}}
56
57 struct C {
58 C();
59 void *operator new(std::size_t);
60 void operator delete(void*) = delete;
61 void operator delete(C *, std::destroying_delete_t) = delete;
62 };
63 // FIXME: This should be ill-formed, but we incorrectly decide that overload
64 // resolution failed (because it selected a deleted function) and thus no
65 // 'operator delete' should be called.
66 C *new_C() { return new C; }
67
68 struct D {
69 void operator delete(D *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
70 void operator delete(D *, std::destroying_delete_t, std::align_val_t) = delete;
71 };
72 void delete_D(D *d) { delete d; } // expected-error {{deleted}}
73
74 struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) E {
75 void operator delete(E *, std::destroying_delete_t) = delete;
76 void operator delete(E *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
77 };
78 void delete_E(E *e) { delete e; } // expected-error {{deleted}}
79
80 struct F {
81 void operator delete(F *, std::destroying_delete_t) = delete; // expected-note {{deleted}}
82 void operator delete(F *, std::destroying_delete_t, std::size_t) = delete;
83 };
84 void delete_F(F *f) { delete f; } // expected-error {{deleted}}
85
86 struct G {
87 void operator delete(G *, std::destroying_delete_t, std::align_val_t) = delete;
88 void operator delete(G *, std::destroying_delete_t, std::size_t) = delete; // expected-note {{deleted}}
89 };
90 void delete_G(G *g) { delete g; } // expected-error {{deleted}}
91
92 struct H {
93 void operator delete(H *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}
94 void operator delete(H *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
95 };
96 void delete_H(H *h) { delete h; } // expected-error {{deleted}}
97
98 struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) I {
99 void operator delete(I *, std::destroying_delete_t, std::size_t) = delete;
100 void operator delete(I *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; // expected-note {{deleted}}
101 };
102 void delete_I(I *i) { delete i; } // expected-error {{deleted}}
103}