[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / test / Analysis / objc_invalidation.m
blob52a79d8f34baa22e124e21ea35a21f3565f5b6eb
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -DRUN_IVAR_INVALIDATION -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.MissingInvalidationMethod -DRUN_MISSING_INVALIDATION_METHOD -verify %s
3 extern void __assert_fail (__const char *__assertion, __const char *__file,
4     unsigned int __line, __const char *__function)
5      __attribute__ ((__noreturn__));
7 #define assert(expr) \
8   ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
10 @protocol NSObject
11 @end
12 @interface NSObject <NSObject> {}
13 +(id)alloc;
14 +(id)new;
15 -(id)init;
16 -(id)autorelease;
17 -(id)copy;
18 - (Class)class;
19 -(id)retain;
20 -(id)description;
21 @end
22 @class NSString;
24 extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
26 @protocol Invalidation1 <NSObject> 
27 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
28 @end 
30 @protocol Invalidation2 <NSObject> 
31 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
32 @end 
34 @protocol Invalidation3 <NSObject>
35 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
36 - (void) invalidate2 __attribute__((annotate("objc_instance_variable_invalidator")));
37 @end
39 @protocol Invalidation3;
40 @protocol Invalidation2;
42 @interface Invalidation2Class <Invalidation2>
43 @end
45 @interface Invalidation1Class <Invalidation1>
46 @end
48 @interface ClassWithInvalidationMethodInCategory <NSObject>
49 @end
51 @interface ClassWithInvalidationMethodInCategory ()
52 - (void) invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
53 @end
55 @interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
56   SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
58 @end
60 @implementation SomeInvalidationImplementingObject
61 - (void)invalidate{
62   ObjA = 0;
64 - (void)invalidate2 {
65   [self invalidate];
67 @end
69 @interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
70   SomeInvalidationImplementingObject *Ivar1; // regular ivar
71   SomeInvalidationImplementingObject *Ivar2; // regular ivar, sending invalidate message
72   SomeInvalidationImplementingObject *_Ivar3; // no property, call -description
73   SomeInvalidationImplementingObject *_Ivar4; // no property, provide as argument to NSLog()
75   SomeInvalidationImplementingObject *_Prop1; // partially implemented property, set to 0 with dot syntax
76   SomeInvalidationImplementingObject *_Prop2; // fully implemented prop, set to 0 with dot syntax
77   SomeInvalidationImplementingObject *_propIvar; // property with custom named ivar, set to 0 via setter
78   Invalidation1Class *MultipleProtocols; // regular ivar belonging to a different class
79   Invalidation2Class *MultInheritance; // regular ivar belonging to a different class
80   SomeInvalidationImplementingObject *_Prop3; // property, invalidate via sending a message to a getter method
81   SomeInvalidationImplementingObject *_Prop4; // property with @synthesize, invalidate via property
82   SomeInvalidationImplementingObject *_Prop5; // property with @synthesize, invalidate via getter method
83   SomeInvalidationImplementingObject *_Prop8;
84   
85   // Ivars invalidated by the partial invalidator. 
86   SomeInvalidationImplementingObject *Ivar9;
87   SomeInvalidationImplementingObject *_Prop10;
88   SomeInvalidationImplementingObject *Ivar11;
90   // No warnings on these as they are not invalidatable.
91   NSObject *NIvar1;
92   NSObject *NObj2;
93   NSObject *_NProp1;
94   NSObject *_NpropIvar;
97 @property (assign) SomeInvalidationImplementingObject* Prop0;
98 @property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
99 @property (assign) SomeInvalidationImplementingObject* Prop2;
100 @property (assign) SomeInvalidationImplementingObject* Prop3;
101 @property (assign) SomeInvalidationImplementingObject *Prop5;
102 @property (assign) SomeInvalidationImplementingObject *Prop4;
104 @property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
105 @property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
106 @property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
108 @property (assign) NSObject* NProp0;
109 @property (nonatomic, assign) NSObject* NProp1;
110 @property (assign) NSObject* NProp2;
112 -(void)setProp1: (SomeInvalidationImplementingObject*) InO;
113 -(void)setNProp1: (NSObject*) InO;
115 -(void)invalidate;
117 // Partial invalidators invalidate only some ivars. They are guaranteed to be 
118 // called before the invalidation methods.
119 -(void)partialInvalidator1 __attribute__((annotate("objc_instance_variable_invalidator_partial")));
120 -(void)partialInvalidator2 __attribute__((annotate("objc_instance_variable_invalidator_partial")));
121 @end
123 @interface SomeSubclassInvalidatableObject()
124 @property (assign) SomeInvalidationImplementingObject* Prop8;
125 @property (assign) SomeInvalidationImplementingObject* Prop10;
126 @end
128 @implementation SomeSubclassInvalidatableObject{
129   @private
130   SomeInvalidationImplementingObject *Ivar5;
131   ClassWithInvalidationMethodInCategory *Ivar13;
134 @synthesize Prop7 = _propIvar;
135 @synthesize Prop3 = _Prop3;
136 @synthesize Prop5 = _Prop5;
137 @synthesize Prop4 = _Prop4;
138 @synthesize Prop8 = _Prop8;
139 @synthesize Prop10 = _Prop10;
142 - (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
143   _Prop1 = InObj;
146 - (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
147   _Prop2 = InObj;
149 - (SomeInvalidationImplementingObject*) Prop2 {
150   return _Prop2;
153 @synthesize NProp2 = _NpropIvar;
155 - (void) setNProp1: (NSObject*) InObj {
156   _NProp1 = InObj;
159 - (void) invalidate {
160    [Ivar2 invalidate];
161    self.Prop0 = 0;
162    self.Prop1 = 0;
163    [self setProp2:0];
164    [self setProp3:0];
165    [[self Prop5] invalidate2];
166    [self.Prop4 invalidate];
167    [self.Prop8 invalidate];
168    self.Prop6 = 0;
169    [[self Prop7] invalidate];
171    [_Ivar3 description]; 
172    NSLog(@"%@", _Ivar4);
173    [super invalidate];
175 #if RUN_IVAR_INVALIDATION
176 // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated}}
177 // expected-warning@-3 {{Instance variable MultipleProtocols needs to be invalidated}}
178 // expected-warning@-4 {{Instance variable MultInheritance needs to be invalidated}}
179 // expected-warning@-5 {{Property SynthIvarProp needs to be invalidated or set to nil}}
180 // expected-warning@-6 {{Instance variable _Ivar3 needs to be invalidated}}
181 // expected-warning@-7 {{Instance variable _Ivar4 needs to be invalidated}}
182 // expected-warning@-8 {{Instance variable Ivar5 needs to be invalidated or set to nil}}
183 // expected-warning@-9 {{Instance variable Ivar13 needs to be invalidated or set to nil}}
184 #endif
186 -(void)partialInvalidator1 {
187   [Ivar9 invalidate];
188   [_Prop10 invalidate];
191 -(void)partialInvalidator2 {
192   [Ivar11 invalidate];
195 @end
197 // Example, where the same property is inherited through 
198 // the parent and directly through a protocol. If a property backing ivar is 
199 // synthesized in the parent, let the parent invalidate it.
201 @protocol IDEBuildable <NSObject>
202 @property (readonly, strong) id <Invalidation2> ObjB;
203 @end
205 @interface Parent : NSObject <IDEBuildable, Invalidation2> {
206   Invalidation2Class *_ObjB; // Invalidation of ObjB happens in the parent.
208 @end
210 @interface Child: Parent <Invalidation2, IDEBuildable> 
211 @end
213 @implementation Parent{
214   @private
215   Invalidation2Class *Ivar10;
216   Invalidation2Class *Ivar11;
217   Invalidation2Class *Ivar12;
220 @synthesize ObjB = _ObjB;
221 - (void)invalidate{
222   _ObjB = ((void*)0);
223   
224   assert(Ivar10 == 0);
226   if (__builtin_expect(!(Ivar11 == ((void*)0)), 0))
227     assert(0);
229   assert(0 == Ivar12);
232 @end
234 @implementation Child
235 - (void)invalidate{ 
236   // no-warning
238 @end
240 @protocol Invalidation <NSObject>
241 - (void)invalidate __attribute__((annotate("objc_instance_variable_invalidator")));
242 @end
244 @interface Foo : NSObject <Invalidation>
245 @end
247 @class FooBar;
248 @protocol FooBar_Protocol <NSObject>
249 @end
251 @interface MissingInvalidationMethod : Foo <FooBar_Protocol>
252 @property (assign) MissingInvalidationMethod *foobar15_warn;
253 #if RUN_IVAR_INVALIDATION
254 // expected-warning@-2 {{Property foobar15_warn needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod}}
255 #endif
256 @end
257 @implementation MissingInvalidationMethod
258 @end
260 @interface MissingInvalidationMethod2 : Foo <FooBar_Protocol> {
261   Foo *Ivar1;
262 #if RUN_IVAR_INVALIDATION
263 // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for MissingInvalidationMethod2}}
264 #endif
266 @end
267 @implementation MissingInvalidationMethod2
268 @end
270 @interface MissingInvalidationMethodDecl : NSObject {
271   Foo *Ivar1;
272 #if RUN_MISSING_INVALIDATION_METHOD
273 // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is declared for MissingInvalidationMethodDecl}}
274 #endif
276 @end
277 @implementation MissingInvalidationMethodDecl
278 @end
280 @interface MissingInvalidationMethodDecl2 : NSObject {
281 @private
282     Foo *_foo1;
283 #if RUN_MISSING_INVALIDATION_METHOD
284 // expected-warning@-2 {{Instance variable _foo1 needs to be invalidated; no invalidation method is declared for MissingInvalidationMethodDecl2}}
285 #endif
287 @property (strong) Foo *bar1; 
288 @end
289 @implementation MissingInvalidationMethodDecl2
290 @end
292 @interface InvalidatedInPartial : SomeInvalidationImplementingObject {
293   SomeInvalidationImplementingObject *Ivar1; 
294   SomeInvalidationImplementingObject *Ivar2; 
296 -(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
297 @end
298 @implementation InvalidatedInPartial
299 -(void)partialInvalidator {
300   [Ivar1 invalidate];
301   Ivar2 = 0;
303 @end
305 @interface NotInvalidatedInPartial : SomeInvalidationImplementingObject {
306   SomeInvalidationImplementingObject *Ivar1; 
308 -(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
309 -(void)partialInvalidatorCallsPartial __attribute__((annotate("objc_instance_variable_invalidator_partial")));
310 @end
311 @implementation NotInvalidatedInPartial
312 -(void)partialInvalidator {
314 -(void)partialInvalidatorCallsPartial {
315   [self partialInvalidator];
318 -(void)invalidate {
320 #if RUN_IVAR_INVALIDATION
321 // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated or set to nil}}
322 #endif
323 @end
325 @interface SomeNotInvalidatedInPartial : SomeInvalidationImplementingObject {
326   SomeInvalidationImplementingObject *Ivar1;
327   SomeInvalidationImplementingObject *Ivar2;
328 #if RUN_IVAR_INVALIDATION
329   // expected-warning@-2 {{Instance variable Ivar2 needs to be invalidated or set to nil}}
330 #endif
332 -(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
333 -(void)partialInvalidatorCallsPartial __attribute__((annotate("objc_instance_variable_invalidator_partial")));
334 @end
335 @implementation SomeNotInvalidatedInPartial {
336   SomeInvalidationImplementingObject *Ivar3;
337 #if RUN_IVAR_INVALIDATION
338   // expected-warning@-2 {{Instance variable Ivar3 needs to be invalidated or set to nil}}
339 #endif
341 -(void)partialInvalidator {
342   Ivar1 = 0;
344 -(void)partialInvalidatorCallsPartial {
345   [self partialInvalidator];
347 @end
349 @interface OnlyPartialDeclsBase : NSObject
350 -(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
351 @end
352 @implementation OnlyPartialDeclsBase
353 -(void)partialInvalidator {}
354 @end
356 @interface OnlyPartialDecls : OnlyPartialDeclsBase {
357   SomeInvalidationImplementingObject *Ivar1;
358 #if RUN_IVAR_INVALIDATION
359   // expected-warning@-2 {{Instance variable Ivar1 needs to be invalidated; no invalidation method is defined in the @implementation for OnlyPartialDecls}}
360 #endif
362 @end
363 @implementation OnlyPartialDecls
364 @end
366 // False negative.
367 @interface PartialCallsFull : SomeInvalidationImplementingObject {
368   SomeInvalidationImplementingObject *Ivar1;
370 -(void)partialInvalidator __attribute__((annotate("objc_instance_variable_invalidator_partial")));
371 @end
372 @implementation PartialCallsFull
373 -(void)partialInvalidator {
374  [self invalidate];
375 } // TODO: It would be nice to check that the full invalidation method actually invalidates the ivar. 
376 @end