1// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
2
3// Tests for the checker which checks missing/extra ivar 'release' calls
4// in dealloc.
5
6@interface NSObject
7- (void)release;
8- (void)dealloc;
9@end
10
11@interface MyClass : NSObject {
12@private
13  id _X;
14  id _Y;
15  id _Z;
16  id _K;
17  id _L;
18  id _N;
19  id _M;
20  id _P;
21  id _Q;
22  id _R;
23  id _S;
24  id _V;
25  id _W;
26
27  MyClass *_other;
28
29  id _nonPropertyIvar;
30}
31@property(retain) id X;
32@property(retain) id Y;
33@property(assign) id Z;
34@property(assign) id K;
35@property(weak) id L;
36@property(readonly) id N;
37@property(retain) id M;
38@property(weak) id P;
39@property(weak) id Q;
40@property(retain) id R;
41@property(weak, readonly) id S;
42
43@property(assign, readonly) id T; // Shadowed in class extension
44@property(assign) id U;
45
46@property(retain) id V;
47@property(retain) id W;
48-(id) O;
49-(void) setO: (id) arg;
50@end
51
52@interface MyClass ()
53// Shadows T to make it readwrite internally but readonly externally.
54@property(assign, readwrite) id T;
55@end
56
57@implementation MyClass
58@synthesize X = _X;
59@synthesize Y = _Y;
60@synthesize Z = _Z;
61@synthesize K = _K;
62@synthesize L = _L;
63@synthesize N = _N;
64@synthesize M = _M;
65@synthesize Q = _Q;
66@synthesize R = _R;
67@synthesize V = _V;
68@synthesize W = _W;
69
70-(id) O{ return 0; }
71-(void) setO:(id)arg { }
72
73
74-(void) releaseInHelper {
75  [_R release]; // no-warning
76  _R = @"Hi";
77}
78
79- (void)dealloc
80{
81
82  [_X release];
83  [_Z release]; // expected-warning{{The '_Z' ivar in 'MyClass' was synthesized for an assign, readwrite property but was released in 'dealloc'}}
84  [_T release]; // no-warning
85
86  [_other->_Z release]; // no-warning
87  [_N release];
88
89  self.M = 0; // This will release '_M'
90  [self setV:0]; // This will release '_V'
91  [self setW:@"newW"]; // This will release '_W', but retain the new value
92
93  [_S release]; // expected-warning {{The '_S' ivar in 'MyClass' was synthesized for a weak property but was released in 'dealloc'}}
94
95  self.O = 0; // no-warning
96
97  [_Q release]; // expected-warning {{The '_Q' ivar in 'MyClass' was synthesized for a weak property but was released in 'dealloc'}}
98
99  self.P = 0;
100
101  [self releaseInHelper];
102
103  [_nonPropertyIvar release]; // no-warning
104
105  // Silly, but not an error.
106  if (!_U)
107    [_U release];
108
109  [super dealloc];
110  // expected-warning@-1{{The '_Y' ivar in 'MyClass' was retained by a synthesized property but not released before '[super dealloc]'}}
111  // expected-warning@-2{{The '_W' ivar in 'MyClass' was retained by a synthesized property but not released before '[super dealloc]'}}
112
113}
114
115@end
116
117