1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
3 typedef signed char BOOL;
4 typedef struct objc_class *Class;
5 typedef struct objc_object {
8 @protocol NSObject - (BOOL)isEqual:(id)object; @end
9 @interface NSObject <NSObject> {}
12 - (oneway void)release;
18 - (oneway void)release;
21 @interface SelfStaysLive : NSObject
25 @implementation SelfStaysLive
31 void selfStaysLive(void) {
32 SelfStaysLive *foo = [[SelfStaysLive alloc] init];
36 // Test that retain release checker warns on leaks and use-after-frees when
37 // self init is not enabled.
38 @interface ParentOfCell : NSObject
39 - (id)initWithInt: (int)inInt;
41 @interface Cell : ParentOfCell{
44 - (id)initWithInt: (int)inInt;
45 + (void)testOverRelease;
51 - (id) initWithInt: (int)inInt {
52 [super initWithInt: inInt];
53 self.x = inInt; // no-warning
54 return self; // Self Init checker would produce a warning here.
56 + (void) testOverRelease {
57 Cell *sharedCell3 = [[Cell alloc] initWithInt: 3];
58 [sharedCell3 release];
59 [sharedCell3 release]; // expected-warning {{Reference-counted object is used after it is released}}
62 Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}}
66 // We should stop tracking some objects even when we inline the call.
67 // Specialically, the objects passed into calls with delegate and callback
70 typedef void (*ReleaseCallbackTy) (DelegateTest *c);
72 @interface Delegate : NSObject
75 @interface DelegateTest : NSObject {
78 // Object initialized with a delagate which could potentially release it.
79 - (id)initWithDelegate: (id) d;
81 - (void) setDelegate: (id) d;
83 // Releases object through callback.
84 + (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc;
86 + (void)test: (Delegate *)d;
88 @property (assign) Delegate* myDel;
91 void releaseObj(DelegateTest *c);
93 // Releases object through callback.
94 void updateObject(DelegateTest *c, ReleaseCallbackTy rel) {
98 @implementation DelegateTest
101 - (id) initWithDelegate: (id) d {
102 if ((self = [super init]))
107 - (void) setDelegate: (id) d {
111 + (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc {
115 + (void) test: (Delegate *)d {
116 DelegateTest *obj1 = [[DelegateTest alloc] initWithDelegate: d]; // no-warning
117 DelegateTest *obj2 = [[DelegateTest alloc] init]; // no-warning
118 DelegateTest *obj3 = [[DelegateTest alloc] init]; // no-warning
119 updateObject(obj2, releaseObj);
120 [DelegateTest updateObject: obj3
121 WithCallback: releaseObj];
122 DelegateTest *obj4 = [[DelegateTest alloc] init]; // no-warning
123 [obj4 setDelegate: d];