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