// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -analyzer-config ipa=dynamic -fno-builtin %s -verify // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -fno-builtin %s -verify @class NSZone, NSCoder; @protocol NSObject - (id)self; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject <NSObject> {} + (id)allocWithZone:(NSZone *)zone; + (id)alloc; - (void)dealloc; -(id)class; -(id)init; -(id)release; @end @interface NSProxy <NSObject> {} @end //#import "Foundation/NSObject.h" typedef unsigned NSUInteger; typedef long NSInteger; @interface NSInvocation : NSObject {} - (void)getArgument:(void *)argumentLocation atIndex:(NSInteger)idx; - (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx; @end @class NSMethodSignature, NSCoder, NSString, NSEnumerator; @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; @end extern NSString * const NSBundleDidLoadNotification; @interface NSAssertionHandler : NSObject {} + (NSAssertionHandler *)currentHandler; - (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; @end extern NSString * const NSConnectionReplyMode; @interface NSBundle : NSObject +(id)loadNibNamed:(NSString*)s owner:(id)o; @end void log(void *obj); extern void *somePtr; @class MyObj; extern id _commonInit(MyObj *self); @interface MyObj : NSObject { id myivar; int myint; } -(id)_init; -(id)initWithSomething:(int)x; -(void)doSomething; +(id)commonInitMember:(id)s; @end @interface MyProxyObj : NSProxy {} -(id)init; @end @implementation MyObj -(id)init { do { if (!((somePtr != 0))) { [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithUTF8String:"init.m"] lineNumber:21 description:(@"Invalid parameter not satisfying: %s"), ("x != 0"), (0), (0), (0), (0)]; } } while(0); return [self initWithSomething:0]; } -(id)init2 { self = [self initWithSomething:0]; return self; } -(id)init3 { log([self class]); return [self initWithSomething:0]; } -(id)init4 { self = [super init]; if (self) { log(&self); } return self; } -(id)init4_w { [super init]; if (self) { log(&self); } return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}} } - (id)initWithSomething:(int)x { if ((self = [super init])) myint = x; return self; } -(id)_init { myivar = 0; return self; } -(id)init5 { [NSBundle loadNibNamed:@"Window" owner:self]; return [self initWithSomething:0]; } -(id)init6 { [NSBundle loadNibNamed:@"Window" owner:myivar]; // no-warning return [self initWithSomething:0]; } -(id)init7 { if (0 != (self = [self _init])) myivar = 0; return self; } -(id)init8 { if ((self = [super init])) { log(&self); myivar = 0; } return self; } -(id)init9 { [self doSomething]; return self; // no-warning } -(id)init10 { myivar = 0; // no-warning return self; } -(id)init11 { return self; // no-warning } -(id)init12 { [super init]; return self; // expected-warning {{Returning 'self'}} } -(id)init13 { if (self == [super init]) { myivar = 0; // expected-warning {{Instance variable used}} } return self; // expected-warning {{Returning 'self'}} } -(id)init14 { if (!(self = _commonInit(self))) return 0; return self; } -(id)init14_w { [super init]; self = _commonInit(self); return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}} } -(id)init15 { if (!(self = [super init])) return 0; return self; } -(id)init16 { somePtr = [super init]; self = somePtr; myivar = 0; return self; } -(id)init17 { somePtr = [super init]; myivar = 0; // expected-warning {{Instance variable used}} return 0; } -(id)init18 { self = [super init]; self = _commonInit(self); return self; } +(id)commonInitMember:(id)s { return s; } -(id)init19 { self = [super init]; self = [MyObj commonInitMember:self]; return self; } -(id)init19_w { [super init]; self = [MyObj commonInitMember:self]; return self; // expected-warning {{Returning 'self'}} } -(void)doSomething {} @end @implementation MyProxyObj - (id)init { return self; } @end // Test for radar://10973514 : self should not be invalidated by a method call. @interface Test : NSObject { NSInvocation *invocation_; } @end @implementation Test -(id) initWithTarget:(id) rec selector:(SEL) cb { if (self=[super init]) { [invocation_ setArgument:&self atIndex:2]; } return self; } @end // Test radar:11235991 - passing self to a call to super. @protocol MyDelegate @end @interface Object : NSObject - (id) initWithObject: (id)i; @end @interface Derived: Object <MyDelegate> - (id) initWithInt: (int)t; @property (nonatomic, retain, readwrite) Object *size; @end @implementation Derived - (id) initWithInt: (int)t { if ((self = [super initWithObject:self])) { _size = [[Object alloc] init]; } return self; } @end // Test for radar://11125870: init constructing a special instance. typedef signed char BOOL; @interface MyClass : NSObject @end @implementation MyClass + (id)specialInstance { return [[MyClass alloc] init]; } - (id)initSpecially:(BOOL)handleSpecially { if ((self = [super init])) { if (handleSpecially) { self = [MyClass specialInstance]; } } return self; } - (id)initSelfSelf { if ((self = [super init])) { self = self; } return self; } @end // Test for radar://12838705. @interface ABCClass : NSObject @property (nonatomic, strong) NSString *foo; @property (nonatomic, strong) NSString *bar; @property (nonatomic, strong) NSString *baz; @end @implementation ABCClass @synthesize foo = foo_; @synthesize bar = bar_; @synthesize baz = baz_; - (id)initWithABC:(ABCClass *)abc { self = [super init]; baz_ = abc->baz_; return self; } - (ABCClass *)abcWithFoo:(NSString *)foo { ABCClass *copy = [[ABCClass alloc] initWithABC:self]; return copy; } @end