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. |
4 | void 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 |
15 | extern "C" A* MakeA(); |
16 | |
17 | // Ensure that deduction works with lifetime qualifiers. |
18 | void 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 |
38 | void 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 | } |
44 | void 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 | } |
51 | void 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 | |
62 | void 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. |
72 | template<typename T, int N> |
73 | void 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 | |
79 | void testAutoIdTemplate(id obj) { |
80 | autoTemplateFunction<id, 2>(obj, obj, [Array new]); // no-warning |
81 | } |
82 | |
83 | // rdar://12229679 |
84 | @interface NSObject @end |
85 | typedef __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 | |
97 | namespace rdar12078752 { |
98 | void f() { |
99 | NSObject* o =0; |
100 | __autoreleasing decltype(o) o2 = o; |
101 | __autoreleasing auto o3 = o; |
102 | } |
103 | } |
104 | |
105 | namespace 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 | |
115 | namespace 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 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} 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 | |