llvm-capstone/clang/test/Analysis/MissingDealloc.m
Artem Dergachev 0ce45fae72 [analyzer] ObjCDealloc: Fix a crash when a class attempts to deallocate a class.
The checker wasn't prepared to see the dealloc message sent to the class itself
rather than to an instance, as if it was +dealloc.

Additionally, it wasn't prepared for pure-unknown or undefined self values.
The new guard covers that as well, but it is annoying to test because
both kinds of values shouldn't really appear and we generally want to
get rid of all of them (by modeling unknown values with symbols and
by warning on use of undefined values before they are used).

The CHECK: directive for FileCheck at the end of the test looks useless,
so i removed it.

Differential Revision: https://reviews.llvm.org/D55680

llvm-svn: 349228
2018-12-15 02:09:02 +00:00

200 lines
4.9 KiB
Objective-C

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