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