1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s
2
3// "Move" semantics, trivial version.
4void move_it(__strong id &&from) {
5  id to = static_cast<__strong id&&>(from);
6}
7
8// Deduction with 'auto'.
9@interface A
10+ alloc;
11- init;
12@end
13
14// <rdar://problem/12031870>: don't warn about this
15extern "C" A* MakeA();
16
17// Ensure that deduction works with lifetime qualifiers.
18void deduction(id obj) {
19  auto a = [[A alloc] init];
20  __strong A** aPtr = &a;
21
22  auto a2([[A alloc] init]);
23  __strong A** aPtr2 = &a2;
24
25  __strong id *idp = new auto(obj);
26
27  __strong id array[17];
28  for (auto x : array) { // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
29    __strong id *xPtr = &x;
30  }
31
32  @try {
33  } @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
34  }
35}
36
37// rdar://problem/11068137
38void test1a() {
39  __autoreleasing id p; // expected-note 2 {{'p' declared here}}
40  (void) [&p] {};
41  (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
42  (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
43}
44void test1b() {
45  __autoreleasing id v;
46  __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}}
47  (void) [&p] {};
48  (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
49  (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
50}
51void test1c() {
52  __autoreleasing id v; // expected-note {{'v' declared here}}
53  __autoreleasing id &p = v;
54  (void) ^{ (void) p; };
55  (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
56}
57
58
59// <rdar://problem/11319689>
60// warn when initializing an 'auto' variable with an 'id' initializer expression
61
62void testAutoId(id obj) {
63  auto x = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
64}
65
66@interface Array
67+ (instancetype)new;
68- (id)objectAtIndex:(int)index;
69@end
70
71// ...but don't warn if it's coming from a template parameter.
72template<typename T, int N>
73void autoTemplateFunction(T param, id obj, Array *arr) {
74  auto x = param; // no-warning
75  auto y = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'y'}}
76  auto z = [arr objectAtIndex:N]; // expected-warning{{'auto' deduced as 'id' in declaration of 'z'}}
77}
78
79void testAutoIdTemplate(id obj) {
80  autoTemplateFunction<id, 2>(obj, obj, [Array new]); // no-warning
81}
82
83// rdar://12229679
84@interface NSObject @end
85typedef __builtin_va_list va_list;
86@interface MyClass : NSObject
87@end
88
89@implementation MyClass
90+ (void)fooMethod:(id)firstArg, ... {
91    va_list args;
92
93    __builtin_va_arg(args, id);
94}
95@end
96
97namespace rdar12078752 {
98  void f() {
99    NSObject* o =0;
100    __autoreleasing decltype(o) o2 = o;
101    __autoreleasing auto o3 = o;
102  }
103}
104
105namespace test_err_arc_array_param_no_ownership {
106  template <class T>
107  void func(T a) {}
108
109  void test() {
110    func([](A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
111    func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
112  }
113}
114
115namespace test_union {
116  // Implicitly-declared special functions of a union are deleted by default if
117  // ARC is enabled and the union has an ObjC pointer field.
118  union U0 {
119    id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
120  };
121
122  union U1 {
123    __weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
124    U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
125    ~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
126    U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
127    U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}}
128    U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
129    U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}}
130  };
131
132  id getStrong();
133
134  // If the ObjC pointer field of a union has a default member initializer, the
135  // implicitly-declared default constructor of the union is not deleted by
136  // default.
137  union U2 {
138    id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
139    ~U2();
140  };
141
142  // It's fine if the user has explicitly defined the special functions.
143  union U3 {
144    id f0;
145    U3();
146    ~U3();
147    U3(const U3 &);
148    U3(U3 &&);
149    U3 & operator=(const U3 &);
150    U3 & operator=(U3 &&);
151  };
152
153  // ObjC pointer fields in anonymous union fields delete the defaulted special
154  // functions of the containing class.
155  struct S0 {
156    union {
157      id f0; // expected-note 6 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
158      char f1;
159    };
160  };
161
162  struct S1 {
163    union {
164      union { // expected-note {{copy constructor of 'S1' is implicitly deleted because field '' has a deleted copy constructor}} expected-note {{copy assignment operator of 'S1' is implicitly deleted because field '' has a deleted copy assignment operator}} expected-note 4 {{'S1' is implicitly deleted because field '' has a deleted}}
165        id f0; // expected-note 2 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
166        char f1;
167      };
168      int f2;
169    };
170  };
171
172  struct S2 {
173    union {
174      // FIXME: the note should say 'f0' is causing the special functions to be deleted.
175      struct { // expected-note 6 {{'S2' is implicitly deleted because variant field '' has a non-trivial}}
176        id f0;
177        int f1;
178      };
179      int f2;
180    };
181    int f3;
182  };
183
184  U0 *x0;
185  U1 *x1;
186  U2 *x2;
187  U3 *x3;
188  S0 *x4;
189  S1 *x5;
190  S2 *x6;
191
192  static union { // expected-error {{call to implicitly-deleted default constructor of}}
193    id g0; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g0' is an ObjC pointer}}
194  };
195
196  static union { // expected-error {{call to implicitly-deleted default constructor of}}
197    union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}}
198      union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}}
199        __weak id g1; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g1' is an ObjC pointer}}
200        int g2;
201      };
202      int g3;
203    };
204    int g4;
205  };
206
207  void testDefaultConstructor() {
208    U0 t0; // expected-error {{call to implicitly-deleted default constructor}}
209    U1 t1; // expected-error {{call to implicitly-deleted default constructor}}
210    U2 t2;
211    U3 t3;
212    S0 t4; // expected-error {{call to implicitly-deleted default constructor}}
213    S1 t5; // expected-error {{call to implicitly-deleted default constructor}}
214    S2 t6; // expected-error {{call to implicitly-deleted default constructor}}
215  }
216
217  void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
218    delete u0; // expected-error {{attempt to use a deleted function}}
219    delete u1; // expected-error {{attempt to use a deleted function}}
220    delete u2;
221    delete u3;
222    delete s0; // expected-error {{attempt to use a deleted function}}
223    delete s1; // expected-error {{attempt to use a deleted function}}
224    delete s2; // expected-error {{attempt to use a deleted function}}
225  }
226
227  void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
228    U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}}
229    U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}}
230    U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}}
231    U3 t3(*u3);
232    S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}}
233    S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}}
234    S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}}
235  }
236
237  void testCopyAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
238    *x0 = *u0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
239    *x1 = *u1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
240    *x2 = *u2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
241    *x3 = *u3;
242    *x4 = *s0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
243    *x5 = *s1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
244    *x6 = *s2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
245  }
246
247  // The diagnostics below refer to the deleted copy constructors and assignment
248  // operators since defaulted move constructors and assignment operators that are
249  // defined as deleted are ignored by overload resolution.
250
251  void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
252    U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}}
253    U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}}
254    U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}}
255    U3 t3(static_cast<U3 &&>(*u3));
256    S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}}
257    S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}}
258    S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}}
259  }
260
261  void testMoveAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
262    *x0 = static_cast<U0 &&>(*u0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
263    *x1 = static_cast<U1 &&>(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
264    *x2 = static_cast<U2 &&>(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
265    *x3 = static_cast<U3 &&>(*u3);
266    *x4 = static_cast<S0 &&>(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
267    *x5 = static_cast<S1 &&>(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
268    *x6 = static_cast<S2 &&>(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
269  }
270}
271