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