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