brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · b8d891f Raw
127 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s2 3typedef signed char BOOL;4typedef struct objc_class *Class;5typedef struct objc_object {6    Class isa;7} *id;8@protocol NSObject  - (BOOL)isEqual:(id)object; @end9@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@end20 21@interface SelfStaysLive : NSObject22- (id)init;23@end24 25@implementation SelfStaysLive26- (id)init {27  return [super init];28}29@end30 31void selfStaysLive(void) {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@interface ParentOfCell : NSObject39- (id)initWithInt: (int)inInt;40@end41@interface Cell : ParentOfCell{42  int x;43}44- (id)initWithInt: (int)inInt;45+ (void)testOverRelease;46+ (void)testLeak;47@property int x;48@end49@implementation Cell50@synthesize x;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.55}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}}60}61+ (void) testLeak {62  Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}}63}64@end65  66// We should stop tracking some objects even when we inline the call. 67// Specialically, the objects passed into calls with delegate and callback 68// parameters.69@class DelegateTest;70typedef void (*ReleaseCallbackTy) (DelegateTest *c);71 72@interface Delegate : NSObject73@end74 75@interface DelegateTest : NSObject {76  Delegate *myDel;77}78// Object initialized with a delagate which could potentially release it.79- (id)initWithDelegate: (id) d;80 81- (void) setDelegate: (id) d;82 83// Releases object through callback.84+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc;85 86+ (void)test: (Delegate *)d;87 88@property (assign) Delegate* myDel;89@end90 91void releaseObj(DelegateTest *c);92 93// Releases object through callback.94void updateObject(DelegateTest *c, ReleaseCallbackTy rel) {95  rel(c);96}97 98@implementation DelegateTest99@synthesize myDel;100 101- (id) initWithDelegate: (id) d {102    if ((self = [super init]))103      myDel = d;104    return self;105}106 107- (void) setDelegate: (id) d {108    myDel = d;109}110 111+ (void)updateObject:(DelegateTest*)obj WithCallback:(ReleaseCallbackTy)rc {112  rc(obj);113}114 115+ (void) test: (Delegate *)d {116  DelegateTest *obj1 = [[DelegateTest alloc] initWithDelegate: d]; // no-warning117  DelegateTest *obj2 = [[DelegateTest alloc] init]; // no-warning118  DelegateTest *obj3 = [[DelegateTest alloc] init]; // no-warning119  updateObject(obj2, releaseObj);120  [DelegateTest updateObject: obj3121        WithCallback: releaseObj];122  DelegateTest *obj4 = [[DelegateTest alloc] init]; // no-warning123  [obj4 setDelegate: d];124}125@end126 127