117 lines
2.5 KiB
Objective-C
117 lines
2.5 KiB
Objective-C
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
|
|
|
|
// Tests for the checker which checks missing/extra ivar 'release' calls
|
|
// in dealloc.
|
|
|
|
@interface NSObject
|
|
- (void)release;
|
|
- (void)dealloc;
|
|
@end
|
|
|
|
@interface MyClass : NSObject {
|
|
@private
|
|
id _X;
|
|
id _Y;
|
|
id _Z;
|
|
id _K;
|
|
id _L;
|
|
id _N;
|
|
id _M;
|
|
id _P;
|
|
id _Q;
|
|
id _R;
|
|
id _S;
|
|
id _V;
|
|
id _W;
|
|
|
|
MyClass *_other;
|
|
|
|
id _nonPropertyIvar;
|
|
}
|
|
@property(retain) id X;
|
|
@property(retain) id Y;
|
|
@property(assign) id Z;
|
|
@property(assign) id K;
|
|
@property(weak) id L;
|
|
@property(readonly) id N;
|
|
@property(retain) id M;
|
|
@property(weak) id P;
|
|
@property(weak) id Q;
|
|
@property(retain) id R;
|
|
@property(weak, readonly) id S;
|
|
|
|
@property(assign, readonly) id T; // Shadowed in class extension
|
|
@property(assign) id U;
|
|
|
|
@property(retain) id V;
|
|
@property(retain) id W;
|
|
-(id) O;
|
|
-(void) setO: (id) arg;
|
|
@end
|
|
|
|
@interface MyClass ()
|
|
// Shadows T to make it readwrite internally but readonly externally.
|
|
@property(assign, readwrite) id T;
|
|
@end
|
|
|
|
@implementation MyClass
|
|
@synthesize X = _X;
|
|
@synthesize Y = _Y;
|
|
@synthesize Z = _Z;
|
|
@synthesize K = _K;
|
|
@synthesize L = _L;
|
|
@synthesize N = _N;
|
|
@synthesize M = _M;
|
|
@synthesize Q = _Q;
|
|
@synthesize R = _R;
|
|
@synthesize V = _V;
|
|
@synthesize W = _W;
|
|
|
|
-(id) O{ return 0; }
|
|
-(void) setO:(id)arg { }
|
|
|
|
|
|
-(void) releaseInHelper {
|
|
[_R release]; // no-warning
|
|
_R = @"Hi";
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
|
|
[_X release];
|
|
[_Z release]; // expected-warning{{The '_Z' ivar in 'MyClass' was synthesized for an assign, readwrite property but was released in 'dealloc'}}
|
|
[_T release]; // no-warning
|
|
|
|
[_other->_Z release]; // no-warning
|
|
[_N release];
|
|
|
|
self.M = 0; // This will release '_M'
|
|
[self setV:0]; // This will release '_V'
|
|
[self setW:@"newW"]; // This will release '_W', but retain the new value
|
|
|
|
[_S release]; // expected-warning {{The '_S' ivar in 'MyClass' was synthesized for a weak property but was released in 'dealloc'}}
|
|
|
|
self.O = 0; // no-warning
|
|
|
|
[_Q release]; // expected-warning {{The '_Q' ivar in 'MyClass' was synthesized for a weak property but was released in 'dealloc'}}
|
|
|
|
self.P = 0;
|
|
|
|
[self releaseInHelper];
|
|
|
|
[_nonPropertyIvar release]; // no-warning
|
|
|
|
// Silly, but not an error.
|
|
if (!_U)
|
|
[_U release];
|
|
|
|
[super dealloc];
|
|
// expected-warning@-1{{The '_Y' ivar in 'MyClass' was retained by a synthesized property but not released before '[super dealloc]'}}
|
|
// expected-warning@-2{{The '_W' ivar in 'MyClass' was retained by a synthesized property but not released before '[super dealloc]'}}
|
|
|
|
}
|
|
|
|
@end
|
|
|