brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · a7b6c83 Raw
373 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.SuperDealloc,debug.ExprInspection -analyzer-output=text -verify %s2 3void clang_analyzer_warnIfReached(void);4 5#define nil ((id)0)6 7typedef unsigned long NSUInteger;8@protocol NSObject9- (instancetype)retain;10- (oneway void)release;11@end12 13@interface NSObject <NSObject> { }14- (void)dealloc;15- (instancetype)init;16@end17 18typedef struct objc_selector *SEL;19 20//===------------------------------------------------------------------------===21//  Check that 'self' is not referenced after calling '[super dealloc]'.22 23@interface SuperDeallocThenReleaseIvarClass : NSObject {24  NSObject *_ivar;25}26@end27 28@implementation SuperDeallocThenReleaseIvarClass29- (instancetype)initWithIvar:(NSObject *)ivar {30  self = [super init];31  if (!self)32    return nil;33  _ivar = [ivar retain];34  return self;35}36- (void)dealloc {37  [super dealloc]; // expected-note {{[super dealloc] called here}}38  [_ivar release]; // expected-warning {{Use of instance variable '_ivar' after 'self' has been deallocated}}39  // expected-note@-1 {{Use of instance variable '_ivar' after 'self' has been deallocated}}40}41@end42 43@interface SuperDeallocThenAssignNilToIvarClass : NSObject {44  NSObject *_delegate;45}46@end47 48@implementation SuperDeallocThenAssignNilToIvarClass49- (instancetype)initWithDelegate:(NSObject *)delegate {50  self = [super init];51  if (!self)52    return nil;53  _delegate = delegate;54  return self;55}56- (void)dealloc {57  [super dealloc]; // expected-note {{[super dealloc] called here}}58  _delegate = nil; // expected-warning {{Use of instance variable '_delegate' after 'self' has been deallocated}}59      // expected-note@-1 {{Use of instance variable '_delegate' after 'self' has been deallocated}}60}61@end62 63 64struct SomeStruct {65  int f;66};67 68@interface SuperDeallocThenAssignIvarField : NSObject {69  struct SomeStruct _s;70}71@end72 73@implementation SuperDeallocThenAssignIvarField74- (void)dealloc {75  [super dealloc]; // expected-note {{[super dealloc] called here}}76  _s.f = 7; // expected-warning {{Use of instance variable '_s' after 'self' has been deallocated}}77      // expected-note@-1 {{Use of instance variable '_s' after 'self' has been deallocated}}78}79@end80 81@interface OtherClassWithIvar {82@public83  int _otherIvar;84}85@end;86 87@interface SuperDeallocThenAssignIvarIvar : NSObject {88  OtherClassWithIvar *_ivar;89}90@end91 92@implementation SuperDeallocThenAssignIvarIvar93- (void)dealloc {94  [super dealloc]; // expected-note {{[super dealloc] called here}}95  _ivar->_otherIvar = 7; // expected-warning {{Use of instance variable '_ivar' after 'self' has been deallocated}}96      // expected-note@-1 {{Use of instance variable '_ivar' after 'self' has been deallocated}}97}98@end99 100@interface SuperDeallocThenAssignSelfIvar : NSObject {101  NSObject *_ivar;102}103@end104 105@implementation SuperDeallocThenAssignSelfIvar106- (void)dealloc {107  [super dealloc]; // expected-note {{[super dealloc] called here}}108  self->_ivar = nil; // expected-warning {{Use of instance variable '_ivar' after 'self' has been deallocated}}109      // expected-note@-1 {{Use of instance variable '_ivar' after 'self' has been deallocated}}110}111@end112 113@interface SuperDeallocThenReleasePropertyClass : NSObject { }114@property (retain) NSObject *ivar;115@end116 117@implementation SuperDeallocThenReleasePropertyClass118- (instancetype)initWithProperty:(NSObject *)ivar {119  self = [super init];120  if (!self)121    return nil;122  self.ivar = ivar;123  return self;124}125- (void)dealloc {126  [super dealloc]; // expected-note {{[super dealloc] called here}}127  self.ivar = nil; // expected-warning {{Use of 'self' after it has been deallocated}}128      // expected-note@-1 {{Use of 'self' after it has been deallocated}}129}130@end131 132@interface SuperDeallocThenAssignNilToPropertyClass : NSObject { }133@property (assign) NSObject *delegate;134@end135 136@implementation SuperDeallocThenAssignNilToPropertyClass137- (instancetype)initWithDelegate:(NSObject *)delegate {138  self = [super init];139  if (!self)140    return nil;141  self.delegate = delegate;142  return self;143}144- (void)dealloc {145  [super dealloc]; // expected-note {{[super dealloc] called here}}146  self.delegate = nil; // expected-warning {{Use of 'self' after it has been deallocated}}147      // expected-note@-1 {{Use of 'self' after it has been deallocated}}148}149@end150 151@interface SuperDeallocThenCallInstanceMethodClass : NSObject { }152- (void)_invalidate;153@end154 155@implementation SuperDeallocThenCallInstanceMethodClass156- (void)_invalidate {157}158- (void)dealloc {159  [super dealloc]; // expected-note {{[super dealloc] called here}}160  [self _invalidate]; // expected-warning {{Use of 'self' after it has been deallocated}}161      // expected-note@-1 {{Use of 'self' after it has been deallocated}}162}163@end164 165@interface SuperDeallocThenCallNonObjectiveCMethodClass : NSObject { }166@end167 168static void _invalidate(NSObject *object) {169  (void)object;170}171 172@implementation SuperDeallocThenCallNonObjectiveCMethodClass173- (void)dealloc {174  [super dealloc]; // expected-note {{[super dealloc] called here}}175  _invalidate(self); // expected-warning {{Use of 'self' after it has been deallocated}}176      // expected-note@-1 {{Use of 'self' after it has been deallocated}}177}178@end179 180@interface SuperDeallocThenCallObjectiveClassMethodClass : NSObject { }181@end182 183@implementation SuperDeallocThenCallObjectiveClassMethodClass184+ (void) invalidate:(id)arg; {185}186 187- (void)dealloc {188  [super dealloc]; // expected-note {{[super dealloc] called here}}189  [SuperDeallocThenCallObjectiveClassMethodClass invalidate:self]; // expected-warning {{Use of 'self' after it has been deallocated}}190      // expected-note@-1 {{Use of 'self' after it has been deallocated}}191}192@end193 194@interface TwoSuperDeallocCallsClass : NSObject {195  NSObject *_ivar;196}197- (void)_invalidate;198@end199 200@implementation TwoSuperDeallocCallsClass201- (void)_invalidate {202}203- (void)dealloc {204  if (_ivar) { // expected-note {{Assuming the condition is false}} expected-note {{Taking false branch}}205    [_ivar release];206    [super dealloc];207    return;208  }209  [super dealloc];    // expected-note {{[super dealloc] called here}}210  [self _invalidate]; // expected-warning {{Use of 'self' after it has been deallocated}}211      // expected-note@-1 {{Use of 'self' after it has been deallocated}}212}213@end214 215//===------------------------------------------------------------------------===216// Warn about calling [super dealloc] twice due to missing return statement.217 218@interface MissingReturnCausesDoubleSuperDeallocClass : NSObject {219  NSObject *_ivar;220}221@end222 223@implementation MissingReturnCausesDoubleSuperDeallocClass224- (void)dealloc {225  if (_ivar) { // expected-note {{Assuming the condition is true}} expected-note {{Taking true branch}}226    [_ivar release];227    [super dealloc]; // expected-note {{[super dealloc] called here}}228    // return;229  }230  [super dealloc]; // expected-warning{{[super dealloc] should not be called multiple times}}231  // expected-note@-1{{[super dealloc] should not be called multiple times}}232}233@end234 235//===------------------------------------------------------------------------===236// Warn about calling [super dealloc] twice in two different methods.237 238@interface SuperDeallocInOtherMethodClass : NSObject {239  NSObject *_ivar;240}241- (void)_cleanup;242@end243 244@implementation SuperDeallocInOtherMethodClass245- (void)_cleanup {246  [_ivar release];247  [super dealloc]; // expected-note {{[super dealloc] called here}}248}249- (void)dealloc {250  [self _cleanup]; // expected-note {{Calling '_cleanup'}}251  //expected-note@-1 {{Returning from '_cleanup'}}252  [super dealloc]; // expected-warning {{[super dealloc] should not be called multiple times}}253  // expected-note@-1 {{[super dealloc] should not be called multiple times}}254}255@end256 257//===------------------------------------------------------------------------===258// Do not warn about calling [super dealloc] recursively for different objects259// of the same type with custom retain counting.260//261// A class that contains an ivar of itself with custom retain counting (such262// as provided by _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN) can generate263// a false positive that [super dealloc] is called twice if each object instance264// is not tracked separately by the checker. This test case is just a simple265// approximation to trigger the false positive.266 267@class ClassWithOwnIvarInstanceClass;268@interface ClassWithOwnIvarInstanceClass : NSObject {269  ClassWithOwnIvarInstanceClass *_ivar;270  NSUInteger _retainCount;271}272@end273 274@implementation ClassWithOwnIvarInstanceClass275- (instancetype)retain {276  ++_retainCount;277  return self;278}279- (oneway void)release {280  --_retainCount;281  if (!_retainCount)282    [self dealloc];283}284- (void)dealloc {285  [_ivar release];286  [super dealloc]; // no warning: different instances of same class287}288@end289 290//===------------------------------------------------------------------------===291// Do not warn about calling [super dealloc] twice if +dealloc is a class292// method.293 294@interface SuperDeallocClassMethodIgnoredClass : NSObject { }295+ (void)dealloc;296@end297 298@implementation SuperDeallocClassMethodIgnoredClass299+ (void)dealloc { }300@end301 302@interface SuperDeallocClassMethodIgnoredSubClass : NSObject { }303+ (void)dealloc;304@end305 306@implementation SuperDeallocClassMethodIgnoredSubClass307+ (void)dealloc {308  [super dealloc];309  [super dealloc]; // no warning: class method310}311@end312 313//===------------------------------------------------------------------------===314// Do not warn about calling [super dealloc] twice if when the analyzer has315// inlined the call to its super deallocator.316 317@interface SuperClassCallingSuperDealloc : NSObject {318  NSObject *_ivar;319}320@end321 322@implementation SuperClassCallingSuperDealloc323- (void)dealloc; {324  [_ivar release]; // no-warning325 326  [super dealloc];327}328@end329 330@interface SubclassCallingSuperDealloc : SuperClassCallingSuperDealloc331@end332 333@implementation SubclassCallingSuperDealloc334- (void)dealloc; {335  [super dealloc];336}337@end338 339//===------------------------------------------------------------------------===340// Treat calling [super dealloc] twice as as a sink.341 342@interface CallingSuperDeallocTwiceIsSink : NSObject343@end344 345@implementation CallingSuperDeallocTwiceIsSink346- (void)dealloc; {347  [super dealloc]; // expected-note {{[super dealloc] called here}}348  [super dealloc]; // expected-warning {{[super dealloc] should not be called multiple times}}349  // expected-note@-1 {{[super dealloc] should not be called multiple times}}350 351  clang_analyzer_warnIfReached(); // no-warning352}353@end354 355 356//===------------------------------------------------------------------------===357// Test path notes with intervening method call on self.358 359@interface InterveningMethodCallOnSelf : NSObject360@end361 362@implementation InterveningMethodCallOnSelf363- (void)anotherMethod {364}365 366- (void)dealloc; {367  [super dealloc]; // expected-note {{[super dealloc] called here}}368  [self anotherMethod]; // expected-warning {{Use of 'self' after it has been deallocated}}369      // expected-note@-1 {{Use of 'self' after it has been deallocated}}370  [super dealloc];371}372@end373