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