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
11typedef 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
22typedef 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 {
138IBOutlet 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