| // 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 |