1 | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify |
2 | // RUN: %clang_analyze_cc1 -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" |
26 | typedef unsigned NSUInteger; |
27 | typedef 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 |
43 | extern NSString * const NSConnectionReplyMode; |
44 | |
45 | @interface NSBundle : NSObject |
46 | +(id)loadNibNamed:(NSString*)s owner:(id)o; |
47 | @end |
48 | |
49 | void log(void *obj); |
50 | extern void *somePtr; |
51 | |
52 | @class MyObj; |
53 | extern 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. |
261 | typedef 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 | |