1 | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s |
2 | // RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s |
3 | |
4 | #define NON_ARC !__has_feature(objc_arc) |
5 | |
6 | // No diagnostics expected under ARC. |
7 | #if !NON_ARC |
8 | // expected-no-diagnostics |
9 | #endif |
10 | |
11 | typedef signed char BOOL; |
12 | @protocol NSObject |
13 | - (BOOL)isEqual:(id)object; |
14 | - (Class)class; |
15 | @end |
16 | |
17 | @interface NSObject <NSObject> {} |
18 | - (void)dealloc; |
19 | - (id)init; |
20 | @end |
21 | |
22 | typedef struct objc_selector *SEL; |
23 | |
24 | //===------------------------------------------------------------------------=== |
25 | // Do not warn about missing -dealloc method. Not enough context to know |
26 | // whether the ivar is retained or not. |
27 | |
28 | @interface MissingDeallocWithIvar : NSObject { |
29 | NSObject *_ivar; |
30 | } |
31 | @end |
32 | |
33 | @implementation MissingDeallocWithIvar |
34 | @end |
35 | |
36 | //===------------------------------------------------------------------------=== |
37 | // Do not warn about missing -dealloc method. These properties are not |
38 | // retained or synthesized. |
39 | |
40 | @interface MissingDeallocWithIntProperty : NSObject |
41 | @property (assign) int ivar; |
42 | @end |
43 | |
44 | @implementation MissingDeallocWithIntProperty |
45 | @end |
46 | |
47 | @interface MissingDeallocWithSELProperty : NSObject |
48 | @property (assign) SEL ivar; |
49 | @end |
50 | |
51 | @implementation MissingDeallocWithSELProperty |
52 | @end |
53 | |
54 | //===------------------------------------------------------------------------=== |
55 | // Warn about missing -dealloc method. |
56 | |
57 | @interface MissingDeallocWithCopyProperty : NSObject |
58 | @property (copy) NSObject *ivar; |
59 | @end |
60 | |
61 | #if NON_ARC |
62 | // expected-warning@+2{{'MissingDeallocWithCopyProperty' lacks a 'dealloc' instance method but must release '_ivar'}} |
63 | #endif |
64 | @implementation MissingDeallocWithCopyProperty |
65 | @end |
66 | |
67 | @interface MissingDeallocWithRetainProperty : NSObject |
68 | @property (retain) NSObject *ivar; |
69 | @end |
70 | |
71 | #if NON_ARC |
72 | // expected-warning@+2{{'MissingDeallocWithRetainProperty' lacks a 'dealloc' instance method but must release '_ivar'}} |
73 | #endif |
74 | @implementation MissingDeallocWithRetainProperty |
75 | @end |
76 | |
77 | @interface MissingDeallocWithMultipleProperties : NSObject |
78 | @property (retain) NSObject *ivar1; |
79 | @property (retain) NSObject *ivar2; |
80 | @end |
81 | |
82 | #if NON_ARC |
83 | // expected-warning@+2{{'MissingDeallocWithMultipleProperties' lacks a 'dealloc' instance method but must release '_ivar1' and others}} |
84 | #endif |
85 | @implementation MissingDeallocWithMultipleProperties |
86 | @end |
87 | |
88 | @interface MissingDeallocWithIVarAndRetainProperty : NSObject { |
89 | NSObject *_ivar2; |
90 | } |
91 | @property (retain) NSObject *ivar1; |
92 | @end |
93 | |
94 | #if NON_ARC |
95 | // expected-warning@+2{{'MissingDeallocWithIVarAndRetainProperty' lacks a 'dealloc' instance method but must release '_ivar1'}} |
96 | #endif |
97 | @implementation MissingDeallocWithIVarAndRetainProperty |
98 | @end |
99 | |
100 | @interface MissingDeallocWithReadOnlyRetainedProperty : NSObject |
101 | @property (readonly,retain) NSObject *ivar; |
102 | @end |
103 | |
104 | #if NON_ARC |
105 | // expected-warning@+2{{'MissingDeallocWithReadOnlyRetainedProperty' lacks a 'dealloc' instance method but must release '_ivar'}} |
106 | #endif |
107 | @implementation MissingDeallocWithReadOnlyRetainedProperty |
108 | @end |
109 | |
110 | |
111 | //===------------------------------------------------------------------------=== |
112 | // Don't warn about iVars that are selectors. |
113 | |
114 | @interface TestSELs : NSObject { |
115 | SEL a; |
116 | SEL b; |
117 | } |
118 | |
119 | @end |
120 | |
121 | @implementation TestSELs |
122 | - (id)init { |
123 | if( (self = [super init]) ) { |
124 | a = @selector(a); |
125 | b = @selector(b); |
126 | } |
127 | |
128 | return self; |
129 | } |
130 | @end |
131 | |
132 | //===------------------------------------------------------------------------=== |
133 | // Don't warn about iVars that are IBOutlets. |
134 | |
135 | @class NSWindow; |
136 | |
137 | @interface HasOutlet : NSObject { |
138 | IBOutlet NSWindow *window; |
139 | } |
140 | @end |
141 | |
142 | @implementation HasOutlet // no-warning |
143 | @end |
144 | |
145 | //===------------------------------------------------------------------------=== |
146 | // PR 3187: http://llvm.org/bugs/show_bug.cgi?id=3187 |
147 | // - Disable the missing -dealloc check for classes that subclass SenTestCase |
148 | |
149 | @class NSString; |
150 | |
151 | @interface SenTestCase : NSObject {} |
152 | @end |
153 | |
154 | @interface MyClassTest : SenTestCase { |
155 | NSString *resourcePath; |
156 | } |
157 | |
158 | @property (retain) NSObject *ivar; |
159 | |
160 | @end |
161 | |
162 | @interface NSBundle : NSObject {} |
163 | + (NSBundle *)bundleForClass:(Class)aClass; |
164 | - (NSString *)resourcePath; |
165 | @end |
166 | |
167 | @implementation MyClassTest |
168 | - (void)setUp { |
169 | resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath]; |
170 | } |
171 | - (void)testXXX { |
172 | // do something which uses resourcepath |
173 | } |
174 | @end |
175 | |
176 | //===------------------------------------------------------------------------=== |
177 | // Don't warn for clases that aren't subclasses of NSObject |
178 | |
179 | __attribute__((objc_root_class)) |
180 | @interface NonNSObjectMissingDealloc |
181 | @property (retain) NSObject *ivar; |
182 | @end |
183 | @implementation NonNSObjectMissingDealloc |
184 | @end |
185 | |
186 | |
187 | //===------------------------------------------------------------------------=== |
188 | // Don't crash on calls to dealloc as a class method. |
189 | |
190 | @interface DeallocingClass : NSObject {} |
191 | @end |
192 | @implementation DeallocingClass |
193 | - (void)dealloc { |
194 | [DeallocingClass dealloc]; // FIXME: Should we warn on this specifically? |
195 | } |
196 | #if NON_ARC |
197 | // expected-warning@-2{{method possibly missing a [super dealloc] call}} |
198 | #endif |
199 | @end |
200 | |