Clang Project

clang_source_code/test/CXX/special/class.copy/p11.0x.move.cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3struct Trivial {};
4struct NonTrivial {
5  NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}
6};
7struct DeletedCopy {
8  DeletedCopy(const DeletedCopy&) = delete;
9};
10
11// A defaulted move constructor for a class X is defined as deleted if X has:
12
13// -- a variant member with a non-trivial corresponding constructor
14union DeletedNTVariant {
15  NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
16  DeletedNTVariant(DeletedNTVariant&&);
17};
18DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
19
20struct DeletedNTVariant2 {
21  union {
22    NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
23  };
24  DeletedNTVariant2(DeletedNTVariant2&&);
25};
26DeletedNTVariant2::DeletedNTVariant2(DeletedNTVariant2&&) = default; // expected-error{{would delete}}
27
28// Note, move constructor is not a candidate because it is deleted.
29template<typename T> struct DeletedNTVariant3 { // expected-note 2{{default}} expected-note 2{{copy}}
30  union {
31    T NT;
32  };
33};
34extern DeletedNTVariant3<NonTrivial> dntv3a(0); // expected-error {{no matching}}
35extern DeletedNTVariant3<DeletedCopy> dntv3a(0); // expected-error {{no matching}}
36
37// -- a non-static data member of class type M (or array thereof) that cannot be
38//    copied because overload resolution results in an ambiguity or a function
39//    that is deleted or inaccessible
40struct NoAccess {
41  NoAccess() = default;
42private:
43  NoAccess(NoAccess&&);
44
45  friend struct HasAccess;
46};
47
48struct HasNoAccess {
49  NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
50  HasNoAccess(HasNoAccess&&);
51};
52HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
53
54struct HasAccess {
55  NoAccess NA;
56  HasAccess(HasAccess&&);
57};
58HasAccess::HasAccess(HasAccess&&) = default;
59
60struct Ambiguity {
61  Ambiguity(const Ambiguity&&);
62  Ambiguity(volatile Ambiguity&&);
63};
64
65struct IsAmbiguous {
66  Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
67  IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}
68};
69IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
70
71struct Deleted {
72  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
73  // 'IA' is deleted, but we select the copy constructor (we ignore the move
74  // constructor, because it was defaulted and deleted).
75  IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}
76  Deleted(Deleted&&);
77};
78Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
79
80// It's implied (but not stated) that this should also happen if overload
81// resolution fails.
82struct ConstMember {
83  const Trivial ct;
84  ConstMember(ConstMember&&);
85};
86ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
87struct ConstMoveOnlyMember {
88  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
89  // 'cnt' is deleted, but we select the copy constructor, because the object is
90  // const.
91  const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}
92  ConstMoveOnlyMember(ConstMoveOnlyMember&&);
93};
94ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
95struct VolatileMember {
96  volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
97  VolatileMember(VolatileMember&&);
98};
99VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
100
101// -- a direct or virtual base class B that cannot be moved because overload
102//    resolution results in an ambiguity or a function that is deleted or
103//    inaccessible
104struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
105  AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
106};
107AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
108
109struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
110  DeletedMoveBase(DeletedMoveBase&&);
111};
112DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
113
114struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
115  InaccessibleMoveBase(InaccessibleMoveBase&&);
116};
117InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
118
119// -- any direct or virtual base class or non-static data member of a type with
120//    a destructor that is deleted or inaccessible
121struct NoAccessDtor {
122  NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
123private:
124  ~NoAccessDtor();
125  friend struct HasAccessDtor;
126};
127
128struct HasNoAccessDtor {
129  NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
130  HasNoAccessDtor(HasNoAccessDtor&&);
131};
132HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
133
134struct HasAccessDtor {
135  NoAccessDtor NAD;
136  HasAccessDtor(HasAccessDtor&&);
137};
138HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
139
140struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
141};
142extern HasNoAccessDtorBase HNADBa;
143HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
144
145// The restriction on rvalue reference members applies to only the copy
146// constructor.
147struct RValue {
148  int &&ri = 1;
149  RValue(RValue&&);
150};
151RValue::RValue(RValue&&) = default;
152
153// -- a non-static data member or direct or virtual base class with a type that
154//    does not have a move constructor and is not trivially copyable
155struct CopyOnly {
156  CopyOnly(const CopyOnly&);
157};
158
159struct NonMove {
160  CopyOnly CO;
161  NonMove(NonMove&&);
162};
163NonMove::NonMove(NonMove&&) = default; // ok under DR1402
164
165struct Moveable {
166  Moveable();
167  Moveable(Moveable&&);
168};
169
170struct HasMove {
171  Moveable M;
172  HasMove(HasMove&&);
173};
174HasMove::HasMove(HasMove&&) = default;
175
176namespace DR1402 {
177  struct member {
178    member();
179    member(const member&);
180    member& operator=(const member&);
181    ~member();
182  };
183
184  struct A {
185    member m_;
186
187    A() = default;
188    A(const A&) = default;
189    A& operator=(const A&) = default;
190    A(A&&) = default;
191    A& operator=(A&&) = default;
192    ~A() = default;
193  };
194
195  // ok, A's explicitly-defaulted move operations copy m_.
196  void f() {
197    A a, b(a), c(static_cast<A&&>(a));
198    a = b;
199    b = static_cast<A&&>(c);
200  }
201}
202