Home | History | Annotate | Download | only in inlining
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
      2 
      3 typedef signed char BOOL;
      4 typedef struct objc_class *Class;
      5 typedef struct objc_object {
      6     Class isa;
      7 } *id;
      8 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
      9 @interface NSObject <NSObject> {}
     10 +(id)alloc;
     11 +(id)new;
     12 - (oneway void)release;
     13 -(id)init;
     14 -(id)autorelease;
     15 -(id)copy;
     16 - (Class)class;
     17 -(id)retain;
     18 - (oneway void)release;
     19 @end
     20 
     21 @interface SelfStaysLive : NSObject
     22 - (id)init;
     23 @end
     24 
     25 @implementation SelfStaysLive
     26 - (id)init {
     27   return [super init];
     28 }
     29 @end
     30 
     31 void selfStaysLive() {
     32     SelfStaysLive *foo = [[SelfStaysLive alloc] init]; 
     33     [foo release];
     34 }
     35 
     36 // Test that retain release checker warns on leaks and use-after-frees when 
     37 // self init is not enabled.  
     38 // radar://12115830
     39 @interface ParentOfCell : NSObject
     40 - (id)initWithInt: (int)inInt;
     41 @end
     42 @interface Cell : ParentOfCell{
     43   int x;
     44 }
     45 - (id)initWithInt: (int)inInt;
     46 + (void)testOverRelease;
     47 + (void)testLeak;
     48 @property int x;
     49 @end
     50 @implementation Cell
     51 @synthesize x;
     52 - (id) initWithInt: (int)inInt {
     53   [super initWithInt: inInt];
     54   self.x = inInt; // no-warning 
     55   return self; // Self Init checker would produce a warning here.
     56 }
     57 + (void) testOverRelease {
     58   Cell *sharedCell3 = [[Cell alloc] initWithInt: 3];
     59   [sharedCell3 release];
     60   [sharedCell3 release]; // expected-warning {{Reference-counted object is used after it is released}}
     61 }
     62 + (void) testLeak {
     63   Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}}
     64 }
     65 @end
     66   
     67 // We should stop tracking some objects even when we inline the call. 
     68 // Specialically, the objects passed into calls with delegate and callback 
     69 // parameters.
     70 @class DelegateTest;
     71 typedef void (*ReleaseCallbackTy) (DelegateTest *c);
     72 
     73 @interface Delegate : NSObject
     74 @end
     75 
     76 @interface DelegateTest : NSObject {
     77   Delegate *myDel;
     78 }
     79 // Object initialized with a delagate which could potentially release it.
     80 - (id)initWithDelegate: (id) d;
     81 
     82 - (void) setDelegate: (id) d;
     83 
     84 // Releases object through callback.
     85 + (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc;
     86 
     87 + (void)test: (Delegate *)d;
     88 
     89 @property (assign) Delegate* myDel;
     90 @end
     91 
     92 void releaseObj(DelegateTest *c);
     93 
     94 // Releases object through callback.
     95 void updateObject(DelegateTest *c, ReleaseCallbackTy rel) {
     96   rel(c);
     97 }
     98 
     99 @implementation DelegateTest
    100 @synthesize myDel;
    101 
    102 - (id) initWithDelegate: (id) d {
    103     if ((self = [super init]))
    104       myDel = d;
    105     return self;
    106 }
    107 
    108 - (void) setDelegate: (id) d {
    109     myDel = d;
    110 }
    111 
    112 + (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc {
    113   rc(obj);
    114 }
    115 
    116 + (void) test: (Delegate *)d {
    117   DelegateTest *obj1 = [[DelegateTest alloc] initWithDelegate: d]; // no-warning
    118   DelegateTest *obj2 = [[DelegateTest alloc] init]; // no-warning
    119   DelegateTest *obj3 = [[DelegateTest alloc] init]; // no-warning
    120   updateObject(obj2, releaseObj);
    121   [DelegateTest updateObject: obj3
    122         WithCallback: releaseObj];
    123   DelegateTest *obj4 = [[DelegateTest alloc] init]; // no-warning
    124   [obj4 setDelegate: d];
    125 }
    126 @end
    127 
    128