objc_invalidation.m revision 31f69cc770888ec0f0f7012212e5df7979aba4f3
1// 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;
13-(id)description;
14@end
15@class NSString;
16
17extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
18
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")));
29- (void) invalidate2 __attribute__((annotate("objc_instance_variable_invalidator")));
30@end
31
32@interface Invalidation2Class <Invalidation2>
33@end
34
35@interface Invalidation1Class <Invalidation1>
36@end
37
38@interface SomeInvalidationImplementingObject: NSObject <Invalidation3, Invalidation2> {
39  SomeInvalidationImplementingObject *ObjA; // invalidation in the parent
40}
41@end
42
43@implementation SomeInvalidationImplementingObject
44- (void)invalidate{
45  ObjA = 0;
46}
47- (void)invalidate2 {
48  [self invalidate];
49}
50@end
51
52@interface SomeSubclassInvalidatableObject : SomeInvalidationImplementingObject {
53  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
66  
67  // No warnings on these as they are not invalidatable.
68  NSObject *NIvar1;
69  NSObject *NObj2;
70  NSObject *_NProp1;
71  NSObject *_NpropIvar;
72}
73
74@property (assign) SomeInvalidationImplementingObject* Prop0;
75@property (nonatomic, assign) SomeInvalidationImplementingObject* Prop1;
76@property (assign) SomeInvalidationImplementingObject* Prop2;
77@property (assign) SomeInvalidationImplementingObject* Prop3;
78@property (assign) SomeInvalidationImplementingObject *Prop5;
79@property (assign) SomeInvalidationImplementingObject *Prop4;
80
81@property (assign) SomeInvalidationImplementingObject* Prop6; // automatically synthesized prop
82@property (assign) SomeInvalidationImplementingObject* Prop7; // automatically synthesized prop
83@property (assign) SomeInvalidationImplementingObject *SynthIvarProp;
84
85@property (assign) NSObject* NProp0;
86@property (nonatomic, assign) NSObject* NProp1;
87@property (assign) NSObject* NProp2;
88
89-(void)setProp1: (SomeInvalidationImplementingObject*) InO;
90-(void)setNProp1: (NSObject*) InO;
91
92-(void)invalidate;
93
94@end
95
96@implementation SomeSubclassInvalidatableObject
97
98@synthesize Prop7 = _propIvar;
99@synthesize Prop3 = _Prop3;
100@synthesize Prop5 = _Prop5;
101@synthesize Prop4 = _Prop4;
102
103
104- (void) setProp1: (SomeInvalidationImplementingObject*) InObj {
105  _Prop1 = InObj;
106}
107
108- (void) setProp2: (SomeInvalidationImplementingObject*) InObj {
109  _Prop2 = InObj;
110}
111- (SomeInvalidationImplementingObject*) Prop2 {
112  return _Prop2;
113}
114
115@synthesize NProp2 = _NpropIvar;
116
117- (void) setNProp1: (NSObject*) InObj {
118  _NProp1 = InObj;
119}
120
121- (void) invalidate {
122   [Ivar2 invalidate];
123   self.Prop0 = 0;
124   self.Prop1 = 0;
125   [self setProp2:0];
126   [self setProp3:0];
127   [[self Prop5] invalidate2];
128   [self.Prop4 invalidate];
129   self.Prop6 = 0;
130   [[self Prop7] invalidate];
131
132   [_Ivar3 description]; 
133   NSLog(@"%@", _Ivar4);
134   [super invalidate];
135}
136// expected-warning@-1 {{Instance variable Ivar1 needs to be invalidated}}
137 // expected-warning@-2 {{Instance variable MultipleProtocols needs to be invalidated}}
138 // expected-warning@-3 {{Instance variable MultInheritance needs to be invalidated}}
139 // expected-warning@-4 {{Property SynthIvarProp needs to be invalidated}}
140 // expected-warning@-5 {{Instance variable _Ivar3 needs to be invalidated}}
141 // expected-warning@-6 {{Instance variable _Ivar4 needs to be invalidated}}
142@end
143