1 | // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s |
2 | |
3 | #if __has_feature(objc_arc) |
4 | #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) |
5 | #else |
6 | #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE |
7 | #endif |
8 | |
9 | typedef const void * CFTypeRef; |
10 | CFTypeRef CFBridgingRetain(id X); |
11 | id CFBridgingRelease(CFTypeRef); |
12 | |
13 | typedef int BOOL; |
14 | typedef unsigned NSUInteger; |
15 | |
16 | @protocol NSObject |
17 | - (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; |
18 | - (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; |
19 | - (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; |
20 | - (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; |
21 | @end |
22 | |
23 | @interface NSObject <NSObject> {} |
24 | - (id)init; |
25 | |
26 | + (id)new; |
27 | + (id)alloc; |
28 | - (void)dealloc; |
29 | |
30 | - (void)finalize; |
31 | |
32 | - (id)copy; |
33 | - (id)mutableCopy; |
34 | @end |
35 | |
36 | typedef const struct __CFString * CFStringRef; |
37 | extern const CFStringRef kUTTypePlainText; |
38 | extern const CFStringRef kUTTypeRTF; |
39 | @class NSString; |
40 | @class A; |
41 | |
42 | struct UnsafeS { |
43 | A *__unsafe_unretained unsafeObj; |
44 | }; |
45 | |
46 | @interface A : NSObject |
47 | - (id)retain __attribute__((unavailable)); // expected-note {{'retain' has been explicitly marked unavailable here}} |
48 | - (id)retainCount __attribute__((unavailable)); // expected-note {{'retainCount' has been explicitly marked unavailable here}} |
49 | - (id)autorelease __attribute__((unavailable)); // expected-note 2 {{'autorelease' has been explicitly marked unavailable here}} |
50 | - (id)init; |
51 | - (oneway void)release; |
52 | - (void)dealloc; |
53 | -(void)test; |
54 | -(id)delegate; |
55 | @end |
56 | |
57 | @implementation A |
58 | -(void)test { |
59 | [super dealloc]; |
60 | } |
61 | -(void)dealloc { |
62 | [super dealloc]; |
63 | } |
64 | |
65 | - (id)retain { return self; } // expected-error {{ARC forbids implementation}} |
66 | - (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} |
67 | - (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} |
68 | - (oneway void)release { } // expected-error {{ARC forbids implementation}} |
69 | |
70 | -(id)delegate { return self; } |
71 | @end |
72 | |
73 | id global_foo; |
74 | |
75 | void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { |
76 | [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ |
77 | // expected-error {{ARC forbids explicit message send}} |
78 | [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ |
79 | // expected-error {{ARC forbids explicit message send}} |
80 | [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \ |
81 | // expected-error {{ARC forbids explicit message send}} \ |
82 | // expected-error {{'retain' is unavailable}} |
83 | id foo = [unsafeS->unsafeObj retain]; // no warning. |
84 | [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \ |
85 | // expected-error {{ARC forbids explicit message send}} |
86 | [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \ |
87 | // expected-error {{ARC forbids explicit message send}} |
88 | [a dealloc]; |
89 | [a retain]; |
90 | [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} \ |
91 | // expected-error {{'retainCount' is unavailable}} |
92 | [a release]; |
93 | [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ |
94 | // expected-error {{ARC forbids explicit message send}} \ |
95 | // expected-error {{'autorelease' is unavailable}} |
96 | [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ |
97 | // expected-error {{ARC forbids explicit message send}} \ |
98 | // expected-error {{'autorelease' is unavailable}} |
99 | a = 0; |
100 | |
101 | CFStringRef cfstr; |
102 | NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ |
103 | // expected-note {{use __bridge to convert directly (no change in ownership)}} \ |
104 | // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} \ |
105 | str = (NSString *)kUTTypePlainText; |
106 | str = b ? kUTTypeRTF : kUTTypePlainText; |
107 | str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); |
108 | str = (NSString *)a; // no change. |
109 | |
110 | SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} |
111 | s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} |
112 | s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} |
113 | s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} |
114 | |
115 | static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} |
116 | } |
117 | |
118 | struct S { |
119 | A* a; |
120 | }; |
121 | |
122 | @interface B |
123 | -(id)alloc; |
124 | - (id)initWithInt: (int) i; |
125 | @end |
126 | |
127 | void rdar8861761() { |
128 | B *o1 = [[B alloc] initWithInt:0]; |
129 | B *o2 = [B alloc]; |
130 | [o2 initWithInt:0]; |
131 | } |
132 | |
133 | @interface Test13 |
134 | - (id) init0; |
135 | - (void) noninit; |
136 | @end |
137 | @implementation Test13 |
138 | - (id) init0 { |
139 | self = 0; |
140 | } |
141 | - (void) noninit { |
142 | self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} |
143 | |
144 | for (__strong id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} |
145 | x = 0; |
146 | } |
147 | } |
148 | @end |
149 | |
150 | void * cvt(id arg) |
151 | { |
152 | void* voidp_val; |
153 | (void)(int*)arg; // expected-error {{disallowed}} |
154 | (void)(id)arg; |
155 | (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} |
156 | (void)(id*)arg; // expected-error {{disallowed}} |
157 | |
158 | (void)(__autoreleasing id**)voidp_val; |
159 | (void)(void*)voidp_val; |
160 | (void)(void**)arg; // expected-error {{disallowed}} |
161 | cvt((void*)arg); // expected-error 2 {{requires a bridged cast}} \ |
162 | // expected-note 2 {{use __bridge to}} expected-note {{use CFBridgingRelease call}} expected-note {{use CFBridgingRetain call}} |
163 | cvt(0); |
164 | (void)(__strong id**)(0); |
165 | return arg; // expected-error {{requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} |
166 | } |
167 | |
168 | |
169 | void test12(id collection) { |
170 | for (id x in collection) { |
171 | x = 0; |
172 | } |
173 | |
174 | for (__strong id x in collection) { |
175 | x = 0; |
176 | } |
177 | } |
178 | |
179 | void test6(unsigned cond) { |
180 | switch (cond) { |
181 | case 0: |
182 | ; |
183 | id x; // expected-note {{jump bypasses initialization of __strong variable}} |
184 | |
185 | case 1: // expected-error {{cannot jump}} |
186 | x = 0; |
187 | break; |
188 | } |
189 | } |
190 | |
191 | @class Test8_incomplete; |
192 | @interface Test8_complete @end; |
193 | @interface Test8_super @end; |
194 | @interface Test8 : Test8_super |
195 | - (id) init00; |
196 | - (id) init01; // expected-note {{declaration in interface}} |
197 | - (id) init02; |
198 | - (id) init03; // covariance |
199 | - (id) init04; // covariance |
200 | - (id) init05; |
201 | |
202 | - (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
203 | - (void) init11; |
204 | - (void) init12; |
205 | - (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
206 | - (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} |
207 | - (void) init15; |
208 | |
209 | // These should be invalid to actually call. |
210 | - (Test8_incomplete*) init20; |
211 | - (Test8_incomplete*) init21; // expected-note {{declaration in interface}} |
212 | - (Test8_incomplete*) init22; |
213 | - (Test8_incomplete*) init23; |
214 | - (Test8_incomplete*) init24; |
215 | - (Test8_incomplete*) init25; |
216 | |
217 | - (Test8_super*) init30; // id exception to covariance |
218 | - (Test8_super*) init31; // expected-note {{declaration in interface}} |
219 | - (Test8_super*) init32; |
220 | - (Test8_super*) init33; |
221 | - (Test8_super*) init34; // covariance |
222 | - (Test8_super*) init35; |
223 | |
224 | - (Test8*) init40; // id exception to covariance |
225 | - (Test8*) init41; // expected-note {{declaration in interface}} |
226 | - (Test8*) init42; |
227 | - (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing |
228 | - (Test8*) init44; |
229 | - (Test8*) init45; |
230 | |
231 | - (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} |
232 | - (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} |
233 | - (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} |
234 | - (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} |
235 | - (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} |
236 | - (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} |
237 | @end |
238 | @implementation Test8 |
239 | - (id) init00 { return 0; } |
240 | - (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} |
241 | - (id) init20 { return 0; } |
242 | - (id) init30 { return 0; } |
243 | - (id) init40 { return 0; } |
244 | - (id) init50 { return 0; } |
245 | |
246 | - (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}} |
247 | - (void) init11 {} |
248 | - (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}} |
249 | - (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}} |
250 | - (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}} |
251 | - (void) init51 {} |
252 | |
253 | - (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
254 | - (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
255 | - (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
256 | - (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
257 | - (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
258 | - (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
259 | |
260 | - (Test8_super*) init03 { return 0; } |
261 | - (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} |
262 | - (Test8_super*) init23 { return 0; } |
263 | - (Test8_super*) init33 { return 0; } |
264 | - (Test8_super*) init43 { return 0; } |
265 | - (Test8_super*) init53 { return 0; } |
266 | |
267 | - (Test8*) init04 { return 0; } |
268 | - (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} |
269 | - (Test8*) init24 { return 0; } |
270 | - (Test8*) init34 { return 0; } |
271 | - (Test8*) init44 { return 0; } |
272 | - (Test8*) init54 { return 0; } |
273 | |
274 | - (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
275 | - (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
276 | - (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
277 | - (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
278 | - (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
279 | - (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} |
280 | @end |
281 | |
282 | @class Test9_incomplete; |
283 | @interface Test9 |
284 | - (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} |
285 | - (Test9_incomplete*) init2; |
286 | @end |
287 | id test9(Test9 *v) { |
288 | return [v init1]; |
289 | } |
290 | |
291 | // rdar://9491791 |
292 | void rdar9491791(int p) { |
293 | switch (p) { |
294 | case 3:; |
295 | NSObject *o = [[NSObject alloc] init]; |
296 | [o release]; |
297 | break; |
298 | default: |
299 | break; |
300 | } |
301 | } |
302 | |
303 | #define RELEASE_MACRO(x) do { [x release]; } while(1) |
304 | |
305 | // rdar://9504750 |
306 | void rdar9504750(id p) { |
307 | RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} |
308 | } |
309 | |
310 | // rdar://8939557 |
311 | @interface TestReadonlyProperty : NSObject |
312 | @property(assign,readonly) NSObject *value; |
313 | @end |
314 | |
315 | @implementation TestReadonlyProperty |
316 | @synthesize value; |
317 | - (void)viewDidLoad { |
318 | value = [NSObject new]; // expected-error {{assigning retained object}} |
319 | } |
320 | @end |
321 | |
322 | // rdar://9601437 |
323 | @interface I9601437 { |
324 | __unsafe_unretained id x; |
325 | } |
326 | -(void)Meth; |
327 | @end |
328 | |
329 | @implementation I9601437 |
330 | -(void)Meth { |
331 | self->x = [NSObject new]; // expected-error {{assigning retained object}} |
332 | } |
333 | @end |
334 | |
335 | @interface Test10 : NSObject { |
336 | CFStringRef cfstr; |
337 | } |
338 | @property (retain) id prop; |
339 | -(void)foo; |
340 | @end |
341 | |
342 | void test(Test10 *x) { |
343 | x.prop = ^{ [x foo]; }; // expected-warning {{likely to lead to a retain cycle}} \ |
344 | // expected-note {{retained by the captured object}} |
345 | } |
346 | |
347 | @implementation Test10 |
348 | -(void)foo { |
349 | ^{ |
350 | NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ |
351 | // expected-note {{use __bridge to convert directly (no change in ownership)}} \ |
352 | // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} |
353 | }; |
354 | } |
355 | @end |
356 | |