// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s

typedef signed char BOOL;
typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;
@protocol NSObject  - (BOOL)isEqual:(id)object; @end
@interface NSObject <NSObject> {}
+(id)alloc;
+(id)new;
- (oneway void)release;
-(id)init;
-(id)autorelease;
-(id)copy;
- (Class)class;
-(id)retain;
- (oneway void)release;
@end

@interface SelfStaysLive : NSObject
- (id)init;
@end

@implementation SelfStaysLive
- (id)init {
  return [super init];
}
@end

void selfStaysLive() {
    SelfStaysLive *foo = [[SelfStaysLive alloc] init]; 
    [foo release];
}

// Test that retain release checker warns on leaks and use-after-frees when 
// self init is not enabled.  
// radar://12115830
@interface ParentOfCell : NSObject
- (id)initWithInt: (int)inInt;
@end
@interface Cell : ParentOfCell{
  int x;
}
- (id)initWithInt: (int)inInt;
+ (void)testOverRelease;
+ (void)testLeak;
@property int x;
@end
@implementation Cell
@synthesize x;
- (id) initWithInt: (int)inInt {
  [super initWithInt: inInt];
  self.x = inInt; // no-warning 
  return self; // Self Init checker would produce a warning here.
}
+ (void) testOverRelease {
  Cell *sharedCell3 = [[Cell alloc] initWithInt: 3];
  [sharedCell3 release];
  [sharedCell3 release]; // expected-warning {{Reference-counted object is used after it is released}}
}
+ (void) testLeak {
  Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}}
}
@end
  
// We should stop tracking some objects even when we inline the call. 
// Specialically, the objects passed into calls with delegate and callback 
// parameters.
@class DelegateTest;
typedef void (*ReleaseCallbackTy) (DelegateTest *c);

@interface Delegate : NSObject
@end

@interface DelegateTest : NSObject {
  Delegate *myDel;
}
// Object initialized with a delagate which could potentially release it.
- (id)initWithDelegate: (id) d;

- (void) setDelegate: (id) d;

// Releases object through callback.
+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc;

+ (void)test: (Delegate *)d;

@property (assign) Delegate* myDel;
@end

void releaseObj(DelegateTest *c);

// Releases object through callback.
void updateObject(DelegateTest *c, ReleaseCallbackTy rel) {
  rel(c);
}

@implementation DelegateTest
@synthesize myDel;

- (id) initWithDelegate: (id) d {
    if ((self = [super init]))
      myDel = d;
    return self;
}

- (void) setDelegate: (id) d {
    myDel = d;
}

+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc {
  rc(obj);
}

+ (void) test: (Delegate *)d {
  DelegateTest *obj1 = [[DelegateTest alloc] initWithDelegate: d]; // no-warning
  DelegateTest *obj2 = [[DelegateTest alloc] init]; // no-warning
  DelegateTest *obj3 = [[DelegateTest alloc] init]; // no-warning
  updateObject(obj2, releaseObj);
  [DelegateTest updateObject: obj3
        WithCallback: releaseObj];
  DelegateTest *obj4 = [[DelegateTest alloc] init]; // no-warning
  [obj4 setDelegate: d];
}
@end

