blob: 8e9cd488a8c430b9bb483d81027bb813433ac87f [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
2
3@protocol NSObject
4@end
5@interface NSObject <NSObject> {}
6+(id)alloc;
7+(id)new;
8-(id)init;
9-(id)autorelease;
10-(id)copy;
11- (Class)class;
12-(id)retain;
Anna Zaks31f69cc2012-09-29 00:20:38 +000013-(id)description;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000014@end
Anna Zaks31f69cc2012-09-29 00:20:38 +000015@class NSString;
16
17extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000018
19@protocol Invalidation1 <NSObject>
20- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
21@end
22
23@protocol Invalidation2 <NSObject>
24- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
25@end
26
27@protocol Invalidation3 <NSObject>
28- (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
Anna Zaks31f69cc2012-09-29 00:20:38 +000029- (void) invalidate2 __attribute__((annotate("objc_instance_variable_invalidator")));
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000030@end
31
32@interface Invalidation2Class <Invalidation2>
33@end
34
35@interface Invalidation1Class <Invalidation1>
36@end
37
38@interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
Anna Zaks31f69cc2012-09-29 00:20:38 +000039 SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000040}
41@end
42
43@implementation SomeInvalidationImplementingObject
44- (void)invalidate{
45 ObjA = 0;
46}
Anna Zaks31f69cc2012-09-29 00:20:38 +000047- (void)invalidate2 {
48 [self invalidate];
49}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000050@end
51
52@interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
Anna Zaks31f69cc2012-09-29 00:20:38 +000053 SomeInvalidationImplementingObject *Ivar1; // regular ivar
54 SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
55 SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
56 SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
57
58 SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
59 SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
60 SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
61 Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
62 Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
63 SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
64 SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
65 SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
Anna Zaksc3c26b72012-10-18 19:17:57 +000066 SomeInvalidationImplementingObject *_Prop8;
Anna Zaksb087bbf2012-09-27 19:45:08 +000067
Anna Zaks31f69cc2012-09-29 00:20:38 +000068 // No warnings on these as they are not invalidatable.
69 NSObject *NIvar1;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000070 NSObject *NObj2;
71 NSObject *_NProp1;
72 NSObject *_NpropIvar;
73}
74
75@property (assign) SomeInvalidationImplementingObject* Prop0;
76@property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
77@property (assign) SomeInvalidationImplementingObject* Prop2;
78@property (assign) SomeInvalidationImplementingObject* Prop3;
Anna Zaks31f69cc2012-09-29 00:20:38 +000079@property (assign) SomeInvalidationImplementingObject *Prop5;
80@property (assign) SomeInvalidationImplementingObject *Prop4;
Anna Zaks377945c2012-09-27 21:57:14 +000081
Anna Zaks31f69cc2012-09-29 00:20:38 +000082@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
83@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
84@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
Anna Zaks377945c2012-09-27 21:57:14 +000085
Anna Zaks5bf5c2e2012-09-26 18:55:16 +000086@property (assign) NSObject* NProp0;
87@property (nonatomic, assign) NSObject* NProp1;
88@property (assign) NSObject* NProp2;
89
90-(void)setProp1: (SomeInvalidationImplementingObject*) InO;
91-(void)setNProp1: (NSObject*) InO;
92
93-(void)invalidate;
94
95@end
96
Anna Zakse0c50fa2012-10-16 19:36:37 +000097@interface SomeSubclassInvalidatableObject()
98@property (assign) SomeInvalidationImplementingObject* Prop8;
99@end
100
101@implementation SomeSubclassInvalidatableObject{
102 @private
103 SomeInvalidationImplementingObject *Ivar5;
104}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000105
Anna Zaks31f69cc2012-09-29 00:20:38 +0000106@synthesize Prop7 = _propIvar;
107@synthesize Prop3 = _Prop3;
108@synthesize Prop5 = _Prop5;
109@synthesize Prop4 = _Prop4;
Anna Zaksc3c26b72012-10-18 19:17:57 +0000110@synthesize Prop8 = _Prop8;
Anna Zaks31f69cc2012-09-29 00:20:38 +0000111
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000112
113- (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
114 _Prop1 = InObj;
115}
116
Anna Zaks31f69cc2012-09-29 00:20:38 +0000117- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
118 _Prop2 = InObj;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000119}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000120- (SomeInvalidationImplementingObject*) Prop2 {
121 return _Prop2;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000122}
123
124@synthesize NProp2 = _NpropIvar;
125
126- (void) setNProp1: (NSObject*) InObj {
127 _NProp1 = InObj;
128}
129
130- (void) invalidate {
Anna Zaks31f69cc2012-09-29 00:20:38 +0000131 [Ivar2 invalidate];
Anna Zaks377945c2012-09-27 21:57:14 +0000132 self.Prop0 = 0;
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000133 self.Prop1 = 0;
134 [self setProp2:0];
135 [self setProp3:0];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000136 [[self Prop5] invalidate2];
137 [self.Prop4 invalidate];
Anna Zaksc3c26b72012-10-18 19:17:57 +0000138 [self.Prop8 invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000139 self.Prop6 = 0;
140 [[self Prop7] invalidate];
141
142 [_Ivar3 description];
143 NSLog(@"%@", _Ivar4);
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000144 [super invalidate];
Anna Zaks31f69cc2012-09-29 00:20:38 +0000145}
146// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
Anna Zaksb087bbf2012-09-27 19:45:08 +0000147 // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
148 // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
Anna Zaksc3c26b72012-10-18 19:17:57 +0000149 // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated or set to nil}}
Anna Zaks31f69cc2012-09-29 00:20:38 +0000150 // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
151 // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
Anna Zakse0c50fa2012-10-16 19:36:37 +0000152 // expected-warning@-7 {{Instance variable Ivar5 needs to be invalidated or set to nil}}
Anna Zaks5bf5c2e2012-09-26 18:55:16 +0000153@end
Anna Zaks5879fb32013-01-07 19:12:56 +0000154
155// Example, where the same property is inherited through
156// the parent and directly through a protocol. If a property backing ivar is
157// synthesized in the parent, let the parent invalidate it.
158
159@protocol IDEBuildable <NSObject>
160@property (readonly, strong) id <Invalidation2> ObjB;
161@end
162
163@interface Parent : NSObject <IDEBuildable, Invalidation2> {
164 Invalidation2Class *_ObjB; // Invalidation of ObjB happens in the parent.
165}
166@end
167
168@interface Child: Parent <Invalidation2, IDEBuildable>
169@end
170
171@implementation Parent
172@synthesize ObjB = _ObjB;
173- (void)invalidate{
174 _ObjB = ((void*)0);
175}
176@end
177
178@implementation Child
179- (void)invalidate{
180 // no-warning
181}
182@end
Anna Zaksb1fc6732013-01-10 20:59:51 +0000183
184@protocol Invalidation <NSObject>
185- (void)invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
186@end
187
188@interface Foo : NSObject <Invalidation>
189@end
190
191@class FooBar;
192@protocol FooBar_Protocol <NSObject>
193@end
194
195@interface MissingInvalidationMethod : Foo <FooBar_Protocol>
196@property (assign) MissingInvalidationMethod *foobar15_warn; // expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod; Property foobar15_warn needs to be invalidated}}
197@end
198@implementation MissingInvalidationMethod
199@end
200
201@interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
202 Foo *Ivar1;// expected-warning {{No invalidation method defined in the @implementation for MissingInvalidationMethod2; Instance variable Ivar1 needs to be invalidated}}
203}
204@end
205@implementation MissingInvalidationMethod2
206@end
207
208@interface MissingInvalidationMethodDecl : NSObject {
209 Foo *Ivar1;// expected-warning {{No invalidation method declared in the @interface for MissingInvalidationMethodDecl; Instance variable Ivar1 needs to be invalidated}}
210}
211@end
212@implementation MissingInvalidationMethodDecl
213@end
214
215@interface MissingInvalidationMethodDecl2 : NSObject {
216@private
Anna Zaks664566c2013-01-10 22:44:16 +0000217 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 +0000218}
Anna Zaks664566c2013-01-10 22:44:16 +0000219@property (strong) Foo *bar1;
Anna Zaksb1fc6732013-01-10 20:59:51 +0000220@end
221@implementation MissingInvalidationMethodDecl2
222@end