1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s |
2 | // RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1 |
3 | |
4 | typedef unsigned long NSUInteger; |
5 | typedef const void * CFTypeRef; |
6 | CFTypeRef CFBridgingRetain(id X); |
7 | id CFBridgingRelease(CFTypeRef); |
8 | @protocol NSCopying @end |
9 | @interface NSDictionary |
10 | + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; |
11 | - (void)setObject:(id)object forKeyedSubscript:(id)key; |
12 | @end |
13 | @class NSFastEnumerationState; |
14 | @protocol NSFastEnumeration |
15 | - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len; |
16 | @end |
17 | @interface NSNumber |
18 | + (NSNumber *)numberWithInt:(int)value; |
19 | @end |
20 | @interface NSArray <NSFastEnumeration> |
21 | + (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; |
22 | @end |
23 | |
24 | void test0(void (*fn)(int), int val) { |
25 | fn(val); |
26 | } |
27 | |
28 | @interface A |
29 | - (id)retain; |
30 | - (id)autorelease; |
31 | - (oneway void)release; |
32 | - (void)dealloc; |
33 | - (NSUInteger)retainCount; |
34 | @end |
35 | |
36 | void test1(A *a) { |
37 | SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} |
38 | s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} |
39 | s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} |
40 | s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} |
41 | [a dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}} |
42 | [a retain]; // expected-error {{ARC forbids explicit message send of 'retain'}} |
43 | [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} |
44 | [a release]; // expected-error {{ARC forbids explicit message send of 'release'}} |
45 | [a autorelease]; // expected-error {{ARC forbids explicit message send of 'autorelease'}} |
46 | } |
47 | |
48 | @interface Test2 : A |
49 | - (void) dealloc; |
50 | @end |
51 | @implementation Test2 |
52 | - (void) dealloc { |
53 | // This should maybe just be ignored. We're just going to warn about it for now. |
54 | [super dealloc]; // expected-error {{ARC forbids explicit message send of 'dealloc'}} |
55 | } |
56 | @end |
57 | |
58 | // rdar://8843638 |
59 | |
60 | @interface I |
61 | - (id)retain; // expected-note {{method 'retain' declared here}} |
62 | - (id)autorelease; // expected-note {{method 'autorelease' declared here}} |
63 | - (oneway void)release; // expected-note {{method 'release' declared here}} |
64 | - (NSUInteger)retainCount; // expected-note {{method 'retainCount' declared here}} |
65 | @end |
66 | |
67 | @implementation I |
68 | - (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}} |
69 | - (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}} |
70 | - (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}} |
71 | - (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}} |
72 | @end |
73 | |
74 | @implementation I(CAT) |
75 | - (id)retain{return 0;} // expected-error {{ARC forbids implementation of 'retain'}} \ |
76 | // expected-warning {{category is implementing a method which will also be implemented by its primary class}} |
77 | - (id)autorelease{return 0;} // expected-error {{ARC forbids implementation of 'autorelease'}} \ |
78 | // expected-warning {{category is implementing a method which will also be implemented by its primary class}} |
79 | - (oneway void)release{} // expected-error {{ARC forbids implementation of 'release'}} \ |
80 | // expected-warning {{category is implementing a method which will also be implemented by its primary class}} |
81 | - (NSUInteger)retainCount{ return 0; } // expected-error {{ARC forbids implementation of 'retainCount'}} \ |
82 | // expected-warning {{category is implementing a method which will also be implemented by its primary class}} |
83 | @end |
84 | |
85 | // rdar://8861761 |
86 | |
87 | @interface B |
88 | + (id)alloc; |
89 | - (id)initWithInt: (int) i; |
90 | - (id)myInit __attribute__((objc_method_family(init))); |
91 | - (id)myBadInit __attribute__((objc_method_family(12))); // expected-error {{'objc_method_family' attribute requires parameter 1 to be an identifier}} |
92 | |
93 | @end |
94 | |
95 | void rdar8861761() { |
96 | B *o1 = [[B alloc] initWithInt:0]; |
97 | B *o2 = [B alloc]; |
98 | [o2 initWithInt:0]; // expected-warning {{expression result unused}} |
99 | B *o3 = [[B alloc] myInit]; |
100 | [[B alloc] myInit]; // expected-warning {{expression result unused}} |
101 | } |
102 | |
103 | // rdar://8925835 |
104 | @interface rdar8925835 |
105 | - (void)foo:(void (^)(unsigned captureCount, I * const capturedStrings[captureCount]))block; |
106 | @end |
107 | |
108 | void test5() { |
109 | extern void test5_helper(__autoreleasing id *); |
110 | id x; |
111 | |
112 | // Okay because of magic temporaries. |
113 | test5_helper(&x); |
114 | |
115 | __autoreleasing id *a = &x; // expected-error {{initializing '__autoreleasing id *' with an expression of type '__strong id *' changes retain/release properties of pointer}} |
116 | |
117 | a = &x; // expected-error {{assigning '__strong id *' to '__autoreleasing id *' changes retain/release properties of pointer}} |
118 | |
119 | extern void test5_helper2(id const *); |
120 | test5_helper2(&x); |
121 | |
122 | extern void test5_helper3(__weak id *); // expected-note {{passing argument to parameter here}} |
123 | test5_helper3(&x); // expected-error {{passing '__strong id *' to parameter of type '__weak id *' changes retain/release properties of pointer}} |
124 | } |
125 | |
126 | // rdar://problem/8937869 |
127 | void test6(unsigned cond) { |
128 | switch (cond) { |
129 | case 0: |
130 | ; |
131 | id x; // expected-note {{jump bypasses initialization of __strong variable}} |
132 | |
133 | case 1: // expected-error {{cannot jump}} |
134 | break; |
135 | } |
136 | } |
137 | void test6a(unsigned cond) { |
138 | switch (cond) { |
139 | case 0: |
140 | ; |
141 | __weak id x; // expected-note {{jump bypasses initialization of __weak variable}} |
142 | |
143 | case 1: // expected-error {{cannot jump}} |
144 | break; |
145 | } |
146 | } |
147 | |
148 | @class NSError; |
149 | void test7(void) { |
150 | extern void test7_helper(NSError **); |
151 | NSError *err; |
152 | test7_helper(&err); |
153 | } |
154 | void test7_weak(void) { |
155 | extern void test7_helper(NSError **); |
156 | __weak NSError *err; |
157 | test7_helper(&err); |
158 | } |
159 | void test7_unsafe(void) { |
160 | extern void test7_helper(NSError **); // expected-note {{passing argument to parameter here}} |
161 | __unsafe_unretained NSError *err; |
162 | test7_helper(&err); // expected-error {{passing 'NSError *__unsafe_unretained *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer}} |
163 | } |
164 | |
165 | @class Test8_incomplete; |
166 | @interface Test8_complete @end; |
167 | @interface Test8_super @end; |
168 | @interface Test8 : Test8_super |
169 | - (id) init00; |
170 | - (id) init01; // expected-note {{declaration in interface}} \ |
171 | // expected-note{{overridden method}} |
172 | - (id) init02; // expected-note{{overridden method}} |
173 | - (id) init03; // covariance |
174 | - (id) init04; // covariance |
175 | - (id) init05; // expected-note{{overridden method}} |
176 | |
177 | - (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
178 | - (void) init11; |
179 | - (void) init12; |
180 | - (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
181 | - (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
182 | - (void) init15; |
183 | |
184 | // These should be invalid to actually call. |
185 | - (Test8_incomplete*) init20; |
186 | - (Test8_incomplete*) init21; // expected-note {{declaration in interface}} |
187 | - (Test8_incomplete*) init22; |
188 | - (Test8_incomplete*) init23; |
189 | - (Test8_incomplete*) init24; |
190 | - (Test8_incomplete*) init25; |
191 | |
192 | - (Test8_super*) init30; // id exception to covariance |
193 | - (Test8_super*) init31; // expected-note {{declaration in interface}} \ |
194 | // expected-note{{overridden method}} |
195 | - (Test8_super*) init32; // expected-note{{overridden method}} |
196 | - (Test8_super*) init33; |
197 | - (Test8_super*) init34; // covariance |
198 | - (Test8_super*) init35; // expected-note{{overridden method}} |
199 | |
200 | - (Test8*) init40; // id exception to covariance |
201 | - (Test8*) init41; // expected-note {{declaration in interface}} \ |
202 | // expected-note{{overridden method}} |
203 | - (Test8*) init42; // expected-note{{overridden method}} |
204 | - (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing |
205 | - (Test8*) init44; |
206 | - (Test8*) init45; // expected-note{{overridden method}} |
207 | |
208 | - (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} |
209 | - (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} |
210 | - (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} |
211 | - (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} |
212 | - (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} |
213 | - (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} |
214 | @end |
215 | @implementation Test8 |
216 | - (id) init00 { return 0; } |
217 | - (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} |
218 | - (id) init20 { return 0; } |
219 | - (id) init30 { return 0; } |
220 | - (id) init40 { return 0; } |
221 | - (id) init50 { return 0; } |
222 | |
223 | - (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ |
224 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} |
225 | - (void) init11 {} |
226 | - (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} |
227 | - (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ |
228 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} |
229 | - (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} \ |
230 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'void'}} |
231 | - (void) init51 {} |
232 | |
233 | - (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
234 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} |
235 | - (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
236 | - (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
237 | - (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
238 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} |
239 | - (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
240 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_incomplete *'}} |
241 | - (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
242 | |
243 | - (Test8_super*) init03 { return 0; } |
244 | - (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} |
245 | - (Test8_super*) init23 { return 0; } |
246 | - (Test8_super*) init33 { return 0; } |
247 | - (Test8_super*) init43 { return 0; } |
248 | - (Test8_super*) init53 { return 0; } |
249 | |
250 | - (Test8*) init04 { return 0; } |
251 | - (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} |
252 | - (Test8*) init24 { return 0; } |
253 | - (Test8*) init34 { return 0; } |
254 | - (Test8*) init44 { return 0; } |
255 | - (Test8*) init54 { return 0; } |
256 | |
257 | - (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
258 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} |
259 | - (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
260 | - (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
261 | - (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
262 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} |
263 | - (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} \ |
264 | // expected-warning{{method is expected to return an instance of its class type 'Test8', but is declared to return 'Test8_complete *'}} |
265 | - (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
266 | @end |
267 | |
268 | @class Test9_incomplete; |
269 | @interface Test9 |
270 | - (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} |
271 | - (Test9_incomplete*) init2; |
272 | @end |
273 | id test9(Test9 *v) { |
274 | return [v init1]; |
275 | } |
276 | |
277 | // Test that the inference rules are different for fast enumeration variables. |
278 | void test10(id collection) { |
279 | for (id x in collection) { |
280 | __strong id *ptr = &x; // expected-warning {{initializing '__strong id *' with an expression of type 'const __strong id *' discards qualifiers}} |
281 | } |
282 | |
283 | for (__strong id x in collection) { |
284 | __weak id *ptr = &x; // expected-error {{initializing '__weak id *' with an expression of type '__strong id *' changes retain/release properties of pointer}} |
285 | } |
286 | } |
287 | |
288 | // rdar://problem/9078626 |
289 | #define nil ((void*) 0) |
290 | void test11(id op, void *vp) { |
291 | _Bool b; |
292 | b = (op == nil); |
293 | b = (nil == op); |
294 | |
295 | b = (vp == nil); |
296 | b = (nil == vp); |
297 | |
298 | b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} |
299 | b = (op == vp); |
300 | } |
301 | |
302 | void test12(id collection) { |
303 | for (id x in collection) { |
304 | x = 0; // expected-error {{fast enumeration variables cannot be modified in ARC by default; declare the variable __strong to allow this}} |
305 | } |
306 | |
307 | for (const id x in collection) { // expected-note {{variable 'x' declared const here}} |
308 | x = 0; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const __strong id'}} |
309 | } |
310 | |
311 | for (__strong id x in collection) { |
312 | x = 0; |
313 | } |
314 | } |
315 | |
316 | @interface Test13 |
317 | - (id) init0; |
318 | - (void) noninit; |
319 | @end |
320 | @implementation Test13 |
321 | - (id) init0 { |
322 | self = 0; |
323 | } |
324 | - (void) noninit { |
325 | self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} |
326 | } |
327 | @end |
328 | |
329 | // <rdar://problem/10274056> |
330 | @interface Test13_B |
331 | - (id) consumesSelf __attribute__((ns_consumes_self)); |
332 | @end |
333 | @implementation Test13_B |
334 | - (id) consumesSelf { |
335 | self = 0; // no-warning |
336 | } |
337 | @end |
338 | |
339 | // rdar://problem/9172151 |
340 | @class Test14A, Test14B; |
341 | void test14() { |
342 | extern void test14_consume(id *); |
343 | extern int test14_cond(void); |
344 | extern float test14_nowriteback(id __autoreleasing const *); // expected-note{{passing argument to parameter here}} |
345 | |
346 | Test14A *a; |
347 | Test14B *b; |
348 | id i; |
349 | id cla[10]; |
350 | id vla[test14_cond() + 10]; |
351 | |
352 | test14_consume((__strong id*) &a); |
353 | test14_consume((test14_cond() ? (__strong id*) &b : &i)); |
354 | test14_consume(test14_cond() ? 0 : &a); |
355 | test14_consume(test14_cond() ? (void*) 0 : (&a)); |
356 | test14_consume(cla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} |
357 | test14_consume(vla); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} |
358 | test14_consume(&cla[5]); // expected-error {{passing address of non-scalar object to __autoreleasing parameter for write-back}} |
359 | |
360 | __strong id *test14_indirect(void); |
361 | test14_consume(test14_indirect()); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} |
362 | |
363 | extern id test14_global; |
364 | test14_consume(&test14_global); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} |
365 | |
366 | extern __strong id *test14_global_ptr; |
367 | test14_consume(test14_global_ptr); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} |
368 | |
369 | static id static_local; |
370 | test14_consume(&static_local); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} |
371 | |
372 | __weak id* wip; |
373 | test14_nowriteback(&static_local); // okay, not a write-back. |
374 | test14_nowriteback(wip); // expected-error{{passing '__weak id *' to parameter of type '__autoreleasing id const *' changes retain/release properties of pointer}} |
375 | } |
376 | |
377 | void test15() { |
378 | __block __autoreleasing id x; // expected-error {{__block variables cannot have __autoreleasing ownership}} |
379 | } |
380 | |
381 | struct Test16; |
382 | @interface Test16a |
383 | - (void) test16_0: (int) x; |
384 | - (int) test16_1: (int) x; // expected-note {{one possibility}} |
385 | - (int) test16_2: (int) x; // expected-note {{one possibility}} |
386 | - (id) test16_3: (int) x __attribute__((ns_returns_retained)); // expected-note {{one possibility}} |
387 | - (void) test16_4: (int) x __attribute__((ns_consumes_self)); // expected-note {{one possibility}} |
388 | - (void) test16_5: (id) __attribute__((ns_consumed)) x; // expected-note {{one possibility}} |
389 | - (void) test16_6: (id) x; |
390 | @end |
391 | |
392 | @interface Test16b |
393 | - (void) test16_0: (int) x; |
394 | - (int) test16_1: (char*) x; // expected-note {{also found}} |
395 | - (char*) test16_2: (int) x; // expected-note {{also found}} |
396 | - (id) test16_3: (int) x; // expected-note {{also found}} |
397 | - (void) test16_4: (int) x; // expected-note {{also found}} |
398 | - (void) test16_5: (id) x; // expected-note {{also found}} |
399 | - (void) test16_6: (struct Test16 *) x; |
400 | @end |
401 | |
402 | void test16(void) { |
403 | id v; |
404 | [v test16_0: 0]; |
405 | [v test16_1: 0]; // expected-error {{multiple methods named 'test16_1:' found with mismatched result, parameter type or attributes}} |
406 | [v test16_2: 0]; // expected-error {{multiple methods named}} |
407 | [v test16_3: 0]; // expected-error {{multiple methods named}} |
408 | [v test16_4: 0]; // expected-error {{multiple methods named}} |
409 | [v test16_5: 0]; // expected-error {{multiple methods named}} |
410 | [v test16_6: 0]; |
411 | } |
412 | |
413 | @class Test17; // expected-note 3{{forward declaration of class here}} |
414 | @protocol Test17p |
415 | - (void) test17; |
416 | + (void) test17; |
417 | @end |
418 | void test17(void) { |
419 | Test17 *v0; |
420 | [v0 test17]; // expected-error {{receiver type 'Test17' for instance message is a forward declaration}} |
421 | |
422 | Test17<Test17p> *v1; |
423 | [v1 test17]; // expected-error {{receiver type 'Test17<Test17p>' for instance message is a forward declaration}} |
424 | |
425 | [Test17 test17]; // expected-error {{receiver 'Test17' for class message is a forward declaration}} |
426 | } |
427 | |
428 | void test18(void) { |
429 | id x; |
430 | [x test18]; // expected-error {{instance method 'test18' not found ; did you mean 'test17'?}} |
431 | } |
432 | |
433 | extern struct Test19 *test19a; |
434 | struct Test19 *const test19b = 0; |
435 | void test19(void) { |
436 | id x; |
437 | x = (id) test19a; // expected-error {{bridged cast}} \ |
438 | // expected-note{{use __bridge to convert directly (no change in ownership)}} \ |
439 | // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}} |
440 | x = (id) test19b; // expected-error {{bridged cast}} \ |
441 | // expected-note{{use __bridge to convert directly (no change in ownership)}} \ |
442 | // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'struct Test19 *' into ARC}} |
443 | } |
444 | |
445 | // rdar://problem/8951453 |
446 | static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} |
447 | static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} |
448 | static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}} |
449 | static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}} |
450 | static __thread __unsafe_unretained id test20_unsafe; |
451 | void test20(void) { |
452 | static __thread id test20_implicit; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} |
453 | static __thread __strong id test20_strong; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}} |
454 | static __thread __weak id test20_weak; // expected-error {{thread-local variable has non-trivial ownership: type is '__weak id'}} |
455 | static __thread __autoreleasing id test20_autoreleasing; // expected-error {{thread-local variable has non-trivial ownership: type is '__autoreleasing id'}} expected-error {{global variables cannot have __autoreleasing ownership}} |
456 | static __thread __unsafe_unretained id test20_unsafe; |
457 | } |
458 | |
459 | // rdar://9310049 |
460 | _Bool fn(id obj) { |
461 | return (_Bool)obj; |
462 | } |
463 | |
464 | // Check casting w/ ownership qualifiers. |
465 | void test21() { |
466 | __strong id *sip; |
467 | (void)(__weak id *)sip; // expected-error{{casting '__strong id *' to type '__weak id *' changes retain/release properties of pointer}} |
468 | (void)(__weak const id *)sip; // expected-error{{casting '__strong id *' to type '__weak id const *' changes retain/release properties of pointer}} |
469 | (void)(__autoreleasing id *)sip; // expected-error{{casting '__strong id *' to type '__autoreleasing id *' changes retain/release properties of pointer}} |
470 | (void)(__autoreleasing const id *)sip; // okay |
471 | } |
472 | |
473 | // rdar://problem/9340462 |
474 | void test22(id x[]) { // expected-error {{must explicitly describe intended ownership of an object array parameter}} |
475 | } |
476 | |
477 | // rdar://problem/9400219 |
478 | void test23(void) { |
479 | void *ptr; |
480 | ptr = @"foo"; |
481 | ptr = (ptr ? @"foo" : 0); |
482 | ptr = (ptr ? @"foo" : @"bar"); |
483 | } |
484 | |
485 | id test24(void) { |
486 | extern void test24_helper(void); |
487 | return test24_helper(), (void*) 0; |
488 | } |
489 | |
490 | // rdar://9400841 |
491 | @interface Base |
492 | @property (assign) id content; |
493 | @end |
494 | |
495 | @interface Foo : Base |
496 | -(void)test; |
497 | @end |
498 | |
499 | @implementation Foo |
500 | -(void)test { |
501 | super.content = 0; |
502 | } |
503 | @end |
504 | |
505 | // <rdar://problem/9398437> |
506 | void test25(Class *classes) { |
507 | Class *other_classes; |
508 | test25(other_classes); |
509 | } |
510 | |
511 | void test26(id y) { |
512 | extern id test26_var1; |
513 | __sync_swap(&test26_var1, 0, y); // expected-error {{cannot perform atomic operation on a pointer to type '__strong id': type has non-trivial ownership}} |
514 | |
515 | extern __unsafe_unretained id test26_var2; |
516 | __sync_swap(&test26_var2, 0, y); |
517 | } |
518 | |
519 | @interface Test26 |
520 | - (id) init; |
521 | - (id) initWithInt: (int) x; |
522 | @end |
523 | @implementation Test26 |
524 | - (id) init { return self; } |
525 | - (id) initWithInt: (int) x { |
526 | [self init]; // expected-error {{the result of a delegate init call must be immediately returned or assigned to 'self'}} |
527 | return self; |
528 | } |
529 | @end |
530 | |
531 | // rdar://9525555 |
532 | @interface Test27 { |
533 | __weak id _myProp1; |
534 | id myProp2; |
535 | } |
536 | @property id x; |
537 | @property (readonly) id ro; |
538 | @property (readonly) id custom_ro; |
539 | @property int y; |
540 | |
541 | @property (readonly) __weak id myProp1; |
542 | @property (readonly) id myProp2; |
543 | @property (readonly) __strong id myProp3; |
544 | @end |
545 | |
546 | @implementation Test27 |
547 | @synthesize x; |
548 | @synthesize ro; |
549 | @synthesize y; |
550 | |
551 | @synthesize myProp1 = _myProp1; |
552 | @synthesize myProp2; |
553 | @synthesize myProp3; |
554 | |
555 | -(id)custom_ro { return 0; } |
556 | @end |
557 | |
558 | // rdar://9569264 |
559 | @interface Test28 |
560 | @property (nonatomic, assign) __strong id a; // expected-error {{unsafe_unretained property 'a' may not also be declared __strong}} |
561 | @end |
562 | |
563 | @interface Test28 () |
564 | @property (nonatomic, assign) __strong id b; // expected-error {{unsafe_unretained property 'b' may not also be declared __strong}} |
565 | @end |
566 | |
567 | @implementation Test28 |
568 | @synthesize a; |
569 | @synthesize b; |
570 | @end |
571 | |
572 | // rdar://9573962 |
573 | typedef struct Bark Bark; |
574 | @interface Test29 |
575 | @property Bark* P; |
576 | @end |
577 | |
578 | @implementation Test29 |
579 | @synthesize P; |
580 | - (id)Meth { |
581 | Bark** f = &P; |
582 | return 0; |
583 | } |
584 | @end |
585 | |
586 | // rdar://9495837 |
587 | @interface Test30 |
588 | + (id) new; |
589 | - (void)Meth; |
590 | @end |
591 | |
592 | @implementation Test30 |
593 | + (id) new { return 0; } |
594 | - (void) Meth { |
595 | __weak id x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}} |
596 | id __unsafe_unretained u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}} |
597 | id y = [Test30 new]; |
598 | x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}} |
599 | u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}} |
600 | y = [Test30 new]; |
601 | } |
602 | @end |
603 | |
604 | // rdar://9411838 |
605 | @protocol PTest31 @end |
606 | |
607 | int Test31() { |
608 | Class cls; |
609 | id ids; |
610 | id<PTest31> pids; |
611 | Class<PTest31> pcls; |
612 | |
613 | int i = (ids->isa ? 1 : 0); // expected-error {{member reference base type 'id' is not a structure or union}} |
614 | int j = (pids->isa ? 1 : 0); // expected-error {{member reference base type 'id<PTest31>' is not a structure or union}} |
615 | int k = (pcls->isa ? i : j); // expected-error {{member reference base type 'Class<PTest31>' is not a structure or union}} |
616 | return cls->isa ? i : j; // expected-error {{member reference base type 'Class' is not a structure or union}} |
617 | } |
618 | |
619 | // rdar://9612030 |
620 | @interface ITest32 { |
621 | @public |
622 | id ivar; |
623 | } |
624 | @end |
625 | |
626 | id Test32(__weak ITest32 *x) { |
627 | __weak ITest32 *y; |
628 | x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}} |
629 | return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}} |
630 | : (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}} |
631 | } |
632 | |
633 | // rdar://9619861 |
634 | extern int printf(const char*, ...); |
635 | typedef long intptr_t; |
636 | |
637 | int Test33(id someid) { |
638 | printf( "Hello%ld", (intptr_t)someid); |
639 | return (int)someid; |
640 | } |
641 | |
642 | // rdar://9636091 |
643 | @interface I34 |
644 | @property (nonatomic, retain) id newName __attribute__((ns_returns_not_retained)) ; |
645 | |
646 | @property (nonatomic, retain) id newName1 __attribute__((ns_returns_not_retained)) ; |
647 | - (id) newName1 __attribute__((ns_returns_not_retained)); |
648 | |
649 | @property (nonatomic, retain) id newName2 __attribute__((ns_returns_not_retained)); // expected-note {{roperty declared here}} |
650 | - (id) newName2; // expected-warning {{property declared as returning non-retained objects; getter returning retained objects}} |
651 | @end |
652 | |
653 | @implementation I34 |
654 | @synthesize newName; |
655 | |
656 | @synthesize newName1; |
657 | - (id) newName1 { return 0; } |
658 | |
659 | @synthesize newName2; |
660 | @end |
661 | |
662 | void test35(void) { |
663 | extern void test36_helper(id*); |
664 | id x; |
665 | __strong id *xp = 0; |
666 | |
667 | test36_helper(&x); |
668 | test36_helper(xp); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}} |
669 | |
670 | // rdar://problem/9665710 |
671 | __block id y; |
672 | test36_helper(&y); |
673 | ^{ test36_helper(&y); }(); |
674 | |
675 | __strong int non_objc_type; // expected-warning {{'__strong' only applies to Objective-C object or block pointer types}} |
676 | } |
677 | |
678 | void test36(int first, ...) { |
679 | // <rdar://problem/9758798> |
680 | __builtin_va_list arglist; |
681 | __builtin_va_start(arglist, first); |
682 | id obj = __builtin_va_arg(arglist, id); |
683 | __builtin_va_end(arglist); |
684 | } |
685 | |
686 | @class Test37; // expected-note{{forward declaration of class here}} |
687 | void test37(Test37 *c) { |
688 | for (id y in c) { // expected-error {{collection expression type 'Test37' is a forward declaration}} |
689 | (void) y; |
690 | } |
691 | |
692 | (void)sizeof(id*); // no error. |
693 | } |
694 | |
695 | // rdar://problem/9887979 |
696 | @interface Test38 |
697 | @property int value; |
698 | @end |
699 | void test38() { |
700 | extern Test38 *test38_helper(void); |
701 | switch (test38_helper().value) { |
702 | case 0: |
703 | case 1: |
704 | ; |
705 | } |
706 | } |
707 | |
708 | // rdar://10186536 |
709 | @class NSColor; |
710 | void _NSCalc(NSColor* color, NSColor* bezelColors[]) __attribute__((unavailable("not available in automatic reference counting mode"))); |
711 | |
712 | void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{must explicitly describe intended ownership of an object array parameter}} |
713 | |
714 | // rdar://9970739 |
715 | @interface RestaurantTableViewCell |
716 | - (void) restaurantLocation; |
717 | @end |
718 | |
719 | @interface Radar9970739 |
720 | - (void) Meth; |
721 | @end |
722 | |
723 | @implementation Radar9970739 |
724 | - (void) Meth { |
725 | RestaurantTableViewCell *cell; |
726 | [cell restaurantLocatoin]; // expected-error {{no visible @interface for 'RestaurantTableViewCell' declares the selector 'restaurantLocatoin'}} |
727 | } |
728 | @end |
729 | |
730 | // rdar://11814185 |
731 | @interface Radar11814185 |
732 | @property (nonatomic, weak) Radar11814185* picker1; |
733 | + alloc; |
734 | - init; |
735 | @end |
736 | |
737 | @implementation Radar11814185 |
738 | |
739 | @synthesize picker1; |
740 | |
741 | - (void)viewDidLoad |
742 | { |
743 | picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak variable; object will be released after assignment}} |
744 | self.picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak property; object will be released after assignment}} |
745 | } |
746 | |
747 | + alloc { return 0; } |
748 | - init { return 0; } |
749 | @end |
750 | |
751 | // <rdar://problem/12569201>. Warn on cases of initializing a weak variable |
752 | // with an Objective-C object literal. |
753 | void rdar12569201(id key, id value) { |
754 | // Declarations. |
755 | __weak id x = @"foo"; // no-warning |
756 | __weak id y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}} |
757 | __weak id z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}} |
758 | __weak id b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}} |
759 | __weak id n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} |
760 | __weak id e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} |
761 | __weak id m = @(41 + 1); // expected-warning {{assigning boxed expression to a weak variable; object will be released after assignment}} |
762 | |
763 | // Assignments. |
764 | y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}} |
765 | z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}} |
766 | b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}} |
767 | n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} |
768 | e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} |
769 | m = @(41 + 1); // expected-warning {{assigning boxed expression to a weak variable; object will be released after assignment}} |
770 | } |
771 | |
772 | @interface C |
773 | - (void)method:(id[])objects; // expected-error{{must explicitly describe intended ownership of an object array parameter}} |
774 | @end |
775 | |
776 | // rdar://13752880 |
777 | @interface NSMutableArray : NSArray @end |
778 | |
779 | typedef __strong NSMutableArray * PSNS; |
780 | |
781 | void test(NSArray *x) { |
782 | NSMutableArray *y = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} |
783 | __strong NSMutableArray *y1 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} |
784 | PSNS y2 = x; // expected-warning {{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} |
785 | } |
786 | |
787 | // rdar://15123684 |
788 | @class NSString; |
789 | |
790 | void foo(NSArray *array) { |
791 | for (NSString *string in array) { |
792 | for (string in @[@"blah", @"more blah", string]) { // expected-error {{selector element of type 'NSString *const __strong' cannot be a constant l-value}} |
793 | } |
794 | } |
795 | } |
796 | |
797 | // rdar://16627903 |
798 | extern void abort(); |
799 | #define TKAssertEqual(a, b) do{\ |
800 | __typeof(a) a_res = (a);\ |
801 | __typeof(b) b_res = (b);\ |
802 | if ((a_res) != (b_res)) {\ |
803 | abort();\ |
804 | }\ |
805 | }while(0) |
806 | |
807 | int garf() { |
808 | id object; |
809 | TKAssertEqual(object, nil); |
810 | TKAssertEqual(object, (id)nil); |
811 | } |
812 | |
813 | void block_capture_autoreleasing(A * __autoreleasing *a, |
814 | A **b, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
815 | A * _Nullable *c, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
816 | A * _Nullable __autoreleasing *d, |
817 | A ** _Nullable e, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
818 | A * __autoreleasing * _Nullable f, |
819 | id __autoreleasing *g, |
820 | id *h, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
821 | id _Nullable *i, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
822 | id _Nullable __autoreleasing *j, |
823 | id * _Nullable k, // expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} |
824 | id __autoreleasing * _Nullable l) { |
825 | ^{ |
826 | (void)*a; |
827 | (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
828 | (void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
829 | (void)*d; |
830 | (void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
831 | (void)*f; |
832 | (void)*g; |
833 | (void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
834 | (void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
835 | (void)*j; |
836 | (void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} |
837 | (void)*l; |
838 | }(); |
839 | } |
840 | |