blob: f21bfdf474fa9833b78f67763a9731205b6ae76e [file] [log] [blame]
Anna Zaks5bf5c2e2012-09-26 18:55:16 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -fobjc-default-synthesize-properties -verify %s
Anna Zaks65032552013-01-10 23:34:16 +00002extern void __assert_fail (__const char *__assertion, __const char *__file,
3 unsigned int __line, __const char *__function)
4 __attribute__ ((__noreturn__));
5
6#define assert(expr) \
7 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
Anna Zaks5bf5c2e2012-09-26 18:55:16 +00008
9@protocol NSObject
10@end
11@interface NSObject <NSObject> {}
12+(id)alloc;
13+(id)new;
14-(id)init;
15-(id)autorelease;
16-(id)copy;
17- (Class)class;
18-(id)retain;
Anna Zaks31f69cc2012-09-29 00:20:38 +000019-(id)description;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000020@end
Anna Zaks31f69cc2012-09-29 00:20:38 +000021@class NSString;
22
23extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000024
25@protocol Invalidation1 <NSObject>
26- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
27@end
28
29@protocol Invalidation2 <NSObject>
30- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
31@end
32
33@protocol Invalidation3 <NSObject>
34- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
Anna Zaks31f69cc2012-09-29 00:20:38 +000035- (void) invalidate2 __attribute__((annotate("objc_instance_variable_invalidator")));
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000036@end
37
38@interface Invalidation2Class <Invalidation2>
39@end
40
41@interface Invalidation1Class <Invalidation1>
42@end
43
44@interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
Anna Zaks31f69cc2012-09-29 00:20:38 +000045 SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000046}
47@end
48
49@implementation SomeInvalidationImplementingObject
50- (void)invalidate{
51 ObjA = 0;
52}
Anna Zaks31f69cc2012-09-29 00:20:38 +000053- (void)invalidate2 {
54 [self invalidate];
55}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000056@end
57
58@interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
Anna Zaks31f69cc2012-09-29 00:20:38 +000059 SomeInvalidationImplementingObject *Ivar1; // regular ivar
60 SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
61 SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
62 SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
63
64 SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
65 SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
66 SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
67 Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
68 Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
69 SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
70 SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
71 SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
Anna Zaksc3c26b72012-10-18 19:17:57 +000072 SomeInvalidationImplementingObject *_Prop8;
Anna Zaksb087bbf2012-09-27 19:45:08 +000073
Anna Zaks31f69cc2012-09-29 00:20:38 +000074 // No warnings on these as they are not invalidatable.
75 NSObject *NIvar1;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000076 NSObject *NObj2;
77 NSObject *_NProp1;
78 NSObject *_NpropIvar;
79}
80
81@property (assign) SomeInvalidationImplementingObject* Prop0;
82@property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
83@property (assign) SomeInvalidationImplementingObject* Prop2;
84@property (assign) SomeInvalidationImplementingObject* Prop3;
Anna Zaks31f69cc2012-09-29 00:20:38 +000085@property (assign) SomeInvalidationImplementingObject *Prop5;
86@property (assign) SomeInvalidationImplementingObject *Prop4;
Anna Zaks377945c2012-09-27 21:57:14 +000087
Anna Zaks31f69cc2012-09-29 00:20:38 +000088@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
89@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
90@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
Anna Zaks377945c2012-09-27 21:57:14 +000091
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000092@property (assign) NSObject* NProp0;
93@property (nonatomic, assign) NSObject* NProp1;
94@property (assign) NSObject* NProp2;
95
96-(void)setProp1: (SomeInvalidationImplementingObject*) InO;
97-(void)setNProp1: (NSObject*) InO;
98
99-(void)invalidate;
100
101@end
102
Anna Zakse0c50fa2012-10-16 19:36:37 +0000103@interface SomeSubclassInvalidatableObject()
104@property (assign) SomeInvalidationImplementingObject* Prop8;
105@end
106
107@implementation SomeSubclassInvalidatableObject{
108 @private
109 SomeInvalidationImplementingObject *Ivar5;
110}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000111
Anna Zaks31f69cc2012-09-29 00:20:38 +0000112@synthesize Prop7 = _propIvar;
113@synthesize Prop3 = _Prop3;
114@synthesize Prop5 = _Prop5;
115@synthesize Prop4 = _Prop4;
Anna Zaksc3c26b72012-10-18 19:17:57 +0000116@synthesize Prop8 = _Prop8;
Anna Zaks31f69cc2012-09-29 00:20:38 +0000117
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000118
119- (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
120 _Prop1 = InObj;
121}
122
Anna Zaks31f69cc2012-09-29 00:20:38 +0000123- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
124 _Prop2 = InObj;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000125}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000126- (SomeInvalidationImplementingObject*) Prop2 {
127 return _Prop2;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000128}
129
130@synthesize NProp2 = _NpropIvar;
131
132- (void) setNProp1: (NSObject*) InObj {
133 _NProp1 = InObj;
134}
135
136- (void) invalidate {
Anna Zaks31f69cc2012-09-29 00:20:38 +0000137 [Ivar2 invalidate];
Anna Zaks377945c2012-09-27 21:57:14 +0000138 self.Prop0 = 0;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000139 self.Prop1 = 0;
140 [self setProp2:0];
141 [self setProp3:0];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000142 [[self Prop5] invalidate2];
143 [self.Prop4 invalidate];
Anna Zaksc3c26b72012-10-18 19:17:57 +0000144 [self.Prop8 invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000145 self.Prop6 = 0;
146 [[self Prop7] invalidate];
147
148 [_Ivar3 description];
149 NSLog(@"%@", _Ivar4);
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000150 [super invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000151}
152// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
Anna Zaksb087bbf2012-09-27 19:45:08 +0000153 // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
154 // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
Anna Zaksc3c26b72012-10-18 19:17:57 +0000155 // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated or set to nil}}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000156 // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
157 // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
Anna Zakse0c50fa2012-10-16 19:36:37 +0000158 // expected-warning@-7 {{Instance variable Ivar5 needs to be invalidated or set to nil}}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000159@end
Anna Zaks5879fb32013-01-07 19:12:56 +0000160
161// Example, where the same property is inherited through
162// the parent and directly through a protocol. If a property backing ivar is
163// synthesized in the parent, let the parent invalidate it.
164
165@protocol IDEBuildable <NSObject>
166@property (readonly, strong) id <Invalidation2> ObjB;
167@end
168
169@interface Parent : NSObject <IDEBuildable, Invalidation2> {
170 Invalidation2Class *_ObjB; // Invalidation of ObjB happens in the parent.
171}
172@end
173
174@interface Child: Parent <Invalidation2, IDEBuildable>
175@end
176
Anna Zaks65032552013-01-10 23:34:16 +0000177@implementation Parent{
178 @private
179 Invalidation2Class *Ivar10;
180 Invalidation2Class *Ivar11;
181 Invalidation2Class *Ivar12;
182}
183
Anna Zaks5879fb32013-01-07 19:12:56 +0000184@synthesize ObjB = _ObjB;
185- (void)invalidate{
186 _ObjB = ((void*)0);
Anna Zaks65032552013-01-10 23:34:16 +0000187
188 assert(Ivar10 == 0);
189
190 if (__builtin_expect(!(Ivar11 == ((void*)0)), 0))
191 assert(0);
192
193 assert(0 == Ivar12);
194
Anna Zaks5879fb32013-01-07 19:12:56 +0000195}
196@end
197
198@implementation Child
199- (void)invalidate{
200 // no-warning
201}
202@end
Anna Zaksb1fc6732013-01-10 20:59:51 +0000203
204@protocol Invalidation <NSObject>
205- (void)invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
206@end
207
208@interface Foo : NSObject <Invalidation>
209@end
210
211@class FooBar;
212@protocol FooBar_Protocol <NSObject>
213@end
214
215@interface MissingInvalidationMethod : Foo <FooBar_Protocol>
216@property (assign) MissingInvalidationMethod *foobar15_warn; // expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod; Property foobar15_warn needs to be invalidated}}
217@end
218@implementation MissingInvalidationMethod
219@end
220
221@interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
222 Foo *Ivar1;// expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod2; Instance variable Ivar1 needs to be invalidated}}
223}
224@end
225@implementation MissingInvalidationMethod2
226@end
227
228@interface MissingInvalidationMethodDecl : NSObject {
229 Foo *Ivar1;// expected-warning {{No invalidation method declared in the @interface for MissingInvalidationMethodDecl; Instance variable Ivar1 needs to be invalidated}}
230}
231@end
232@implementation MissingInvalidationMethodDecl
233@end
234
235@interface MissingInvalidationMethodDecl2 : NSObject {
236@private
Anna Zaks664566c2013-01-10 22:44:16 +0000237 Foo *_foo1; // expected-warning {{No invalidation method declared in the @interface for MissingInvalidationMethodDecl2; Instance variable _foo1 needs to be invalidated}}
Anna Zaksb1fc6732013-01-10 20:59:51 +0000238}
Anna Zaks664566c2013-01-10 22:44:16 +0000239@property (strong) Foo *bar1;
Anna Zaksb1fc6732013-01-10 20:59:51 +0000240@end
241@implementation MissingInvalidationMethodDecl2
242@end