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
9typedef const void * CFTypeRef;
10CFTypeRef CFBridgingRetain(id X);
11id CFBridgingRelease(CFTypeRef);
12
13typedef int BOOL;
14typedef 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
36typedef const struct __CFString * CFStringRef;
37extern const CFStringRef kUTTypePlainText;
38extern const CFStringRef kUTTypeRTF;
39@class NSString;
40@class A;
41
42struct 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
73id global_foo;
74
75void 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
118struct S {
119  A* a; // expected-error {{ARC forbids Objective-C objects in struct}}
120};
121
122@interface B
123-(id)alloc;
124- (id)initWithInt: (int) i;
125@end
126
127void 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
150void * 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
169void 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
179void 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
287id test9(Test9 *v) {
288  return [v init1];
289}
290
291// rdar://9491791
292void 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
306void 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
342void 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