1*44b21749SNathan Sidwell // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base %s
222653bacSSebastian Redl
322653bacSSebastian Redl // Tests for implicit (non-)declaration of move constructor and
422653bacSSebastian Redl // assignment: p9, p11, p20, p23.
522653bacSSebastian Redl
622653bacSSebastian Redl // This class, used as a member, allows to distinguish move from copy because
722653bacSSebastian Redl // move operations are no-throw, copy operations aren't.
822653bacSSebastian Redl struct ThrowingCopy {
922653bacSSebastian Redl ThrowingCopy() noexcept;
1022653bacSSebastian Redl ThrowingCopy(ThrowingCopy &&) noexcept;
1122653bacSSebastian Redl ThrowingCopy(const ThrowingCopy &) noexcept(false);
1222653bacSSebastian Redl ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
1322653bacSSebastian Redl ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
1422653bacSSebastian Redl };
1522653bacSSebastian Redl
1622653bacSSebastian Redl struct HasCopyConstructor {
1722653bacSSebastian Redl ThrowingCopy tc;
1822653bacSSebastian Redl HasCopyConstructor() noexcept;
1922653bacSSebastian Redl HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
2022653bacSSebastian Redl };
2122653bacSSebastian Redl
2222653bacSSebastian Redl struct HasCopyAssignment {
2322653bacSSebastian Redl ThrowingCopy tc;
2422653bacSSebastian Redl HasCopyAssignment() noexcept;
2522653bacSSebastian Redl HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
2622653bacSSebastian Redl };
2722653bacSSebastian Redl
286f1e2c6dSRichard Smith struct HasMoveConstructor {
2922653bacSSebastian Redl ThrowingCopy tc;
3022653bacSSebastian Redl HasMoveConstructor() noexcept;
31f989e51cSRichard Smith HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
3222653bacSSebastian Redl };
3322653bacSSebastian Redl
3422653bacSSebastian Redl struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
3522653bacSSebastian Redl ThrowingCopy tc;
3622653bacSSebastian Redl HasMoveAssignment() noexcept;
3722653bacSSebastian Redl HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
3822653bacSSebastian Redl };
3922653bacSSebastian Redl
4022653bacSSebastian Redl struct HasDestructor {
4122653bacSSebastian Redl ThrowingCopy tc;
4222653bacSSebastian Redl HasDestructor() noexcept;
4322653bacSSebastian Redl ~HasDestructor() noexcept;
4422653bacSSebastian Redl };
4522653bacSSebastian Redl
test_basic_exclusion()4622653bacSSebastian Redl void test_basic_exclusion() {
4722653bacSSebastian Redl static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
4822653bacSSebastian Redl HasCopyConstructor hcc;
4922653bacSSebastian Redl static_assert(!noexcept(hcc = HasCopyConstructor()), "");
5022653bacSSebastian Redl
5122653bacSSebastian Redl static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
5222653bacSSebastian Redl HasCopyAssignment hca;
5322653bacSSebastian Redl static_assert(!noexcept(hca = HasCopyAssignment()), "");
5422653bacSSebastian Redl
5522653bacSSebastian Redl static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
5622653bacSSebastian Redl HasMoveConstructor hmc;
57de1a4874SRichard Smith hmc = HasMoveConstructor(); // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
5822653bacSSebastian Redl
5922653bacSSebastian Redl (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
6022653bacSSebastian Redl HasMoveAssignment hma;
6122653bacSSebastian Redl static_assert(noexcept(hma = HasMoveAssignment()), "");
6222653bacSSebastian Redl
6322653bacSSebastian Redl static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
6422653bacSSebastian Redl HasDestructor hd;
6522653bacSSebastian Redl static_assert(!noexcept(hd = HasDestructor()), "");
6622653bacSSebastian Redl }
6722653bacSSebastian Redl
6822653bacSSebastian Redl struct PrivateMove {
6922653bacSSebastian Redl PrivateMove() noexcept;
7022653bacSSebastian Redl PrivateMove(const PrivateMove &) noexcept(false);
7122653bacSSebastian Redl PrivateMove & operator =(const PrivateMove &) noexcept(false);
7222653bacSSebastian Redl private:
7322653bacSSebastian Redl PrivateMove(PrivateMove &&) noexcept;
7422653bacSSebastian Redl PrivateMove & operator =(PrivateMove &&) noexcept;
7522653bacSSebastian Redl };
7622653bacSSebastian Redl
7722653bacSSebastian Redl struct InheritsPrivateMove : PrivateMove {};
7822653bacSSebastian Redl struct ContainsPrivateMove {
7922653bacSSebastian Redl PrivateMove pm;
8022653bacSSebastian Redl };
8122653bacSSebastian Redl
8222653bacSSebastian Redl struct PrivateDestructor {
8322653bacSSebastian Redl PrivateDestructor() noexcept;
8422653bacSSebastian Redl PrivateDestructor(const PrivateDestructor &) noexcept(false);
8522653bacSSebastian Redl PrivateDestructor(PrivateDestructor &&) noexcept;
8622653bacSSebastian Redl private:
8722653bacSSebastian Redl ~PrivateDestructor() noexcept;
8822653bacSSebastian Redl };
8922653bacSSebastian Redl
90852265ffSRichard Smith struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
91852265ffSRichard Smith struct ContainsPrivateDestructor {
92852265ffSRichard Smith PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
9322653bacSSebastian Redl };
9422653bacSSebastian Redl
9522653bacSSebastian Redl struct NonTrivialCopyOnly {
9622653bacSSebastian Redl NonTrivialCopyOnly() noexcept;
9722653bacSSebastian Redl NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
9822653bacSSebastian Redl NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
9922653bacSSebastian Redl };
10022653bacSSebastian Redl
10122653bacSSebastian Redl struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
10222653bacSSebastian Redl struct ContainsNonTrivialCopyOnly {
10322653bacSSebastian Redl NonTrivialCopyOnly ntco;
10422653bacSSebastian Redl };
10522653bacSSebastian Redl
10622653bacSSebastian Redl struct ContainsConst {
10722653bacSSebastian Redl const int i;
10822653bacSSebastian Redl ContainsConst() noexcept;
10922653bacSSebastian Redl ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
11022653bacSSebastian Redl };
11122653bacSSebastian Redl
11222653bacSSebastian Redl struct ContainsRef {
11322653bacSSebastian Redl int &i;
11422653bacSSebastian Redl ContainsRef() noexcept;
11522653bacSSebastian Redl ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
11622653bacSSebastian Redl };
11722653bacSSebastian Redl
11822653bacSSebastian Redl struct Base {
11922653bacSSebastian Redl Base & operator =(Base &);
12022653bacSSebastian Redl };
12122653bacSSebastian Redl struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
12222653bacSSebastian Redl struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
12322653bacSSebastian Redl
test_deletion_exclusion()12422653bacSSebastian Redl void test_deletion_exclusion() {
12522653bacSSebastian Redl // FIXME: How to test the union thing?
12622653bacSSebastian Redl
12722653bacSSebastian Redl static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
12822653bacSSebastian Redl static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
12922653bacSSebastian Redl InheritsPrivateMove ipm;
13022653bacSSebastian Redl static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
13122653bacSSebastian Redl ContainsPrivateMove cpm;
13222653bacSSebastian Redl static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
13322653bacSSebastian Redl
13474f7d50fSDouglas Gregor (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
13574f7d50fSDouglas Gregor (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
13622653bacSSebastian Redl
13722653bacSSebastian Redl static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
13822653bacSSebastian Redl static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
13922653bacSSebastian Redl InheritsNonTrivialCopyOnly intco;
14022653bacSSebastian Redl static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
14122653bacSSebastian Redl ContainsNonTrivialCopyOnly cntco;
14222653bacSSebastian Redl static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
14322653bacSSebastian Redl
14422653bacSSebastian Redl ContainsConst cc;
14522653bacSSebastian Redl cc = ContainsConst(); // expected-error {{no viable}}
14622653bacSSebastian Redl
14722653bacSSebastian Redl ContainsRef cr;
14822653bacSSebastian Redl cr = ContainsRef(); // expected-error {{no viable}}
14922653bacSSebastian Redl
15022653bacSSebastian Redl DirectVirtualBase dvb;
15122653bacSSebastian Redl dvb = DirectVirtualBase(); // expected-error {{no viable}}
15222653bacSSebastian Redl
15322653bacSSebastian Redl IndirectVirtualBase ivb;
15422653bacSSebastian Redl ivb = IndirectVirtualBase(); // expected-error {{no viable}}
15522653bacSSebastian Redl }
15622653bacSSebastian Redl
15722653bacSSebastian Redl struct ContainsRValueRef {
15822653bacSSebastian Redl int&& ri;
15922653bacSSebastian Redl ContainsRValueRef() noexcept;
16022653bacSSebastian Redl };
16122653bacSSebastian Redl
test_contains_rref()16222653bacSSebastian Redl void test_contains_rref() {
16322653bacSSebastian Redl (ContainsRValueRef(ContainsRValueRef()));
16422653bacSSebastian Redl }
165cf8ec8daSRichard Smith
166cf8ec8daSRichard Smith
167cf8ec8daSRichard Smith namespace DR1402 {
168cf8ec8daSRichard Smith struct NonTrivialCopyCtor {
169cf8ec8daSRichard Smith NonTrivialCopyCtor(const NonTrivialCopyCtor &);
170cf8ec8daSRichard Smith };
171cf8ec8daSRichard Smith struct NonTrivialCopyAssign {
172cf8ec8daSRichard Smith NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
173cf8ec8daSRichard Smith };
174cf8ec8daSRichard Smith
175cf8ec8daSRichard Smith struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
176cf8ec8daSRichard Smith NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
177cf8ec8daSRichard Smith NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
178cf8ec8daSRichard Smith };
179cf8ec8daSRichard Smith struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
180cf8ec8daSRichard Smith NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
181cf8ec8daSRichard Smith NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
182cf8ec8daSRichard Smith };
183cf8ec8daSRichard Smith
184cf8ec8daSRichard Smith struct NonTrivialMoveAssign {
185cf8ec8daSRichard Smith NonTrivialMoveAssign(NonTrivialMoveAssign&&);
186cf8ec8daSRichard Smith NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
187cf8ec8daSRichard Smith };
188cf8ec8daSRichard Smith struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
189cf8ec8daSRichard Smith NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
190cf8ec8daSRichard Smith NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
191cf8ec8daSRichard Smith };
192cf8ec8daSRichard Smith
1938b86f2d4SRichard Smith // DR1402: A non-movable, non-trivially-copyable class type as a subobject no
1948b86f2d4SRichard Smith // longer inhibits the declaration of a move operation.
1958b86f2d4SRichard Smith struct NoMove1 { NonTrivialCopyCtor ntcc; };
1968b86f2d4SRichard Smith struct NoMove2 { NonTrivialCopyAssign ntcc; };
1978b86f2d4SRichard Smith struct NoMove3 : NonTrivialCopyCtor {};
1988b86f2d4SRichard Smith struct NoMove4 : NonTrivialCopyAssign {};
1998b86f2d4SRichard Smith struct NoMove5 : virtual NonTrivialCopyCtor {};
2008b86f2d4SRichard Smith struct NoMove6 : virtual NonTrivialCopyAssign {};
2018b86f2d4SRichard Smith struct NoMove7 : NonTrivialCopyCtorVBase {};
2028b86f2d4SRichard Smith struct NoMove8 : NonTrivialCopyAssignVBase {};
203cf8ec8daSRichard Smith
2048b86f2d4SRichard Smith // DR1402: A non-trivially-move-assignable virtual base class no longer
2058b86f2d4SRichard Smith // inhibits the declaration of a move assignment (even though it might
2068b86f2d4SRichard Smith // move-assign the base class multiple times).
207cf8ec8daSRichard Smith struct NoMove9 : NonTrivialMoveAssign {};
2088b86f2d4SRichard Smith struct NoMove10 : virtual NonTrivialMoveAssign {};
2098b86f2d4SRichard Smith struct NoMove11 : NonTrivialMoveAssignVBase {};
210cf8ec8daSRichard Smith
test(T t)2118b86f2d4SRichard Smith template<typename T> void test(T t) {
2128b86f2d4SRichard Smith (void)T(static_cast<T&&>(t)); // ok
2138b86f2d4SRichard Smith t = static_cast<T&&>(t); // ok
2148b86f2d4SRichard Smith }
2158b86f2d4SRichard Smith template void test(NoMove1);
2168b86f2d4SRichard Smith template void test(NoMove2);
2178b86f2d4SRichard Smith template void test(NoMove3);
2188b86f2d4SRichard Smith template void test(NoMove4);
2198b86f2d4SRichard Smith template void test(NoMove5);
2208b86f2d4SRichard Smith template void test(NoMove6);
2218b86f2d4SRichard Smith template void test(NoMove7);
2228b86f2d4SRichard Smith template void test(NoMove8);
2238b86f2d4SRichard Smith template void test(NoMove9);
2248b86f2d4SRichard Smith template void test(NoMove10);
2258b86f2d4SRichard Smith template void test(NoMove11);
226cf8ec8daSRichard Smith
2278b86f2d4SRichard Smith struct CopyOnly {
2288b86f2d4SRichard Smith CopyOnly(const CopyOnly&);
2298b86f2d4SRichard Smith CopyOnly &operator=(const CopyOnly&);
230cf8ec8daSRichard Smith };
2318b86f2d4SRichard Smith struct MoveOnly {
2328b86f2d4SRichard Smith MoveOnly(MoveOnly&&); // expected-note {{user-declared move}}
2338b86f2d4SRichard Smith MoveOnly &operator=(MoveOnly&&);
2348b86f2d4SRichard Smith };
2358b86f2d4SRichard Smith template void test(CopyOnly); // ok, copies
2368b86f2d4SRichard Smith template void test(MoveOnly); // ok, moves
2378b86f2d4SRichard Smith struct CopyAndMove { // expected-note {{implicitly deleted}}
2388b86f2d4SRichard Smith CopyOnly co;
2398b86f2d4SRichard Smith MoveOnly mo; // expected-note {{deleted copy}}
2408b86f2d4SRichard Smith };
2418b86f2d4SRichard Smith template void test(CopyAndMove); // ok, copies co, moves mo
test2(CopyAndMove cm)2428b86f2d4SRichard Smith void test2(CopyAndMove cm) {
2438b86f2d4SRichard Smith (void)CopyAndMove(cm); // expected-error {{deleted}}
2448b86f2d4SRichard Smith cm = cm; // expected-error {{deleted}}
2458b86f2d4SRichard Smith }
246b2504bdcSRichard Smith
247b2504bdcSRichard Smith namespace VbaseMove {
248b2504bdcSRichard Smith struct A {};
249b2504bdcSRichard Smith struct B { B &operator=(B&&); };
250b2504bdcSRichard Smith struct C { C &operator=(const C&); };
251b2504bdcSRichard Smith struct D { B b; };
252b2504bdcSRichard Smith
253b2504bdcSRichard Smith template<typename T, unsigned I, bool NonTrivialMove = false>
254b2504bdcSRichard Smith struct E : virtual T {};
255b2504bdcSRichard Smith
256b2504bdcSRichard Smith template<typename T, unsigned I>
257b2504bdcSRichard Smith struct E<T, I, true> : virtual T { E &operator=(E&&); };
258b2504bdcSRichard Smith
259b2504bdcSRichard Smith template<typename T>
260b2504bdcSRichard Smith struct F :
2616ed72516SAlp Toker E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
2626ed72516SAlp Toker E<T, 1> {}; // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
263b2504bdcSRichard Smith
264b2504bdcSRichard Smith template<typename T>
265b2504bdcSRichard Smith struct G : E<T, 0, true>, E<T, 0> {};
266b2504bdcSRichard Smith
267b2504bdcSRichard Smith template<typename T>
268b2504bdcSRichard Smith struct H : E<T, 0, true>, E<T, 1, true> {};
269b2504bdcSRichard Smith
270b2504bdcSRichard Smith template<typename T>
271b2504bdcSRichard Smith struct I : E<T, 0>, T {};
272b2504bdcSRichard Smith
273b2504bdcSRichard Smith template<typename T>
274b2504bdcSRichard Smith struct J :
2756ed72516SAlp Toker E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
2766ed72516SAlp Toker virtual T {}; // expected-note-re 2{{virtual base class '{{[BD]}}' declared here}}
277b2504bdcSRichard Smith
move(T t)278b2504bdcSRichard Smith template<typename T> void move(T t) { t = static_cast<T&&>(t); }
2796ed72516SAlp Toker // expected-warning-re@-1 4{{defaulted move assignment operator of {{.*}} will move assign virtual base class '{{[BD]}}' multiple times}}
280b2504bdcSRichard Smith template void move(F<A>);
281b2504bdcSRichard Smith template void move(F<B>); // expected-note {{in instantiation of}}
282b2504bdcSRichard Smith template void move(F<C>);
283b2504bdcSRichard Smith template void move(F<D>); // expected-note {{in instantiation of}}
284b2504bdcSRichard Smith template void move(G<A>);
285b2504bdcSRichard Smith template void move(G<B>);
286b2504bdcSRichard Smith template void move(G<C>);
287b2504bdcSRichard Smith template void move(G<D>);
288b2504bdcSRichard Smith template void move(H<A>);
289b2504bdcSRichard Smith template void move(H<B>);
290b2504bdcSRichard Smith template void move(H<C>);
291b2504bdcSRichard Smith template void move(H<D>);
292b2504bdcSRichard Smith template void move(I<A>);
293b2504bdcSRichard Smith template void move(I<B>);
294b2504bdcSRichard Smith template void move(I<C>);
295b2504bdcSRichard Smith template void move(I<D>);
296b2504bdcSRichard Smith template void move(J<A>);
297b2504bdcSRichard Smith template void move(J<B>); // expected-note {{in instantiation of}}
298b2504bdcSRichard Smith template void move(J<C>);
299b2504bdcSRichard Smith template void move(J<D>); // expected-note {{in instantiation of}}
300b2504bdcSRichard Smith }
301cf8ec8daSRichard Smith }
3021ad04d95SRichard Smith
3031ad04d95SRichard Smith namespace PR12625 {
3041ad04d95SRichard Smith struct X; // expected-note {{forward decl}}
3051ad04d95SRichard Smith struct Y {
3061ad04d95SRichard Smith X x; // expected-error {{incomplete}}
3071ad04d95SRichard Smith } y = Y();
3081ad04d95SRichard Smith }
309