Home | History | Annotate | Download | only in SemaCXX
      1 // 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
      3 class A {
      4 public:
      5   ~A();
      6 };
      7 
      8 class B {
      9 public:
     10   ~B() { }
     11 };
     12 
     13 class C {
     14 public:
     15   (~C)() { }
     16 };
     17 
     18 struct D {
     19   static void ~D(int, ...) const { } //                          \
     20     // expected-error{{static member function cannot have 'const' qualifier}} \
     21     // expected-error{{destructor cannot be declared 'static'}}  \
     22     // expected-error{{destructor cannot have any parameters}}   \
     23     // 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}}
     26 };
     27 
     28 struct D2 {
     29   void ~D2() { } //                          \
     30   // expected-error{{destructor cannot have a return type}}
     31 };
     32 
     33 
     34 struct E;
     35 
     36 typedef E E_typedef;
     37 struct E {
     38   ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
     39 };
     40 
     41 struct F {
     42   (~F)(); // expected-note {{previous declaration is here}}
     43   ~F(); // expected-error {{destructor cannot be redeclared}}
     44 };
     45 
     46 ~; // expected-error {{expected a class name after '~' to name a destructor}}
     47 ~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
     48 ~operator+(int, int);  // expected-error {{expected a class name after '~' to name a destructor}}
     49 ~F(){} // expected-error {{destructor must be a non-static member function}}
     50 
     51 struct G {
     52   ~G();
     53 };
     54 
     55 G::~G() { }
     56 
     57 // <rdar://problem/6841210>
     58 struct H {
     59   ~H(void) { }
     60 };
     61 
     62 struct X {};
     63 
     64 struct Y {
     65   ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
     66 };
     67 
     68 namespace PR6421 {
     69   class T; // expected-note{{forward declaration}}
     70 
     71   class QGenericArgument // expected-note{{declared here}}
     72   {
     73     template<typename U>
     74     void foo(T t) // expected-error{{variable has incomplete type}}
     75     { }
     76 
     77     void disconnect()
     78     {
     79       T* t;
     80       bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
     81       // expected-error{{does not refer to a value}}
     82     }
     83   };
     84 }
     85 
     86 namespace PR6709 {
     87 #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
     93   template<class T> class X { T v; ~X() { ++*v; } };
     94   void a(X<int> x) {}
     95 }
     96 
     97 struct X0 { virtual ~X0() throw(); };
     98 struct X1 : public X0 { };
     99 
    100 // Make sure we instantiate operator deletes when building a virtual
    101 // destructor.
    102 namespace test6 {
    103   template <class T> class A {
    104   public:
    105     void *operator new(__SIZE_TYPE__);
    106     void operator delete(void *p) {
    107       T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
    108     }
    109 
    110 #ifdef MSABI
    111     // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
    112 #endif
    113     virtual ~A() {}
    114   };
    115 
    116 #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(); };
    120   B::B() {}
    121 }
    122 
    123 // Make sure classes are marked invalid when they have invalid
    124 // members.  This avoids a crash-on-invalid.
    125 namespace 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 }
    136 
    137 namespace nonvirtualdtor {
    138 struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
    139   virtual void m();
    140 };
    141 
    142 struct S2 {
    143   ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
    144   virtual void m();
    145 };
    146 
    147 struct S3 : public S1 {  // expected-warning {{has virtual functions but non-virtual destructor}}
    148   virtual void m();
    149 };
    150 
    151 struct S4 : public S2 {  // expected-warning {{has virtual functions but non-virtual destructor}}
    152   virtual void m();
    153 };
    154 
    155 struct B {
    156   virtual ~B();
    157   virtual void m();
    158 };
    159 
    160 struct S5 : public B {
    161   virtual void m();
    162 };
    163 
    164 struct S6 {
    165   virtual void m();
    166 private:
    167   ~S6();
    168 };
    169 
    170 struct S7 {
    171   virtual void m();
    172 protected:
    173   ~S7();
    174 };
    175 
    176 struct S8 {} s8;
    177 
    178 UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}}
    179   s8.~S8();
    180 }
    181 
    182 template<class T> class TS : public B {
    183   virtual void m();
    184 };
    185 
    186 TS<int> baz;
    187 
    188 template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
    189   virtual void m();
    190 };
    191 
    192 TS2<int> foo; // expected-note {{instantiation}}
    193 }
    194 
    195 namespace dnvd { // delete-non-virtual-dtor warning
    196 struct NP {};
    197 
    198 struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
    199   virtual void foo();
    200 };
    201 
    202 struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
    203 
    204 struct F final : B {};
    205 
    206 struct VB {
    207   virtual void foo();
    208   virtual ~VB();
    209 };
    210 
    211 struct VD: VB {};
    212 
    213 struct VF final: VB {};
    214 
    215 template <typename T>
    216 class simple_ptr {
    217 public:
    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; }
    223 private:
    224   T* _ptr;
    225 };
    226 
    227 template <typename T>
    228 class simple_ptr2 {
    229 public:
    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; }
    233 private:
    234   T* _ptr;
    235 };
    236 
    237 void use(B&);
    238 void use(VB&);
    239 
    240 void 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 
    249 void nowarnnonpoly() {
    250   {
    251     NP* np = new NP();
    252     delete np;
    253   }
    254   {
    255     NP* np = new NP[4];
    256     delete[] np;
    257   }
    258 }
    259 
    260 void 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 
    279 template <typename T>
    280 void nowarntemplate() {
    281   {
    282     T* t = new T();
    283     delete t;
    284   }
    285   {
    286     T* t = new T[4];
    287     delete[] t;
    288   }
    289 }
    290 
    291 void 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 
    314 void 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 
    329 void 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 
    352 void 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 
    368 namespace PR9238 {
    369   class B { public: ~B(); };
    370   class C : virtual B { public: ~C() { } };
    371 }
    372 
    373 namespace 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 }
    385 
    386 namespace PR16892 {
    387   auto p = &A::~A; // expected-error{{taking the address of a destructor}}
    388 }
    389 
    390 namespace PR20238 {
    391 struct S {
    392   volatile ~S() { } // expected-error{{destructor cannot have a return type}}
    393 };
    394 }
    395 
    396 namespace PR22668 {
    397 struct S {
    398 };
    399 void f(S s) {
    400   (s.~S)();
    401 }
    402 void g(S s) {
    403   (s.~S); // expected-error{{reference to destructor must be called}}
    404 }
    405 }
    406