blob: 4fd46c2243f9c85a0e1ed76d4b66ece36ebba1bb [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
Anna Zaksb8f66782013-01-11 03:52:40 +000038@protocol Invalidation3;
39@protocol Invalidation2;
40
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000041@interface Invalidation2Class <Invalidation2>
42@end
43
44@interface Invalidation1Class <Invalidation1>
45@end
46
Anna Zaksae81e172013-01-11 03:52:37 +000047@interface ClassWithInvalidationMethodInCategory <NSObject>
48@end
49
50@interface ClassWithInvalidationMethodInCategory ()
51- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
52@end
53
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000054@interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
Anna Zaks31f69cc2012-09-29 00:20:38 +000055 SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000056}
57@end
58
59@implementation SomeInvalidationImplementingObject
60- (void)invalidate{
61 ObjA = 0;
62}
Anna Zaks31f69cc2012-09-29 00:20:38 +000063- (void)invalidate2 {
64 [self invalidate];
65}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000066@end
67
68@interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
Anna Zaks31f69cc2012-09-29 00:20:38 +000069 SomeInvalidationImplementingObject *Ivar1; // regular ivar
70 SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
71 SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
72 SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
73
74 SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
75 SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
76 SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
77 Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
78 Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
79 SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
80 SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
81 SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
Anna Zaksc3c26b72012-10-18 19:17:57 +000082 SomeInvalidationImplementingObject *_Prop8;
Anna Zaksb087bbf2012-09-27 19:45:08 +000083
Anna Zaks31f69cc2012-09-29 00:20:38 +000084 // No warnings on these as they are not invalidatable.
85 NSObject *NIvar1;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000086 NSObject *NObj2;
87 NSObject *_NProp1;
88 NSObject *_NpropIvar;
89}
90
91@property (assign) SomeInvalidationImplementingObject* Prop0;
92@property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
93@property (assign) SomeInvalidationImplementingObject* Prop2;
94@property (assign) SomeInvalidationImplementingObject* Prop3;
Anna Zaks31f69cc2012-09-29 00:20:38 +000095@property (assign) SomeInvalidationImplementingObject *Prop5;
96@property (assign) SomeInvalidationImplementingObject *Prop4;
Anna Zaks377945c2012-09-27 21:57:14 +000097
Anna Zaks31f69cc2012-09-29 00:20:38 +000098@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
99@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
100@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
Anna Zaks377945c2012-09-27 21:57:14 +0000101
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000102@property (assign) NSObject* NProp0;
103@property (nonatomic, assign) NSObject* NProp1;
104@property (assign) NSObject* NProp2;
105
106-(void)setProp1: (SomeInvalidationImplementingObject*) InO;
107-(void)setNProp1: (NSObject*) InO;
108
109-(void)invalidate;
110
111@end
112
Anna Zakse0c50fa2012-10-16 19:36:37 +0000113@interface SomeSubclassInvalidatableObject()
114@property (assign) SomeInvalidationImplementingObject* Prop8;
115@end
116
117@implementation SomeSubclassInvalidatableObject{
118 @private
119 SomeInvalidationImplementingObject *Ivar5;
Anna Zaksae81e172013-01-11 03:52:37 +0000120 ClassWithInvalidationMethodInCategory *Ivar13;
Anna Zakse0c50fa2012-10-16 19:36:37 +0000121}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000122
Anna Zaks31f69cc2012-09-29 00:20:38 +0000123@synthesize Prop7 = _propIvar;
124@synthesize Prop3 = _Prop3;
125@synthesize Prop5 = _Prop5;
126@synthesize Prop4 = _Prop4;
Anna Zaksc3c26b72012-10-18 19:17:57 +0000127@synthesize Prop8 = _Prop8;
Anna Zaks31f69cc2012-09-29 00:20:38 +0000128
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000129
130- (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
131 _Prop1 = InObj;
132}
133
Anna Zaks31f69cc2012-09-29 00:20:38 +0000134- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
135 _Prop2 = InObj;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000136}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000137- (SomeInvalidationImplementingObject*) Prop2 {
138 return _Prop2;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000139}
140
141@synthesize NProp2 = _NpropIvar;
142
143- (void) setNProp1: (NSObject*) InObj {
144 _NProp1 = InObj;
145}
146
147- (void) invalidate {
Anna Zaks31f69cc2012-09-29 00:20:38 +0000148 [Ivar2 invalidate];
Anna Zaks377945c2012-09-27 21:57:14 +0000149 self.Prop0 = 0;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000150 self.Prop1 = 0;
151 [self setProp2:0];
152 [self setProp3:0];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000153 [[self Prop5] invalidate2];
154 [self.Prop4 invalidate];
Anna Zaksc3c26b72012-10-18 19:17:57 +0000155 [self.Prop8 invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000156 self.Prop6 = 0;
157 [[self Prop7] invalidate];
158
159 [_Ivar3 description];
160 NSLog(@"%@", _Ivar4);
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000161 [super invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000162}
163// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
Anna Zaksb087bbf2012-09-27 19:45:08 +0000164 // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
165 // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
Anna Zaksc3c26b72012-10-18 19:17:57 +0000166 // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated or set to nil}}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000167 // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
168 // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
Anna Zakse0c50fa2012-10-16 19:36:37 +0000169 // expected-warning@-7 {{Instance variable Ivar5 needs to be invalidated or set to nil}}
Anna Zaksae81e172013-01-11 03:52:37 +0000170// expected-warning@-8 {{Instance variable Ivar13 needs to be invalidated or set to nil}}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000171@end
Anna Zaks5879fb32013-01-07 19:12:56 +0000172
173// Example, where the same property is inherited through
174// the parent and directly through a protocol. If a property backing ivar is
175// synthesized in the parent, let the parent invalidate it.
176
177@protocol IDEBuildable <NSObject>
178@property (readonly, strong) id <Invalidation2> ObjB;
179@end
180
181@interface Parent : NSObject <IDEBuildable, Invalidation2> {
182 Invalidation2Class *_ObjB; // Invalidation of ObjB happens in the parent.
183}
184@end
185
186@interface Child: Parent <Invalidation2, IDEBuildable>
187@end
188
Anna Zaks65032552013-01-10 23:34:16 +0000189@implementation Parent{
190 @private
191 Invalidation2Class *Ivar10;
192 Invalidation2Class *Ivar11;
193 Invalidation2Class *Ivar12;
194}
195
Anna Zaks5879fb32013-01-07 19:12:56 +0000196@synthesize ObjB = _ObjB;
197- (void)invalidate{
198 _ObjB = ((void*)0);
Anna Zaks65032552013-01-10 23:34:16 +0000199
200 assert(Ivar10 == 0);
201
202 if (__builtin_expect(!(Ivar11 == ((void*)0)), 0))
203 assert(0);
204
205 assert(0 == Ivar12);
206
Anna Zaks5879fb32013-01-07 19:12:56 +0000207}
208@end
209
210@implementation Child
211- (void)invalidate{
212 // no-warning
213}
214@end
Anna Zaksb1fc6732013-01-10 20:59:51 +0000215
216@protocol Invalidation <NSObject>
217- (void)invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
218@end
219
220@interface Foo : NSObject <Invalidation>
221@end
222
223@class FooBar;
224@protocol FooBar_Protocol <NSObject>
225@end
226
227@interface MissingInvalidationMethod : Foo <FooBar_Protocol>
Anna Zaks79ccd562013-01-16 01:35:57 +0000228@property (assign) MissingInvalidationMethod *foobar15_warn; // expected-warning {{Property foobar15_warn needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod}}
Anna Zaksb1fc6732013-01-10 20:59:51 +0000229@end
230@implementation MissingInvalidationMethod
231@end
232
233@interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
Anna Zaks79ccd562013-01-16 01:35:57 +0000234 Foo *Ivar1;// expected-warning {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod2}}
Anna Zaksb1fc6732013-01-10 20:59:51 +0000235}
236@end
237@implementation MissingInvalidationMethod2
238@end
239
240@interface MissingInvalidationMethodDecl : NSObject {
Anna Zaks79ccd562013-01-16 01:35:57 +0000241 Foo *Ivar1;// expected-warning {{Instance variable Ivar1 needs to be invalidated; no invalidation method is declared for MissingInvalidationMethodDecl}}
Anna Zaksb1fc6732013-01-10 20:59:51 +0000242}
243@end
244@implementation MissingInvalidationMethodDecl
245@end
246
247@interface MissingInvalidationMethodDecl2 : NSObject {
248@private
Anna Zaks79ccd562013-01-16 01:35:57 +0000249 Foo *_foo1; // expected-warning {{Instance variable _foo1 needs to be invalidated; no invalidation method is declared for MissingInvalidationMethodDecl2}}
Anna Zaksb1fc6732013-01-10 20:59:51 +0000250}
Anna Zaks664566c2013-01-10 22:44:16 +0000251@property (strong) Foo *bar1;
Anna Zaksb1fc6732013-01-10 20:59:51 +0000252@end
253@implementation MissingInvalidationMethodDecl2
254@end