Home | History | Annotate | Download | only in class.dtor
      1 // RUN: %clang_cc1 -verify -std=c++11 %s
      2 
      3 struct NonTrivDtor {
      4   ~NonTrivDtor();
      5 };
      6 struct DeletedDtor {
      7   ~DeletedDtor() = delete; // expected-note 5 {{deleted here}}
      8 };
      9 class InaccessibleDtor {
     10   ~InaccessibleDtor() = default;
     11 };
     12 
     13 // A defaulted destructor for a class X is defined as deleted if:
     14 
     15 // -- X is a union-like class that has a variant member with a non-trivial
     16 // destructor.
     17 union A1 {
     18   A1();
     19   NonTrivDtor n; // expected-note {{destructor of 'A1' is implicitly deleted because variant field 'n' has a non-trivial destructor}}
     20 };
     21 A1 a1; // expected-error {{deleted function}}
     22 struct A2 {
     23   A2();
     24   union {
     25     NonTrivDtor n; // expected-note {{because variant field 'n' has a non-trivial destructor}}
     26   };
     27 };
     28 A2 a2; // expected-error {{deleted function}}
     29 union A3 {
     30   A3();
     31   NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}}
     32 };
     33 A3 a3; // expected-error {{deleted function}}
     34 struct A4 {
     35   A4();
     36   union {
     37     NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}}
     38   };
     39 };
     40 A4 a4; // expected-error {{deleted function}}
     41 
     42 // -- any of the non-static data members has class type M (or array thereof) and
     43 // M has a deleted or inaccessible destructor.
     44 struct B1 {
     45   B1();
     46   DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
     47 };
     48 B1 b1; // expected-error {{deleted function}}
     49 struct B2 {
     50   B2();
     51   InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
     52 };
     53 B2 b2; // expected-error {{deleted function}}
     54 struct B3 {
     55   B3();
     56   DeletedDtor a[4]; // expected-note {{because field 'a' has a deleted destructor}}
     57 };
     58 B3 b3; // expected-error {{deleted function}}
     59 struct B4 {
     60   B4();
     61   InaccessibleDtor a[4]; // expected-note {{because field 'a' has an inaccessible destructor}}
     62 };
     63 B4 b4; // expected-error {{deleted function}}
     64 union B5 {
     65   B5();
     66   // FIXME: Describe the anonymous union member better than ''.
     67   union { // expected-note {{because field '' has a deleted destructor}}
     68     DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
     69   };
     70 };
     71 B5 b5; // expected-error {{deleted function}}
     72 union B6 {
     73   B6();
     74   union { // expected-note {{because field '' has a deleted destructor}}
     75     InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
     76   };
     77 };
     78 B6 b6; // expected-error {{deleted function}}
     79 
     80 // -- any direct or virtual base class has a deleted or inaccessible destructor.
     81 struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
     82 struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
     83 struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
     84 struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
     85 
     86 // -- for a virtual destructor, lookup of the non-array deallocation function
     87 // results in an ambiguity or a function that is deleted or inaccessible.
     88 class D1 {
     89   void operator delete(void*);
     90 public:
     91   virtual ~D1() = default; // expected-note {{here}}
     92 } d1; // ok
     93 struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} \
     94                  // expected-error {{deleted function '~D2' cannot override a non-deleted}}
     95   // implicitly-virtual destructor
     96 } d2; // expected-error {{deleted function}}
     97 struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
     98   virtual ~D3() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
     99   void operator delete(void*, double = 0.0);
    100   void operator delete(void*, char = 0);
    101 } d3; // expected-error {{deleted function}}
    102 struct D4 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
    103   virtual ~D4() = default; // expected-note {{implicitly deleted here}}
    104   void operator delete(void*) = delete;
    105 } d4; // expected-error {{deleted function}}
    106