blob: 60cb0ef09089bcd2c40bf998aa3ce2a0cbfae70b [file] [log] [blame]
Hans Wennborgc9bd88e2014-01-14 19:35:09 +00001// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
2// RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
Douglas Gregor831c93f2008-11-05 20:51:48 +00003class A {
4public:
5 ~A();
6};
7
8class B {
9public:
10 ~B() { }
11};
12
13class C {
14public:
15 (~C)() { }
16};
17
18struct D {
19 static void ~D(int, ...) const { } // \
Richard Smith63168c72012-02-10 11:05:11 +000020 // expected-error{{static member function cannot have 'const' qualifier}} \
Douglas Gregor831c93f2008-11-05 20:51:48 +000021 // expected-error{{destructor cannot be declared 'static'}} \
Douglas Gregor831c93f2008-11-05 20:51:48 +000022 // expected-error{{destructor cannot have any parameters}} \
Douglas Gregor95755162010-07-01 05:10:53 +000023 // expected-error{{destructor cannot be variadic}} \
24 // expected-error{{destructor cannot have a return type}} \
25 // expected-error{{'const' qualifier is not allowed on a destructor}}
Douglas Gregor831c93f2008-11-05 20:51:48 +000026};
27
Chris Lattner38378bf2009-04-25 08:28:21 +000028struct D2 {
29 void ~D2() { } // \
30 // expected-error{{destructor cannot have a return type}}
31};
32
Chris Lattnerf6d1c9c2009-04-25 08:06:05 +000033
Douglas Gregor831c93f2008-11-05 20:51:48 +000034struct E;
35
36typedef E E_typedef;
37struct E {
John McCall85f90552010-03-10 11:27:22 +000038 ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
Douglas Gregor831c93f2008-11-05 20:51:48 +000039};
40
41struct F {
Chris Lattner0369c572008-11-23 23:12:31 +000042 (~F)(); // expected-note {{previous declaration is here}}
43 ~F(); // expected-error {{destructor cannot be redeclared}}
Douglas Gregor831c93f2008-11-05 20:51:48 +000044};
45
Douglas Gregorfe17d252010-02-16 19:09:40 +000046~; // expected-error {{expected a class name after '~' to name a destructor}}
Fariborz Jahanianc0656de2009-07-20 22:41:12 +000047~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
Douglas Gregorfe17d252010-02-16 19:09:40 +000048~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}}
Argyrios Kyrtzidise4426352008-11-07 22:02:30 +000049~F(){} // expected-error {{destructor must be a non-static member function}}
Douglas Gregor4287b372008-12-12 08:25:50 +000050
51struct G {
52 ~G();
53};
54
55G::~G() { }
56
Anders Carlsson5e965472009-04-30 23:18:11 +000057// <rdar://problem/6841210>
58struct H {
59 ~H(void) { }
60};
Fariborz Jahanianb154eca2009-07-21 15:28:50 +000061
62struct X {};
63
64struct Y {
65 ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
66};
Douglas Gregor422f1552010-02-25 18:11:54 +000067
68namespace PR6421 {
69 class T; // expected-note{{forward declaration}}
70
Douglas Gregor29d907d2010-09-17 22:25:06 +000071 class QGenericArgument // expected-note{{declared here}}
Douglas Gregor422f1552010-02-25 18:11:54 +000072 {
73 template<typename U>
74 void foo(T t) // expected-error{{variable has incomplete type}}
75 { }
76
77 void disconnect()
78 {
79 T* t;
Douglas Gregor29d907d2010-09-17 22:25:06 +000080 bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
81 // expected-error{{does not refer to a value}}
Douglas Gregor422f1552010-02-25 18:11:54 +000082 }
83 };
84}
Douglas Gregorf956b352010-03-26 06:57:13 +000085
86namespace PR6709 {
Hans Wennborg9125b082014-01-13 19:48:13 +000087#ifdef MSABI
88 // This bug, "Clang instantiates destructor for function argument" is intended
89 // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
90 // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
91 // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
92#endif
Douglas Gregorf956b352010-03-26 06:57:13 +000093 template<class T> class X { T v; ~X() { ++*v; } };
94 void a(X<int> x) {}
95}
Douglas Gregor95755162010-07-01 05:10:53 +000096
97struct X0 { virtual ~X0() throw(); };
98struct X1 : public X0 { };
John McCall1e5d75d2010-07-03 18:33:00 +000099
100// Make sure we instantiate operator deletes when building a virtual
101// destructor.
102namespace test6 {
103 template <class T> class A {
104 public:
Benjamin Kramerba62bda2010-07-03 20:33:13 +0000105 void *operator new(__SIZE_TYPE__);
John McCall1e5d75d2010-07-03 18:33:00 +0000106 void operator delete(void *p) {
107 T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
108 }
109
Hans Wennborg9125b082014-01-13 19:48:13 +0000110#ifdef MSABI
111 // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
112#endif
Nick Lewyckyef4f4562010-11-25 00:35:20 +0000113 virtual ~A() {}
John McCall1e5d75d2010-07-03 18:33:00 +0000114 };
115
Hans Wennborg9125b082014-01-13 19:48:13 +0000116#ifndef MSABI
117 // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
118#endif
119 class B : A<int> { B(); };
Nick Lewyckyef4f4562010-11-25 00:35:20 +0000120 B::B() {}
John McCall1e5d75d2010-07-03 18:33:00 +0000121}
John McCall12d53da2010-08-12 00:57:17 +0000122
123// Make sure classes are marked invalid when they have invalid
124// members. This avoids a crash-on-invalid.
125namespace test7 {
126 struct A {
127 ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
128 };
129 struct B : A {};
130
131 void test() {
132 B *b;
133 b->~B();
134 }
135}
Argyrios Kyrtzidis7f3986d2011-01-31 07:05:00 +0000136
137namespace nonvirtualdtor {
138struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
139 virtual void m();
140};
141
142struct S2 {
143 ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
144 virtual void m();
145};
146
147struct S3 : public S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
148 virtual void m();
149};
150
151struct S4 : public S2 { // expected-warning {{has virtual functions but non-virtual destructor}}
152 virtual void m();
153};
154
155struct B {
156 virtual ~B();
157 virtual void m();
158};
159
160struct S5 : public B {
161 virtual void m();
162};
Argyrios Kyrtzidis33799ca2011-01-31 17:10:25 +0000163
164struct S6 {
165 virtual void m();
166private:
167 ~S6();
168};
169
170struct S7 {
171 virtual void m();
172protected:
173 ~S7();
174};
Argyrios Kyrtzidis83b797f2011-02-02 18:47:41 +0000175
Nico Weber4486d612015-02-18 05:19:40 +0000176struct S8 {} s8;
177
178UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}}
179 s8.~S8();
180}
181
Argyrios Kyrtzidis83b797f2011-02-02 18:47:41 +0000182template<class T> class TS : public B {
183 virtual void m();
184};
185
186TS<int> baz;
187
188template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
189 virtual void m();
190};
191
192TS2<int> foo; // expected-note {{instantiation}}
Argyrios Kyrtzidis7f3986d2011-01-31 07:05:00 +0000193}
Douglas Gregor0cf82f62011-02-19 19:14:36 +0000194
Argyrios Kyrtzidis8bd42852011-05-24 19:53:26 +0000195namespace dnvd { // delete-non-virtual-dtor warning
196struct NP {};
197
198struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
199 virtual void foo();
200};
201
202struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
203
David Blaikie04e2e662014-05-09 22:02:28 +0000204struct F final : B {};
Argyrios Kyrtzidis8bd42852011-05-24 19:53:26 +0000205
206struct VB {
207 virtual void foo();
208 virtual ~VB();
209};
210
211struct VD: VB {};
212
213struct VF final: VB {};
214
215template <typename T>
216class simple_ptr {
217public:
218 simple_ptr(T* t): _ptr(t) {}
219 ~simple_ptr() { delete _ptr; } // \
220 // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \
221 // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
222 T& operator*() const { return *_ptr; }
223private:
224 T* _ptr;
225};
226
227template <typename T>
228class simple_ptr2 {
229public:
230 simple_ptr2(T* t): _ptr(t) {}
231 ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
232 T& operator*() const { return *_ptr; }
233private:
234 T* _ptr;
235};
236
237void use(B&);
238void use(VB&);
239
240void nowarnstack() {
241 B b; use(b);
242 D d; use(d);
243 F f; use(f);
244 VB vb; use(vb);
245 VD vd; use(vd);
246 VF vf; use(vf);
247}
248
249void nowarnnonpoly() {
250 {
251 NP* np = new NP();
252 delete np;
253 }
254 {
255 NP* np = new NP[4];
256 delete[] np;
257 }
258}
259
260void nowarnarray() {
261 {
262 B* b = new B[4];
263 delete[] b;
264 }
265 {
266 D* d = new D[4];
267 delete[] d;
268 }
269 {
270 VB* vb = new VB[4];
271 delete[] vb;
272 }
273 {
274 VD* vd = new VD[4];
275 delete[] vd;
276 }
277}
278
279template <typename T>
280void nowarntemplate() {
281 {
282 T* t = new T();
283 delete t;
284 }
285 {
286 T* t = new T[4];
287 delete[] t;
288 }
289}
290
291void nowarn0() {
292 {
293 F* f = new F();
294 delete f;
295 }
296 {
297 VB* vb = new VB();
298 delete vb;
299 }
300 {
301 VB* vb = new VD();
302 delete vb;
303 }
304 {
305 VD* vd = new VD();
306 delete vd;
307 }
308 {
309 VF* vf = new VF();
310 delete vf;
311 }
312}
313
314void warn0() {
315 {
316 B* b = new B();
317 delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
318 }
319 {
320 B* b = new D();
321 delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
322 }
323 {
324 D* d = new D();
325 delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
326 }
327}
328
329void nowarn1() {
330 {
331 simple_ptr<F> f(new F());
332 use(*f);
333 }
334 {
335 simple_ptr<VB> vb(new VB());
336 use(*vb);
337 }
338 {
339 simple_ptr<VB> vb(new VD());
340 use(*vb);
341 }
342 {
343 simple_ptr<VD> vd(new VD());
344 use(*vd);
345 }
346 {
347 simple_ptr<VF> vf(new VF());
348 use(*vf);
349 }
350}
351
352void warn1() {
353 {
354 simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
355 use(*b);
356 }
357 {
358 simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
359 use(*b);
360 }
361 {
362 simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
363 use(*d);
364 }
365}
366}
367
Douglas Gregor0cf82f62011-02-19 19:14:36 +0000368namespace PR9238 {
369 class B { public: ~B(); };
370 class C : virtual B { public: ~C() { } };
371}
Douglas Gregor4cf85a72011-03-04 22:32:08 +0000372
373namespace PR7900 {
374 struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
375 };
376 struct B : public A {
377 };
378 void foo() {
379 B b;
380 b.~B();
381 b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
382 (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
383 }
384}
Benjamin Kramer915d1692013-10-10 09:44:41 +0000385
386namespace PR16892 {
387 auto p = &A::~A; // expected-error{{taking the address of a destructor}}
388}
David Majnemer03f705f2014-07-08 18:18:04 +0000389
390namespace PR20238 {
391struct S {
392 volatile ~S() { } // expected-error{{destructor cannot have a return type}}
393};
394}
David Majnemerced8bdf2015-02-25 17:36:15 +0000395
396namespace PR22668 {
397struct S {
398};
399void f(S s) {
400 (s.~S)();
401}
402void g(S s) {
403 (s.~S); // expected-error{{reference to destructor must be called}}
404}
405}