]> granicus.if.org Git - clang/blob - test/Analysis/PR2978.m
b609da5aac24ba678c33c4f7f51e95bb63733ac5
[clang] / test / Analysis / PR2978.m
1 // RUN: %clang_cc1 -analyze -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