1 // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -fcxx-exceptions -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
3 
4 #if defined(BE_THE_HEADER)
5 
6 // Wdelete-non-virtual-dtor should warn about the delete from smart pointer
7 // classes in system headers (std::unique_ptr...) too.
8 
9 #pragma clang system_header
10 namespace dnvd {
11 
12 struct SystemB {
13   virtual void foo();
14 };
15 
16 template <typename T>
17 class simple_ptr {
18 public:
simple_ptr(T * t)19   simple_ptr(T* t): _ptr(t) {}
~simple_ptr()20   ~simple_ptr() { delete _ptr; } // \
21     // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} \
22     // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}}
operator *() const23   T& operator*() const { return *_ptr; }
24 private:
25   T* _ptr;
26 };
27 }
28 
29 #else
30 
31 #define BE_THE_HEADER
32 #include __FILE__
33 
34 class A {
35 public:
36   ~A();
37 };
38 
39 class B {
40 public:
~B()41   ~B() { }
42 };
43 
44 class C {
45 public:
46   (~C)() { }
47 };
48 
49 struct D {
~DD50   static void ~D(int, ...) const { } //                          \
51     // expected-error{{static member function cannot have 'const' qualifier}} \
52     // expected-error{{destructor cannot be declared 'static'}}  \
53     // expected-error{{destructor cannot have any parameters}}   \
54     // expected-error{{destructor cannot be variadic}} \
55     // expected-error{{destructor cannot have a return type}} \
56     // expected-error{{'const' qualifier is not allowed on a destructor}}
57 };
58 
59 struct D2 {
~D2D260   void ~D2() { } //                          \
61   // expected-error{{destructor cannot have a return type}}
62 };
63 
64 
65 struct E;
66 
67 typedef E E_typedef;
68 struct E {
69   ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
70 };
71 
72 struct F {
73   (~F)(); // expected-note {{previous declaration is here}}
74   ~F(); // expected-error {{destructor cannot be redeclared}}
75 };
76 
77 ~; // expected-error {{expected a class name after '~' to name a destructor}}
78 ~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
79 ~operator+(int, int);  // expected-error {{expected a class name after '~' to name a destructor}}
~F()80 ~F(){} // expected-error {{destructor must be a non-static member function}}
81 
82 struct G {
83   ~G();
84 };
85 
~G()86 G::~G() { }
87 
88 // <rdar://problem/6841210>
89 struct H {
~HH90   ~H(void) { }
91 };
92 
93 struct X {};
94 
95 struct Y {
96   ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
97 };
98 
99 namespace PR6421 {
100   class T; // expected-note{{forward declaration}}
101 
102   class QGenericArgument // expected-note{{declared here}}
103   {
104     template<typename U>
foo(T t)105     void foo(T t) // expected-error{{variable has incomplete type}}
106     { }
107 
disconnect()108     void disconnect()
109     {
110       T* t;
111       bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
112       // expected-error{{does not refer to a value}}
113     }
114   };
115 }
116 
117 namespace PR6709 {
118 #ifdef MSABI
119   // This bug, "Clang instantiates destructor for function argument" is intended
120   // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
121   // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
122   // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
123 #endif
~X()124   template<class T> class X { T v; ~X() { ++*v; } };
a(X<int> x)125   void a(X<int> x) {}
126 }
127 
128 struct X0 { virtual ~X0() throw(); };
129 struct X1 : public X0 { };
130 
131 // Make sure we instantiate operator deletes when building a virtual
132 // destructor.
133 namespace test6 {
134   template <class T> class A {
135   public:
136     void *operator new(__SIZE_TYPE__);
operator delete(void * p)137     void operator delete(void *p) {
138       T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
139     }
140 
141 #ifdef MSABI
142     // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
143 #endif
~A()144     virtual ~A() {}
145   };
146 
147 #ifndef MSABI
148     // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
149 #endif
150   class B : A<int> { B(); };
B()151   B::B() {}
152 }
153 
154 // Make sure classes are marked invalid when they have invalid
155 // members.  This avoids a crash-on-invalid.
156 namespace test7 {
157   struct A {
158     ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
159   };
160   struct B : A {};
161 
test()162   void test() {
163     B *b;
164     b->~B();
165   }
166 }
167 
168 namespace nonvirtualdtor {
169 struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
170   virtual void m();
171 };
172 
173 struct S2 {
174   ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
175   virtual void m();
176 };
177 
178 struct S3 : public S1 {  // expected-warning {{has virtual functions but non-virtual destructor}}
179   virtual void m();
180 };
181 
182 struct S4 : public S2 {  // expected-warning {{has virtual functions but non-virtual destructor}}
183   virtual void m();
184 };
185 
186 struct B {
187   virtual ~B();
188   virtual void m();
189 };
190 
191 struct S5 : public B {
192   virtual void m();
193 };
194 
195 struct S6 {
196   virtual void m();
197 private:
198   ~S6();
199 };
200 
201 struct S7 {
202   virtual void m();
203 protected:
204   ~S7();
205 };
206 
207 struct S8 {} s8;
208 
~S8()209 UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}}
210   s8.~S8();
211 }
212 
213 template<class T> class TS : public B {
214   virtual void m();
215 };
216 
217 TS<int> baz;
218 
219 template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
220   virtual void m();
221 };
222 
223 TS2<int> foo; // expected-note {{instantiation}}
224 }
225 
226 namespace dnvd { // delete-non-virtual-dtor warning
227 struct NP {};
228 
229 struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
230   virtual void foo();
231 };
232 
233 struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
234 
235 struct F final : B {};
236 
237 struct VB {
238   virtual void foo();
239   virtual ~VB();
240 };
241 
242 struct VD: VB {};
243 
244 struct VF final: VB {};
245 
246 template <typename T>
247 class simple_ptr2 {
248 public:
simple_ptr2(T * t)249   simple_ptr2(T* t): _ptr(t) {}
~simple_ptr2()250   ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}}
operator *() const251   T& operator*() const { return *_ptr; }
252 private:
253   T* _ptr;
254 };
255 
256 void use(B&);
257 void use(SystemB&);
258 void use(VB&);
259 
nowarnstack()260 void nowarnstack() {
261   B b; use(b);
262   D d; use(d);
263   F f; use(f);
264   VB vb; use(vb);
265   VD vd; use(vd);
266   VF vf; use(vf);
267 }
268 
nowarnnonpoly()269 void nowarnnonpoly() {
270   {
271     NP* np = new NP();
272     delete np;
273   }
274   {
275     NP* np = new NP[4];
276     delete[] np;
277   }
278 }
279 
280 // FIXME: Why are these supposed to not warn?
nowarnarray()281 void nowarnarray() {
282   {
283     B* b = new B[4];
284     delete[] b;
285   }
286   {
287     D* d = new D[4];
288     delete[] d;
289   }
290   {
291     VB* vb = new VB[4];
292     delete[] vb;
293   }
294   {
295     VD* vd = new VD[4];
296     delete[] vd;
297   }
298 }
299 
300 template <typename T>
nowarntemplate()301 void nowarntemplate() {
302   {
303     T* t = new T();
304     delete t;
305   }
306   {
307     T* t = new T[4];
308     delete[] t;
309   }
310 }
311 
nowarn0()312 void nowarn0() {
313   {
314     F* f = new F();
315     delete f;
316   }
317   {
318     VB* vb = new VB();
319     delete vb;
320   }
321   {
322     VB* vb = new VD();
323     delete vb;
324   }
325   {
326     VD* vd = new VD();
327     delete vd;
328   }
329   {
330     VF* vf = new VF();
331     delete vf;
332   }
333 }
334 
nowarn0_explicit_dtor(F * f,VB * vb,VD * vd,VF * vf)335 void nowarn0_explicit_dtor(F* f, VB* vb, VD* vd, VF* vf) {
336   f->~F();
337   f->~F();
338   vb->~VB();
339   vd->~VD();
340   vf->~VF();
341 }
342 
warn0()343 void warn0() {
344   {
345     B* b = new B();
346     delete b; // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}}
347   }
348   {
349     B* b = new D();
350     delete b; // expected-warning {{delete called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}}
351   }
352   {
353     D* d = new D();
354     delete d; // expected-warning {{delete called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}}
355   }
356 }
357 
358 // Taken from libc++, slightly simplified.
359 template <class>
360 struct __is_destructible_apply { typedef int type; };
361 struct __two {char __lx[2];};
362 template <typename _Tp>
363 struct __is_destructor_wellformed {
364   template <typename _Tp1>
365   static char __test(typename __is_destructible_apply<
366                        decltype(_Tp1().~_Tp1())>::type);
367   template <typename _Tp1>
368   static __two __test (...);
369 
370   static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
371 };
372 
warn0_explicit_dtor(B * b,B & br,D * d)373 void warn0_explicit_dtor(B* b, B& br, D* d) {
374   b->~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}}
375   b->B::~B(); // No warning when the call isn't virtual.
376 
377   // No warning in unevaluated contexts.
378   (void)__is_destructor_wellformed<B>::value;
379 
380   br.~B(); // expected-warning {{destructor called on non-final 'dnvd::B' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}}
381   br.B::~B();
382 
383   d->~D(); // expected-warning {{destructor called on non-final 'dnvd::D' that has virtual functions but non-virtual destructor}} expected-note{{qualify call to silence this warning}}
384   d->D::~D();
385 }
386 
nowarn1()387 void nowarn1() {
388   {
389     simple_ptr<F> f(new F());
390     use(*f);
391   }
392   {
393     simple_ptr<VB> vb(new VB());
394     use(*vb);
395   }
396   {
397     simple_ptr<VB> vb(new VD());
398     use(*vb);
399   }
400   {
401     simple_ptr<VD> vd(new VD());
402     use(*vd);
403   }
404   {
405     simple_ptr<VF> vf(new VF());
406     use(*vf);
407   }
408   {
409     simple_ptr<SystemB> sb(new SystemB());
410     use(*sb);
411   }
412 }
413 
warn1()414 void warn1() {
415   {
416     simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
417     use(*b);
418   }
419   {
420     simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
421     use(*b);
422   }
423   {
424     simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
425     use(*d);
426   }
427 }
428 }
429 
430 namespace PR9238 {
431   class B { public: ~B(); };
~C()432   class C : virtual B { public: ~C() { } };
433 }
434 
435 namespace PR7900 {
436   struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
437   };
438   struct B : public A {
439   };
foo()440   void foo() {
441     B b;
442     b.~B();
443     b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
444     (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
445   }
446 }
447 
448 namespace PR16892 {
449   auto p = &A::~A; // expected-error{{taking the address of a destructor}}
450 }
451 
452 namespace PR20238 {
453 struct S {
~SPR20238::S454   volatile ~S() { } // expected-error{{destructor cannot have a return type}}
455 };
456 }
457 
458 namespace PR22668 {
459 struct S {
460 };
f(S s)461 void f(S s) {
462   (s.~S)();
463 }
g(S s)464 void g(S s) {
465   (s.~S); // expected-error{{reference to destructor must be called}}
466 }
467 }
468 
469 class Invalid {
470     ~Invalid();
471     UnknownType xx; // expected-error{{unknown type name}}
472 };
473 
474 // The constructor definition should not have errors
~Invalid()475 Invalid::~Invalid() {}
476 
477 namespace PR30361 {
478 template <typename T>
479 struct C1 {
~C1PR30361::C1480   ~C1() {}
operator C1<T>*PR30361::C1481   operator C1<T>* () { return nullptr; }
482   void foo1();
483 };
484 
485 template<typename T>
foo1()486 void C1<T>::foo1() {
487   C1::operator C1<T>*();
488   C1::~C1();
489 }
490 
foo1()491 void foo1() {
492   C1<int> x;
493   x.foo1();
494 }
495 }
496 #endif // BE_THE_HEADER
497