1// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify
2// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fno-builtin %s -verify
3
4@class NSZone, NSCoder;
5@protocol NSObject
6- (id)self;
7@end
8@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
9@end 
10@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
11@end 
12@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
13@end
14@interface NSObject <NSObject> {}
15+ (id)allocWithZone:(NSZone *)zone;
16+ (id)alloc;
17- (void)dealloc;
18-(id)class;
19-(id)init;
20-(id)release;
21@end
22@interface NSProxy <NSObject> {}
23@end
24
25//#import "Foundation/NSObject.h"
26typedef unsigned NSUInteger;
27typedef long NSInteger;
28
29@interface NSInvocation : NSObject {}
30- (void)getArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
31- (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
32@end
33
34@class NSMethodSignature, NSCoder, NSString, NSEnumerator;
35@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
36- (NSUInteger)length;
37+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
38@end extern NSString * const NSBundleDidLoadNotification;
39@interface NSAssertionHandler : NSObject {}
40+ (NSAssertionHandler *)currentHandler;
41- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
42@end
43extern NSString * const NSConnectionReplyMode;
44
45@interface NSBundle : NSObject
46+(id)loadNibNamed:(NSString*)s owner:(id)o;
47@end
48
49void log(void *obj);
50extern void *somePtr;
51
52@class MyObj;
53extern id _commonInit(MyObj *self);
54
55@interface MyObj : NSObject {
56	id myivar;
57	int myint;
58}
59-(id)_init;
60-(id)initWithSomething:(int)x;
61-(void)doSomething;
62+(id)commonInitMember:(id)s;
63@end
64
65@interface MyProxyObj : NSProxy {}
66-(id)init;
67@end
68
69@implementation MyObj
70
71-(id)init {
72  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);
73  return [self initWithSomething:0];
74}
75
76-(id)init2 {
77  self = [self initWithSomething:0];
78  return self;
79}
80
81-(id)init3 {
82	log([self class]);
83	return [self initWithSomething:0];
84}
85
86-(id)init4 {
87	self = [super init];
88	if (self) {
89		log(&self);
90	}
91	return self;
92}
93
94-(id)init4_w {
95  [super init];
96  if (self) {
97    log(&self);
98  }
99  return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}}
100}
101
102- (id)initWithSomething:(int)x {    
103	if ((self = [super init]))
104		myint = x;
105	return self;
106}
107
108-(id)_init {
109	myivar = 0;
110	return self;
111}
112
113-(id)init5 {
114  [NSBundle loadNibNamed:@"Window" owner:self];
115  return [self initWithSomething:0];
116}
117
118-(id)init6 {
119  [NSBundle loadNibNamed:@"Window" owner:myivar]; // no-warning
120  return [self initWithSomething:0];
121}
122
123-(id)init7 {
124  if (0 != (self = [self _init]))
125    myivar = 0;
126  return self;
127}
128
129-(id)init8 {
130    if ((self = [super init])) {
131		log(&self);
132		myivar = 0;
133    }
134    return self;
135}
136
137-(id)init9 {
138  [self doSomething];
139  return self; // no-warning
140}
141
142-(id)init10 {
143  myivar = 0; // no-warning
144  return self;
145}
146
147-(id)init11 {
148  return self; // no-warning
149}
150
151-(id)init12 {
152	[super init];
153	return self; // expected-warning {{Returning 'self'}}
154}
155
156-(id)init13 {
157	if (self == [super init]) {
158	  myivar = 0; // expected-warning {{Instance variable used}}
159	}
160	return self; // expected-warning {{Returning 'self'}}
161}
162
163-(id)init14 {
164  if (!(self = _commonInit(self)))
165    return 0;
166  return self;
167}
168
169-(id)init14_w {
170  [super init];
171  self = _commonInit(self);
172  return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}}
173}
174
175-(id)init15 {
176  if (!(self = [super init]))
177    return 0;
178  return self;
179}
180
181-(id)init16 {
182  somePtr = [super init];
183  self = somePtr;
184  myivar = 0; 
185  return self;
186}
187
188-(id)init17 {
189  somePtr = [super init];
190  myivar = 0; // expected-warning {{Instance variable used}}
191  return 0;
192}
193
194-(id)init18 {
195  self = [super init];
196  self = _commonInit(self);
197  return self;
198}
199
200+(id)commonInitMember:(id)s {
201  return s;
202}
203
204-(id)init19 {
205  self = [super init];
206  self = [MyObj commonInitMember:self];
207  return self;
208}
209
210-(id)init19_w {
211  [super init];
212  self = [MyObj commonInitMember:self];
213  return self; // expected-warning {{Returning 'self'}}
214}
215
216-(void)doSomething {}
217
218@end
219
220@implementation MyProxyObj
221
222- (id)init { return self; }
223
224@end
225
226
227// Test for radar://10973514 : self should not be invalidated by a method call.
228@interface Test : NSObject {
229    NSInvocation *invocation_;
230}
231@end
232@implementation Test
233-(id) initWithTarget:(id) rec selector:(SEL) cb {
234  if (self=[super init]) {
235    [invocation_ setArgument:&self atIndex:2];
236  }   
237  return self;
238}
239@end
240
241// Test radar:11235991 - passing self to a call to super.
242@protocol MyDelegate
243@end
244@interface Object : NSObject
245- (id) initWithObject: (id)i;
246@end
247@interface Derived: Object <MyDelegate>
248- (id) initWithInt: (int)t;
249@property (nonatomic, retain, readwrite) Object *size;
250@end
251@implementation Derived 
252- (id) initWithInt: (int)t {
253   if ((self = [super initWithObject:self])) {
254      _size = [[Object alloc] init];
255   }
256   return self;
257}
258@end
259
260// Test for radar://11125870: init constructing a special instance.
261typedef signed char BOOL;
262@interface MyClass : NSObject
263@end
264@implementation MyClass
265+ (id)specialInstance {
266    return [[MyClass alloc] init];
267}
268- (id)initSpecially:(BOOL)handleSpecially {
269    if ((self = [super init])) {
270        if (handleSpecially) {
271            self = [MyClass specialInstance];
272        }
273    }
274    return self;
275}
276- (id)initSelfSelf {
277    if ((self = [super init])) {
278      self = self;
279    }
280    return self;
281}
282@end
283
284// Test for radar://12838705.
285@interface ABCClass : NSObject
286@property (nonatomic, strong) NSString *foo;
287@property (nonatomic, strong) NSString *bar;
288@property (nonatomic, strong) NSString *baz;
289@end
290
291@implementation ABCClass
292@synthesize foo = foo_;
293@synthesize bar = bar_;
294@synthesize baz = baz_;
295
296- (id)initWithABC:(ABCClass *)abc {
297  self = [super init];
298  baz_ = abc->baz_;
299  return self;
300}
301
302- (ABCClass *)abcWithFoo:(NSString *)foo {
303  ABCClass *copy = [[ABCClass alloc] initWithABC:self];
304  return copy;
305}
306
307@end
308
309