1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3 // Tests for implicit (non-)declaration of move constructor and
4 // assignment: p9, p11, p20, p23.
5
6 // This class, used as a member, allows to distinguish move from copy because
7 // move operations are no-throw, copy operations aren't.
8 struct ThrowingCopy {
9 ThrowingCopy() noexcept;
10 ThrowingCopy(ThrowingCopy &&) noexcept;
11 ThrowingCopy(const ThrowingCopy &) noexcept(false);
12 ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
13 ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
14 };
15
16 struct HasCopyConstructor {
17 ThrowingCopy tc;
18 HasCopyConstructor() noexcept;
19 HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
20 };
21
22 struct HasCopyAssignment {
23 ThrowingCopy tc;
24 HasCopyAssignment() noexcept;
25 HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
26 };
27
28 struct HasMoveConstructor {
29 ThrowingCopy tc;
30 HasMoveConstructor() noexcept;
31 HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
32 };
33
34 struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
35 ThrowingCopy tc;
36 HasMoveAssignment() noexcept;
37 HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
38 };
39
40 struct HasDestructor {
41 ThrowingCopy tc;
42 HasDestructor() noexcept;
43 ~HasDestructor() noexcept;
44 };
45
test_basic_exclusion()46 void test_basic_exclusion() {
47 static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
48 HasCopyConstructor hcc;
49 static_assert(!noexcept(hcc = HasCopyConstructor()), "");
50
51 static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
52 HasCopyAssignment hca;
53 static_assert(!noexcept(hca = HasCopyAssignment()), "");
54
55 static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
56 HasMoveConstructor hmc;
57 hmc = HasMoveConstructor(); // expected-error {{selected implicitly-deleted copy assignment}}
58
59 (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
60 HasMoveAssignment hma;
61 static_assert(noexcept(hma = HasMoveAssignment()), "");
62
63 static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
64 HasDestructor hd;
65 static_assert(!noexcept(hd = HasDestructor()), "");
66 }
67
68 struct PrivateMove {
69 PrivateMove() noexcept;
70 PrivateMove(const PrivateMove &) noexcept(false);
71 PrivateMove & operator =(const PrivateMove &) noexcept(false);
72 private:
73 PrivateMove(PrivateMove &&) noexcept;
74 PrivateMove & operator =(PrivateMove &&) noexcept;
75 };
76
77 struct InheritsPrivateMove : PrivateMove {};
78 struct ContainsPrivateMove {
79 PrivateMove pm;
80 };
81
82 struct PrivateDestructor {
83 PrivateDestructor() noexcept;
84 PrivateDestructor(const PrivateDestructor &) noexcept(false);
85 PrivateDestructor(PrivateDestructor &&) noexcept;
86 private:
87 ~PrivateDestructor() noexcept;
88 };
89
90 struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
91 struct ContainsPrivateDestructor {
92 PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
93 };
94
95 struct NonTrivialCopyOnly {
96 NonTrivialCopyOnly() noexcept;
97 NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
98 NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
99 };
100
101 struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
102 struct ContainsNonTrivialCopyOnly {
103 NonTrivialCopyOnly ntco;
104 };
105
106 struct ContainsConst {
107 const int i;
108 ContainsConst() noexcept;
109 ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
110 };
111
112 struct ContainsRef {
113 int &i;
114 ContainsRef() noexcept;
115 ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
116 };
117
118 struct Base {
119 Base & operator =(Base &);
120 };
121 struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
122 struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
123
test_deletion_exclusion()124 void test_deletion_exclusion() {
125 // FIXME: How to test the union thing?
126
127 static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
128 static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
129 InheritsPrivateMove ipm;
130 static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
131 ContainsPrivateMove cpm;
132 static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
133
134 (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
135 (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
136
137 static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
138 static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
139 InheritsNonTrivialCopyOnly intco;
140 static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
141 ContainsNonTrivialCopyOnly cntco;
142 static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
143
144 ContainsConst cc;
145 cc = ContainsConst(); // expected-error {{no viable}}
146
147 ContainsRef cr;
148 cr = ContainsRef(); // expected-error {{no viable}}
149
150 DirectVirtualBase dvb;
151 dvb = DirectVirtualBase(); // expected-error {{no viable}}
152
153 IndirectVirtualBase ivb;
154 ivb = IndirectVirtualBase(); // expected-error {{no viable}}
155 }
156
157 struct ContainsRValueRef {
158 int&& ri;
159 ContainsRValueRef() noexcept;
160 };
161
test_contains_rref()162 void test_contains_rref() {
163 (ContainsRValueRef(ContainsRValueRef()));
164 }
165
166
167 namespace DR1402 {
168 struct NonTrivialCopyCtor {
169 NonTrivialCopyCtor(const NonTrivialCopyCtor &);
170 };
171 struct NonTrivialCopyAssign {
172 NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
173 };
174
175 struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
176 NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
177 NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
178 };
179 struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
180 NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
181 NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
182 };
183
184 struct NonTrivialMoveAssign {
185 NonTrivialMoveAssign(NonTrivialMoveAssign&&);
186 NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
187 };
188 struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
189 NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
190 NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
191 };
192
193 // A non-movable, non-trivially-copyable class type as a subobject inhibits
194 // the declaration of a move operation.
195 struct NoMove1 { NonTrivialCopyCtor ntcc; }; // expected-note 2{{'const DR1402::NoMove1 &'}}
196 struct NoMove2 { NonTrivialCopyAssign ntcc; }; // expected-note 2{{'const DR1402::NoMove2 &'}}
197 struct NoMove3 : NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove3 &'}}
198 struct NoMove4 : NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove4 &'}}
199 struct NoMove5 : virtual NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove5 &'}}
200 struct NoMove6 : virtual NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove6 &'}}
201 struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'const DR1402::NoMove7 &'}}
202 struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'const DR1402::NoMove8 &'}}
203
204 // A non-trivially-move-assignable virtual base class inhibits the declaration
205 // of a move assignment (which might move-assign the base class multiple
206 // times).
207 struct NoMove9 : NonTrivialMoveAssign {};
208 struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'const DR1402::NoMove10 &'}}
209 struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'const DR1402::NoMove11 &'}}
210
211 struct Test {
212 friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{no matching function}}
213 friend NoMove2::NoMove2(NoMove2 &&); // expected-error {{no matching function}}
214 friend NoMove3::NoMove3(NoMove3 &&); // expected-error {{no matching function}}
215 friend NoMove4::NoMove4(NoMove4 &&); // expected-error {{no matching function}}
216 friend NoMove5::NoMove5(NoMove5 &&); // expected-error {{no matching function}}
217 friend NoMove6::NoMove6(NoMove6 &&); // expected-error {{no matching function}}
218 friend NoMove7::NoMove7(NoMove7 &&); // expected-error {{no matching function}}
219 friend NoMove8::NoMove8(NoMove8 &&); // expected-error {{no matching function}}
220 friend NoMove9::NoMove9(NoMove9 &&);
221 friend NoMove10::NoMove10(NoMove10 &&);
222 friend NoMove11::NoMove11(NoMove11 &&);
223
224 friend NoMove1 &NoMove1::operator=(NoMove1 &&); // expected-error {{no matching function}}
225 friend NoMove2 &NoMove2::operator=(NoMove2 &&); // expected-error {{no matching function}}
226 friend NoMove3 &NoMove3::operator=(NoMove3 &&); // expected-error {{no matching function}}
227 friend NoMove4 &NoMove4::operator=(NoMove4 &&); // expected-error {{no matching function}}
228 friend NoMove5 &NoMove5::operator=(NoMove5 &&); // expected-error {{no matching function}}
229 friend NoMove6 &NoMove6::operator=(NoMove6 &&); // expected-error {{no matching function}}
230 friend NoMove7 &NoMove7::operator=(NoMove7 &&); // expected-error {{no matching function}}
231 friend NoMove8 &NoMove8::operator=(NoMove8 &&); // expected-error {{no matching function}}
232 friend NoMove9 &NoMove9::operator=(NoMove9 &&);
233 friend NoMove10 &NoMove10::operator=(NoMove10 &&); // expected-error {{no matching function}}
234 friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error {{no matching function}}
235 };
236 }
237
238 namespace PR12625 {
239 struct X; // expected-note {{forward decl}}
240 struct Y {
241 X x; // expected-error {{incomplete}}
242 } y = Y();
243 }
244