1 | // RUN: %clang_cc1 -verify -std=c++11 %s -Wno-defaulted-function-deleted |
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 2{{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 | |