// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
#define NON_ARC !__has_feature(objc_arc)
// No diagnostics expected under ARC.
#if !NON_ARC
// expected-no-diagnostics
#endif
typedef signed char BOOL;
@protocol NSObject
- (BOOL)isEqual:(id)object;
- (Class)class;
@end
@interface NSObject <NSObject> {}
- (void)dealloc;
- (id)init;
@end
typedef struct objc_selector *SEL;
//===------------------------------------------------------------------------===
// Do not warn about missing -dealloc method. Not enough context to know
// whether the ivar is retained or not.
@interface MissingDeallocWithIvar : NSObject {
NSObject *_ivar;
}
@end
@implementation MissingDeallocWithIvar
@end
//===------------------------------------------------------------------------===
// Do not warn about missing -dealloc method. These properties are not
// retained or synthesized.
@interface MissingDeallocWithIntProperty : NSObject
@property (assign) int ivar;
@end
@implementation MissingDeallocWithIntProperty
@end
@interface MissingDeallocWithSELProperty : NSObject
@property (assign) SEL ivar;
@end
@implementation MissingDeallocWithSELProperty
@end
//===------------------------------------------------------------------------===
// Warn about missing -dealloc method.
@interface MissingDeallocWithCopyProperty : NSObject
@property (copy) NSObject *ivar;
@end
#if NON_ARC
// expected-warning@+2{{'MissingDeallocWithCopyProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
#endif
@implementation MissingDeallocWithCopyProperty
@end
@interface MissingDeallocWithRetainProperty : NSObject
@property (retain) NSObject *ivar;
@end
#if NON_ARC
// expected-warning@+2{{'MissingDeallocWithRetainProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
#endif
@implementation MissingDeallocWithRetainProperty
@end
@interface MissingDeallocWithMultipleProperties : NSObject
@property (retain) NSObject *ivar1;
@property (retain) NSObject *ivar2;
@end
#if NON_ARC
// expected-warning@+2{{'MissingDeallocWithMultipleProperties' lacks a 'dealloc' instance method but must release '_ivar1' and others}}
#endif
@implementation MissingDeallocWithMultipleProperties
@end
@interface MissingDeallocWithIVarAndRetainProperty : NSObject {
NSObject *_ivar2;
}
@property (retain) NSObject *ivar1;
@end
#if NON_ARC
// expected-warning@+2{{'MissingDeallocWithIVarAndRetainProperty' lacks a 'dealloc' instance method but must release '_ivar1'}}
#endif
@implementation MissingDeallocWithIVarAndRetainProperty
@end
@interface MissingDeallocWithReadOnlyRetainedProperty : NSObject
@property (readonly,retain) NSObject *ivar;
@end
#if NON_ARC
// expected-warning@+2{{'MissingDeallocWithReadOnlyRetainedProperty' lacks a 'dealloc' instance method but must release '_ivar'}}
#endif
@implementation MissingDeallocWithReadOnlyRetainedProperty
@end
//===------------------------------------------------------------------------===
// Don't warn about iVars that are selectors.
@interface TestSELs : NSObject {
SEL a;
SEL b;
}
@end
@implementation TestSELs
- (id)init {
if( (self = [super init]) ) {
a = @selector(a);
b = @selector(b);
}
return self;
}
@end
//===------------------------------------------------------------------------===
// Don't warn about iVars that are IBOutlets.
@class NSWindow;
@interface HasOutlet : NSObject {
IBOutlet NSWindow *window;
}
@end
@implementation HasOutlet // no-warning
@end
//===------------------------------------------------------------------------===
// PR 3187: http://llvm.org/bugs/show_bug.cgi?id=3187
// - Disable the missing -dealloc check for classes that subclass SenTestCase
@class NSString;
@interface SenTestCase : NSObject {}
@end
@interface MyClassTest : SenTestCase {
NSString *resourcePath;
}
@property (retain) NSObject *ivar;
@end
@interface NSBundle : NSObject {}
+ (NSBundle *)bundleForClass:(Class)aClass;
- (NSString *)resourcePath;
@end
@implementation MyClassTest
- (void)setUp {
resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
}
- (void)testXXX {
// do something which uses resourcepath
}
@end
//===------------------------------------------------------------------------===
// Don't warn for clases that aren't subclasses of NSObject
__attribute__((objc_root_class))
@interface NonNSObjectMissingDealloc
@property (retain) NSObject *ivar;
@end
@implementation NonNSObjectMissingDealloc
@end
//===------------------------------------------------------------------------===
// Don't crash on calls to dealloc as a class method.
@interface DeallocingClass : NSObject {}
@end
@implementation DeallocingClass
- (void)dealloc {
[DeallocingClass dealloc]; // FIXME: Should we warn on this specifically?
}
#if NON_ARC
// expected-warning@-2{{method possibly missing a [super dealloc] call}}
#endif
@end