blob: 15bcabec69a3941e84e59bca68fbeaa462ab5ccb [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
Anna Zaksae81e172013-01-11 03:52:37 +000044@interface ClassWithInvalidationMethodInCategory <NSObject>
45@end
46
47@interface ClassWithInvalidationMethodInCategory ()
48- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
49@end
50
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000051@interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
Anna Zaks31f69cc2012-09-29 00:20:38 +000052 SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000053}
54@end
55
56@implementation SomeInvalidationImplementingObject
57- (void)invalidate{
58 ObjA = 0;
59}
Anna Zaks31f69cc2012-09-29 00:20:38 +000060- (void)invalidate2 {
61 [self invalidate];
62}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000063@end
64
65@interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
Anna Zaks31f69cc2012-09-29 00:20:38 +000066 SomeInvalidationImplementingObject *Ivar1; // regular ivar
67 SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
68 SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
69 SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
70
71 SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
72 SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
73 SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
74 Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
75 Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
76 SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
77 SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
78 SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
Anna Zaksc3c26b72012-10-18 19:17:57 +000079 SomeInvalidationImplementingObject *_Prop8;
Anna Zaksb087bbf2012-09-27 19:45:08 +000080
Anna Zaks31f69cc2012-09-29 00:20:38 +000081 // No warnings on these as they are not invalidatable.
82 NSObject *NIvar1;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000083 NSObject *NObj2;
84 NSObject *_NProp1;
85 NSObject *_NpropIvar;
86}
87
88@property (assign) SomeInvalidationImplementingObject* Prop0;
89@property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
90@property (assign) SomeInvalidationImplementingObject* Prop2;
91@property (assign) SomeInvalidationImplementingObject* Prop3;
Anna Zaks31f69cc2012-09-29 00:20:38 +000092@property (assign) SomeInvalidationImplementingObject *Prop5;
93@property (assign) SomeInvalidationImplementingObject *Prop4;
Anna Zaks377945c2012-09-27 21:57:14 +000094
Anna Zaks31f69cc2012-09-29 00:20:38 +000095@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
96@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
97@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
Anna Zaks377945c2012-09-27 21:57:14 +000098
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000099@property (assign) NSObject* NProp0;
100@property (nonatomic, assign) NSObject* NProp1;
101@property (assign) NSObject* NProp2;
102
103-(void)setProp1: (SomeInvalidationImplementingObject*) InO;
104-(void)setNProp1: (NSObject*) InO;
105
106-(void)invalidate;
107
108@end
109
Anna Zakse0c50fa2012-10-16 19:36:37 +0000110@interface SomeSubclassInvalidatableObject()
111@property (assign) SomeInvalidationImplementingObject* Prop8;
112@end
113
114@implementation SomeSubclassInvalidatableObject{
115 @private
116 SomeInvalidationImplementingObject *Ivar5;
Anna Zaksae81e172013-01-11 03:52:37 +0000117 ClassWithInvalidationMethodInCategory *Ivar13;
Anna Zakse0c50fa2012-10-16 19:36:37 +0000118}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000119
Anna Zaks31f69cc2012-09-29 00:20:38 +0000120@synthesize Prop7 = _propIvar;
121@synthesize Prop3 = _Prop3;
122@synthesize Prop5 = _Prop5;
123@synthesize Prop4 = _Prop4;
Anna Zaksc3c26b72012-10-18 19:17:57 +0000124@synthesize Prop8 = _Prop8;
Anna Zaks31f69cc2012-09-29 00:20:38 +0000125
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000126
127- (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
128 _Prop1 = InObj;
129}
130
Anna Zaks31f69cc2012-09-29 00:20:38 +0000131- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
132 _Prop2 = InObj;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000133}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000134- (SomeInvalidationImplementingObject*) Prop2 {
135 return _Prop2;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000136}
137
138@synthesize NProp2 = _NpropIvar;
139
140- (void) setNProp1: (NSObject*) InObj {
141 _NProp1 = InObj;
142}
143
144- (void) invalidate {
Anna Zaks31f69cc2012-09-29 00:20:38 +0000145 [Ivar2 invalidate];
Anna Zaks377945c2012-09-27 21:57:14 +0000146 self.Prop0 = 0;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000147 self.Prop1 = 0;
148 [self setProp2:0];
149 [self setProp3:0];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000150 [[self Prop5] invalidate2];
151 [self.Prop4 invalidate];
Anna Zaksc3c26b72012-10-18 19:17:57 +0000152 [self.Prop8 invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000153 self.Prop6 = 0;
154 [[self Prop7] invalidate];
155
156 [_Ivar3 description];
157 NSLog(@"%@", _Ivar4);
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000158 [super invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000159}
160// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
Anna Zaksb087bbf2012-09-27 19:45:08 +0000161 // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
162 // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
Anna Zaksc3c26b72012-10-18 19:17:57 +0000163 // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated or set to nil}}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000164 // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
165 // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
Anna Zakse0c50fa2012-10-16 19:36:37 +0000166 // expected-warning@-7 {{Instance variable Ivar5 needs to be invalidated or set to nil}}
Anna Zaksae81e172013-01-11 03:52:37 +0000167// expected-warning@-8 {{Instance variable Ivar13 needs to be invalidated or set to nil}}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000168@end
Anna Zaks5879fb32013-01-07 19:12:56 +0000169
170// Example, where the same property is inherited through
171// the parent and directly through a protocol. If a property backing ivar is
172// synthesized in the parent, let the parent invalidate it.
173
174@protocol IDEBuildable <NSObject>
175@property (readonly, strong) id <Invalidation2> ObjB;
176@end
177
178@interface Parent : NSObject <IDEBuildable, Invalidation2> {
179 Invalidation2Class *_ObjB; // Invalidation of ObjB happens in the parent.
180}
181@end
182
183@interface Child: Parent <Invalidation2, IDEBuildable>
184@end
185
Anna Zaks65032552013-01-10 23:34:16 +0000186@implementation Parent{
187 @private
188 Invalidation2Class *Ivar10;
189 Invalidation2Class *Ivar11;
190 Invalidation2Class *Ivar12;
191}
192
Anna Zaks5879fb32013-01-07 19:12:56 +0000193@synthesize ObjB = _ObjB;
194- (void)invalidate{
195 _ObjB = ((void*)0);
Anna Zaks65032552013-01-10 23:34:16 +0000196
197 assert(Ivar10 == 0);
198
199 if (__builtin_expect(!(Ivar11 == ((void*)0)), 0))
200 assert(0);
201
202 assert(0 == Ivar12);
203
Anna Zaks5879fb32013-01-07 19:12:56 +0000204}
205@end
206
207@implementation Child
208- (void)invalidate{
209 // no-warning
210}
211@end
Anna Zaksb1fc6732013-01-10 20:59:51 +0000212
213@protocol Invalidation <NSObject>
214- (void)invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
215@end
216
217@interface Foo : NSObject <Invalidation>
218@end
219
220@class FooBar;
221@protocol FooBar_Protocol <NSObject>
222@end
223
224@interface MissingInvalidationMethod : Foo <FooBar_Protocol>
225@property (assign) MissingInvalidationMethod *foobar15_warn; // expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod; Property foobar15_warn needs to be invalidated}}
226@end
227@implementation MissingInvalidationMethod
228@end
229
230@interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
231 Foo *Ivar1;// expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod2; Instance variable Ivar1 needs to be invalidated}}
232}
233@end
234@implementation MissingInvalidationMethod2
235@end
236
237@interface MissingInvalidationMethodDecl : NSObject {
238 Foo *Ivar1;// expected-warning {{No invalidation method declared in the @interface for MissingInvalidationMethodDecl; Instance variable Ivar1 needs to be invalidated}}
239}
240@end
241@implementation MissingInvalidationMethodDecl
242@end
243
244@interface MissingInvalidationMethodDecl2 : NSObject {
245@private
Anna Zaks664566c2013-01-10 22:44:16 +0000246 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 +0000247}
Anna Zaks664566c2013-01-10 22:44:16 +0000248@property (strong) Foo *bar1;
Anna Zaksb1fc6732013-01-10 20:59:51 +0000249@end
250@implementation MissingInvalidationMethodDecl2
251@end