Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s
      3 
      4 #include "Inputs/system-header-simulator-for-objc-dealloc.h"
      5 
      6 #define NON_ARC !__has_feature(objc_arc)
      7 
      8 #if NON_ARC
      9 #define WEAK_ON_ARC
     10 #else
     11 #define WEAK_ON_ARC __weak
     12 #endif
     13 
     14 // No diagnostics expected under ARC.
     15 #if !NON_ARC
     16   // expected-no-diagnostics
     17 #endif
     18 
     19 // Do not warn about missing release in -dealloc for ivars.
     20 
     21 @interface MyIvarClass1 : NSObject {
     22   NSObject *_ivar;
     23 }
     24 @end
     25 
     26 @implementation MyIvarClass1
     27 - (instancetype)initWithIvar:(NSObject *)ivar
     28 {
     29   self = [super init];
     30   if (!self)
     31     return nil;
     32 #if NON_ARC
     33   _ivar = [ivar retain];
     34 #endif
     35   return self;
     36 }
     37 - (void)dealloc
     38 {
     39 #if NON_ARC
     40   [super dealloc];
     41 #endif
     42 }
     43 @end
     44 
     45 @interface MyIvarClass2 : NSObject {
     46   NSObject *_ivar;
     47 }
     48 - (NSObject *)ivar;
     49 - (void)setIvar:(NSObject *)ivar;
     50 @end
     51 
     52 @implementation MyIvarClass2
     53 - (instancetype)init
     54 {
     55   self = [super init];
     56   return self;
     57 }
     58 - (void)dealloc
     59 {
     60 #if NON_ARC
     61   [super dealloc];
     62 #endif
     63 }
     64 - (NSObject *)ivar
     65 {
     66   return _ivar;
     67 }
     68 - (void)setIvar:(NSObject *)ivar
     69 {
     70 #if NON_ARC
     71   [_ivar release];
     72   _ivar = [ivar retain];
     73 #else
     74  _ivar = ivar;
     75 #endif
     76 }
     77 @end
     78 
     79 // Warn about missing release in -dealloc for properties.
     80 
     81 @interface MyPropertyClass1 : NSObject
     82 @property (copy) NSObject *ivar;
     83 @end
     84 
     85 @implementation MyPropertyClass1
     86 - (void)dealloc
     87 {
     88 #if NON_ARC
     89   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass1' was copied by a synthesized property but not released before '[super dealloc]'}}
     90 #endif
     91 }
     92 @end
     93 
     94 @interface MyPropertyClass2 : NSObject
     95 @property (retain) NSObject *ivar;
     96 @end
     97 
     98 @implementation MyPropertyClass2
     99 - (void)dealloc
    100 {
    101 #if NON_ARC
    102   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass2' was retained by a synthesized property but not released before '[super dealloc]'}}
    103 #endif
    104 }
    105 @end
    106 
    107 @interface MyPropertyClass3 : NSObject {
    108   NSObject *_ivar;
    109 }
    110 @property (retain) NSObject *ivar;
    111 @end
    112 
    113 @implementation MyPropertyClass3
    114 @synthesize ivar = _ivar;
    115 - (void)dealloc
    116 {
    117 #if NON_ARC
    118   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClass3' was retained by a synthesized property but not released before '[super dealloc]'}}
    119 #endif
    120 }
    121 
    122 @end
    123 
    124 @interface MyPropertyClass4 : NSObject {
    125   void (^_blockPropertyIvar)(void);
    126 }
    127 @property (copy) void (^blockProperty)(void);
    128 @property (copy) void (^blockProperty2)(void);
    129 @property (copy) void (^blockProperty3)(void);
    130 
    131 @end
    132 
    133 @implementation MyPropertyClass4
    134 @synthesize blockProperty = _blockPropertyIvar;
    135 - (void)dealloc
    136 {
    137 #if NON_ARC
    138   [_blockProperty2 release];
    139   Block_release(_blockProperty3);
    140 
    141   [super dealloc]; // expected-warning {{The '_blockPropertyIvar' ivar in 'MyPropertyClass4' was copied by a synthesized property but not released before '[super dealloc]'}}
    142 #endif
    143 }
    144 @end
    145 
    146 @interface MyPropertyClass5 : NSObject {
    147   WEAK_ON_ARC NSObject *_ivar;
    148 }
    149 @property (weak) NSObject *ivar;
    150 @end
    151 
    152 @implementation MyPropertyClass5
    153 @synthesize ivar = _ivar;
    154 - (void)dealloc
    155 {
    156 #if NON_ARC
    157   [super dealloc]; // no-warning because it is a weak property
    158 #endif
    159 }
    160 @end
    161 
    162 @interface MyPropertyClassWithReturnInDealloc : NSObject {
    163   NSObject *_ivar;
    164 }
    165 @property (retain) NSObject *ivar;
    166 @end
    167 
    168 @implementation MyPropertyClassWithReturnInDealloc
    169 @synthesize ivar = _ivar;
    170 - (void)dealloc
    171 {
    172   return;
    173 #if NON_ARC
    174   // expected-warning@-2{{The '_ivar' ivar in 'MyPropertyClassWithReturnInDealloc' was retained by a synthesized property but not released before '[super dealloc]'}}
    175   [super dealloc];
    176 #endif
    177 }
    178 @end
    179 
    180 @interface MyPropertyClassWithReleaseInOtherInstance : NSObject {
    181   NSObject *_ivar;
    182   MyPropertyClassWithReleaseInOtherInstance *_other;
    183 }
    184 @property (retain) NSObject *ivar;
    185 
    186 -(void)releaseIvars;
    187 @end
    188 
    189 @implementation MyPropertyClassWithReleaseInOtherInstance
    190 @synthesize ivar = _ivar;
    191 
    192 -(void)releaseIvars; {
    193 #if NON_ARC
    194   [_ivar release];
    195 #endif
    196 }
    197 
    198 - (void)dealloc
    199 {
    200   [_other releaseIvars];
    201 #if NON_ARC
    202   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'MyPropertyClassWithReleaseInOtherInstance' was retained by a synthesized property but not released before '[super dealloc]'}}
    203 #endif
    204 }
    205 @end
    206 
    207 @interface MyPropertyClassWithNeitherReturnNorSuperDealloc : NSObject {
    208   NSObject *_ivar;
    209 }
    210 @property (retain) NSObject *ivar;
    211 @end
    212 
    213 @implementation MyPropertyClassWithNeitherReturnNorSuperDealloc
    214 @synthesize ivar = _ivar;
    215 - (void)dealloc
    216 {
    217 }
    218 #if NON_ARC
    219   // expected-warning@-2 {{method possibly missing a [super dealloc] call}} (From Sema)
    220   // expected-warning@-3{{The '_ivar' ivar in 'MyPropertyClassWithNeitherReturnNorSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}}
    221 #endif
    222 @end
    223 
    224 // <rdar://problem/6380411>: 'myproperty' has kind 'assign' and thus the
    225 //  assignment through the setter does not perform a release.
    226 
    227 @interface MyObject : NSObject {
    228   id __unsafe_unretained _myproperty;
    229 }
    230 @property(assign) id myproperty;
    231 @end
    232 
    233 @implementation MyObject
    234 @synthesize myproperty=_myproperty; // no-warning
    235 - (void)dealloc {
    236   // Don't claim that myproperty is released since it the property
    237   // has the 'assign' attribute.
    238   self.myproperty = 0; // no-warning
    239 #if NON_ARC
    240   [super dealloc];
    241 #endif
    242 }
    243 @end
    244 
    245 @interface ClassWithControlFlowInRelease : NSObject {
    246   BOOL _ivar1;
    247 }
    248 @property (retain) NSObject *ivar2;
    249 @end
    250 
    251 @implementation ClassWithControlFlowInRelease
    252 - (void)dealloc; {
    253   if (_ivar1) {
    254     // We really should warn because there is a path through -dealloc on which
    255     // _ivar2 is not released.
    256 #if NON_ARC
    257     [_ivar2 release];
    258 #endif
    259   }
    260 
    261 #if NON_ARC
    262   [super dealloc]; // expected-warning {{The '_ivar2' ivar in 'ClassWithControlFlowInRelease' was retained by a synthesized property but not released before '[super dealloc]'}}
    263 #endif
    264 }
    265 @end
    266 
    267 // Don't warn when the property is nil'd out in -dealloc
    268 
    269 @interface ClassWithNildOutProperty : NSObject
    270 @property (retain) NSObject *ivar;
    271 @property (assign) int *intPtrProp;
    272 @end
    273 
    274 @implementation ClassWithNildOutProperty
    275 - (void)dealloc; {
    276   self.ivar = nil;
    277 
    278   // Make sure to handle setting a non-retainable property to 0.
    279   self.intPtrProp = 0;
    280 #if NON_ARC
    281   [super dealloc];  // no-warning
    282 #endif
    283 }
    284 @end
    285 
    286 // Do warn when the ivar but not the property is nil'd out in -dealloc
    287 
    288 @interface ClassWithNildOutIvar : NSObject
    289 @property (retain) NSObject *ivar;
    290 @end
    291 
    292 @implementation ClassWithNildOutIvar
    293 - (void)dealloc; {
    294   // Oops. Meant self.ivar = nil
    295   _ivar = nil;
    296 
    297 #if NON_ARC
    298   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithNildOutIvar' was retained by a synthesized property but not released before '[super dealloc]'}}
    299 #endif
    300 }
    301 @end
    302 
    303 // Do warn when the ivar is updated to a different value that is then
    304 // released.
    305 
    306 @interface ClassWithUpdatedIvar : NSObject
    307 @property (retain) NSObject *ivar;
    308 @end
    309 
    310 @implementation ClassWithUpdatedIvar
    311 - (void)dealloc; {
    312   _ivar = [[NSObject alloc] init];
    313 
    314 #if NON_ARC
    315   [_ivar release];
    316 #endif
    317 
    318 #if NON_ARC
    319   [super dealloc]; // expected-warning {{The '_ivar' ivar in 'ClassWithUpdatedIvar' was retained by a synthesized property but not released before '[super dealloc]'}}
    320 #endif
    321 }
    322 @end
    323 
    324 
    325 // Don't warn when the property is nil'd out with a setter in -dealloc
    326 
    327 @interface ClassWithNildOutPropertyViaSetter : NSObject
    328 @property (retain) NSObject *ivar;
    329 @end
    330 
    331 @implementation ClassWithNildOutPropertyViaSetter
    332 - (void)dealloc; {
    333   [self setIvar:nil];
    334 
    335 #if NON_ARC
    336   [super dealloc];  // no-warning
    337 #endif
    338 }
    339 @end
    340 
    341 
    342 // Don't warn about missing releases when -dealloc helpers are called.
    343 
    344 @interface ClassWithDeallocHelpers : NSObject
    345 @property (retain) NSObject *ivarReleasedInMethod;
    346 @property (retain) NSObject *propNilledOutInMethod;
    347 
    348 @property (retain) NSObject *ivarReleasedInFunction;
    349 @property (retain) NSObject *propNilledOutInFunction;
    350 
    351 @property (retain) NSObject *ivarNeverReleased;
    352 - (void)invalidateInMethod;
    353 @end
    354 
    355 void ReleaseValueHelper(NSObject *iv) {
    356 #if NON_ARC
    357   [iv release];
    358 #endif
    359 }
    360 
    361 void NilOutPropertyHelper(ClassWithDeallocHelpers *o) {
    362   o.propNilledOutInFunction = nil;
    363 }
    364 
    365 @implementation ClassWithDeallocHelpers
    366 - (void)invalidateInMethod {
    367 #if NON_ARC
    368   [_ivarReleasedInMethod release];
    369 #endif
    370   self.propNilledOutInMethod = nil;
    371 }
    372 
    373 - (void)dealloc; {
    374   ReleaseValueHelper(_ivarReleasedInFunction);
    375   NilOutPropertyHelper(self);
    376 
    377   [self invalidateInMethod];
    378 #if NON_ARC
    379   [super dealloc]; // expected-warning {{The '_ivarNeverReleased' ivar in 'ClassWithDeallocHelpers' was retained by a synthesized property but not released before '[super dealloc]'}}
    380 #endif
    381 }
    382 @end
    383 
    384 
    385 // Don't warn when self in -dealloc escapes.
    386 
    387 @interface ClassWhereSelfEscapesViaMethodCall : NSObject
    388 @property (retain) NSObject *ivar;  // no-warning
    389 @end
    390 
    391 @interface ClassWhereSelfEscapesViaMethodCall (Other)
    392 - (void)invalidate; // In other translation unit.
    393 @end
    394 
    395 @implementation ClassWhereSelfEscapesViaMethodCall
    396 - (void)dealloc; {
    397   [self invalidate];
    398 #if NON_ARC
    399   [super dealloc];
    400 #endif
    401 } // no-warning
    402 @end
    403 
    404 @interface ClassWhereSelfEscapesViaPropertyAccess : NSObject
    405 @property (retain) NSObject *ivar;
    406 @end
    407 
    408 @interface ClassWhereSelfEscapesViaPropertyAccess (Other)
    409 // The implementation of this property is unknown and therefore could
    410 // release ivar.
    411 @property (retain) NSObject *otherIvar;
    412 @end
    413 
    414 @implementation ClassWhereSelfEscapesViaPropertyAccess
    415 - (void)dealloc; {
    416   self.otherIvar = nil;
    417 #if NON_ARC
    418   [super dealloc];
    419 #endif
    420 } // no-warning
    421 @end
    422 
    423 // Don't treat self as escaping when setter called on *synthesized*
    424 // property.
    425 
    426 @interface ClassWhereSelfEscapesViaSynthesizedPropertyAccess : NSObject
    427 @property (retain) NSObject *ivar;
    428 @property (retain) NSObject *otherIvar;
    429 @end
    430 
    431 @implementation ClassWhereSelfEscapesViaSynthesizedPropertyAccess
    432 - (void)dealloc; {
    433   self.otherIvar = nil;
    434 #if NON_ARC
    435   [super dealloc];  // expected-warning {{The '_ivar' ivar in 'ClassWhereSelfEscapesViaSynthesizedPropertyAccess' was retained by a synthesized property but not released before '[super dealloc]'}}
    436 #endif
    437 }
    438 @end
    439 
    440 
    441 // Don't treat calls to system headers as escapes
    442 
    443 @interface ClassWhereSelfEscapesViaCallToSystem : NSObject
    444 @property (retain) NSObject *ivar1;
    445 @property (retain) NSObject *ivar2;
    446 @property (retain) NSObject *ivar3;
    447 @property (retain) NSObject *ivar4;
    448 @property (retain) NSObject *ivar5;
    449 @property (retain) NSObject *ivar6;
    450 @end
    451 
    452 @implementation ClassWhereSelfEscapesViaCallToSystem
    453 - (void)dealloc; {
    454 #if NON_ARC
    455   [_ivar2 release];
    456   if (_ivar3) {
    457     [_ivar3 release];
    458   }
    459 #endif
    460 
    461   [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
    462   [[NSNotificationCenter defaultCenter] removeObserver:self];
    463 
    464 #if NON_ARC
    465   [_ivar4 release];
    466 
    467   if (_ivar5) {
    468     [_ivar5 release];
    469   }
    470 #endif
    471 
    472   [[NSNotificationCenter defaultCenter] removeObserver:self];
    473 
    474 #if NON_ARC
    475   if (_ivar6) {
    476     [_ivar6 release];
    477   }
    478 
    479   [super dealloc];  // expected-warning {{The '_ivar1' ivar in 'ClassWhereSelfEscapesViaCallToSystem' was retained by a synthesized property but not released before '[super dealloc]'}}
    480 #endif
    481 }
    482 @end
    483 
    484 // Don't warn when value escapes.
    485 
    486 @interface ClassWhereIvarValueEscapes : NSObject
    487 @property (retain) NSObject *ivar;
    488 @end
    489 
    490 void ReleaseMe(id arg);
    491 
    492 @implementation ClassWhereIvarValueEscapes
    493 - (void)dealloc; {
    494 
    495   ReleaseMe(_ivar);
    496 
    497 #if NON_ARC
    498   [super dealloc];
    499 #endif
    500 } // no-warning
    501 @end
    502 
    503 // Don't warn when value is known to be nil.
    504 
    505 @interface ClassWhereIvarIsNil : NSObject
    506 @property (retain) NSObject *ivarIsNil;
    507 @end
    508 
    509 @implementation ClassWhereIvarIsNil
    510 - (void)dealloc; {
    511 
    512 #if NON_ARC
    513   if (_ivarIsNil)
    514     [_ivarIsNil release];
    515 
    516   [super dealloc];
    517 #endif
    518 } // no-warning
    519 @end
    520 
    521 
    522 // Don't warn for non-retainable properties.
    523 
    524 @interface ClassWithNonRetainableProperty : NSObject
    525 @property (assign) int *ivar;  // no-warning
    526 @end
    527 
    528 @implementation ClassWithNonRetainableProperty
    529 - (void)dealloc; {
    530 #if NON_ARC
    531   [super dealloc];
    532 #endif
    533 } // no-warning
    534 @end
    535 
    536 
    537 @interface SuperClassOfClassWithInlinedSuperDealloc : NSObject
    538 @property (retain) NSObject *propInSuper;
    539 @end
    540 
    541 @implementation SuperClassOfClassWithInlinedSuperDealloc
    542 - (void)dealloc {
    543 #if NON_ARC
    544   [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}}
    545 #endif
    546 }
    547 @end
    548 
    549 @interface ClassWithInlinedSuperDealloc : SuperClassOfClassWithInlinedSuperDealloc
    550 @property (retain) NSObject *propInSub;
    551 @end
    552 
    553 @implementation ClassWithInlinedSuperDealloc
    554 - (void)dealloc {
    555 #if NON_ARC
    556   [super dealloc]; // expected-warning {{The '_propInSub' ivar in 'ClassWithInlinedSuperDealloc' was retained by a synthesized property but not released before '[super dealloc]'}}
    557 #endif
    558 }
    559 @end
    560 
    561 
    562 @interface SuperClassOfClassWithInlinedSuperDeallocAndInvalidation : NSObject
    563 @property (retain) NSObject *propInSuper;
    564 
    565 - (void)invalidate;
    566 @end
    567 
    568 @implementation SuperClassOfClassWithInlinedSuperDeallocAndInvalidation
    569 
    570 - (void)invalidate {
    571 #if NON_ARC
    572   [_propInSuper release];
    573 #endif
    574   _propInSuper = nil;
    575 }
    576 
    577 - (void)dealloc {
    578   [self invalidate];
    579 #if NON_ARC
    580   [super dealloc]; // no-warning
    581 #endif
    582 }
    583 @end
    584 
    585 @interface ClassWithInlinedSuperDeallocAndInvalidation : SuperClassOfClassWithInlinedSuperDeallocAndInvalidation
    586 @property (retain) NSObject *propInSub;
    587 @end
    588 
    589 @implementation ClassWithInlinedSuperDeallocAndInvalidation
    590 
    591 - (void)invalidate {
    592 #if NON_ARC
    593   [_propInSub release];
    594 #endif
    595   [super invalidate];
    596 }
    597 
    598 - (void)dealloc {
    599 #if NON_ARC
    600   [super dealloc]; // no-warning
    601 #endif
    602 }
    603 @end
    604 
    605 
    606 @interface SuperClassOfClassThatEscapesBeforeInliningSuper : NSObject
    607 @property (retain) NSObject *propInSuper;
    608 @end
    609 
    610 @implementation SuperClassOfClassThatEscapesBeforeInliningSuper
    611 
    612 - (void)dealloc {
    613 
    614 #if NON_ARC
    615   [super dealloc]; // expected-warning {{The '_propInSuper' ivar in 'SuperClassOfClassThatEscapesBeforeInliningSuper' was retained by a synthesized property but not released before '[super dealloc]'}}
    616 #endif
    617 }
    618 @end
    619 
    620 @interface ClassThatEscapesBeforeInliningSuper : SuperClassOfClassThatEscapesBeforeInliningSuper
    621 @property (retain) NSObject *propInSub;
    622 @end
    623 
    624 @interface ClassThatEscapesBeforeInliningSuper (Other)
    625 - (void)invalidate; // No implementation in translation unit.
    626 @end
    627 
    628 @implementation ClassThatEscapesBeforeInliningSuper
    629 - (void)dealloc {
    630   [self invalidate];
    631 
    632 #if NON_ARC
    633   [super dealloc]; // no-warning
    634 #endif
    635 }
    636 @end
    637 
    638 
    639 #if NON_ARC
    640 @interface ReleaseIvarInField : NSObject {
    641   int _tag;
    642   union {
    643     NSObject *field1;
    644     NSObject *field2;
    645   } _someUnion;
    646 
    647   struct {
    648     NSObject *field1;
    649   } _someStruct;
    650 }
    651 @end
    652 
    653 @implementation ReleaseIvarInField
    654 - (void)dealloc {
    655   if (_tag) {
    656     [_someUnion.field1 release];
    657   } else {
    658     [_someUnion.field2 release];
    659   }
    660 
    661   [_someStruct.field1 release];
    662   [super dealloc];
    663 }
    664 @end
    665 #endif
    666 
    667 struct SomeStruct {
    668   int f;
    669 };
    670 @interface ZeroOutStructWithSetter : NSObject
    671   @property(assign) struct SomeStruct s;
    672 @end
    673 
    674 @implementation ZeroOutStructWithSetter
    675 - (void)dealloc {
    676   struct SomeStruct zeroedS;
    677   zeroedS.f = 0;
    678 
    679   self.s = zeroedS;
    680 #if NON_ARC
    681   [super dealloc];
    682 #endif
    683 }
    684 @end
    685 
    686 #if NON_ARC
    687 @interface ReleaseIvarInArray : NSObject {
    688   NSObject *_array[3];
    689 }
    690 @end
    691 
    692 @implementation ReleaseIvarInArray
    693 - (void)dealloc {
    694   for (int i = 0; i < 3; i++) {
    695     [_array[i] release];
    696   }
    697   [super dealloc];
    698 }
    699 @end
    700 #endif
    701 
    702 // Don't warn about missing releases for subclasses of SenTestCase or
    703 // for classes that are not subclasses of NSObject.
    704 
    705 @interface SenTestCase : NSObject {}
    706 @end
    707 
    708 @interface MyClassTest : SenTestCase
    709 @property (retain) NSObject *ivar;
    710 @end
    711 
    712 @implementation MyClassTest
    713 -(void)tearDown {
    714 #if NON_ARC
    715   [_ivar release];
    716 #endif
    717 }
    718 
    719 -(void)dealloc; {
    720 #if NON_ARC
    721   [super dealloc]; // no-warning
    722 #endif
    723 }
    724 @end
    725 
    726 @interface XCTestCase : NSObject {}
    727 @end
    728 
    729 @interface MyClassXCTest : XCTestCase
    730 @property (retain) NSObject *ivar;
    731 @end
    732 
    733 @implementation MyClassXCTest
    734 -(void)tearDown {
    735 #if NON_ARC
    736   [_ivar release];
    737 #endif
    738 }
    739 
    740 -(void)dealloc; {
    741 #if NON_ARC
    742   [super dealloc]; // no-warning
    743 #endif
    744 }
    745 @end
    746 
    747 
    748 __attribute__((objc_root_class))
    749 @interface NonNSObjectMissingDealloc
    750 @property (retain) NSObject *ivar;
    751 @end
    752 @implementation NonNSObjectMissingDealloc
    753 -(void)dealloc; {
    754 
    755 }
    756 @end
    757 
    758 // Warn about calling -dealloc rather than release by mistake.
    759 
    760 @interface CallDeallocOnRetainPropIvar : NSObject {
    761   NSObject *okToDeallocDirectly;
    762 }
    763 
    764 @property (retain) NSObject *ivar;
    765 @end
    766 
    767 @implementation CallDeallocOnRetainPropIvar
    768 - (void)dealloc
    769 {
    770 #if NON_ARC
    771   // Only warn for synthesized ivars.
    772   [okToDeallocDirectly dealloc]; // no-warning
    773   [_ivar dealloc];  // expected-warning {{'_ivar' should be released rather than deallocated}}
    774 
    775   [super dealloc];
    776 #endif
    777 }
    778 @end
    779 
    780 // CIFilter special cases.
    781 // By design, -[CIFilter dealloc] releases (by calling -setValue: forKey: with
    782 // 'nil') all ivars (even in its *subclasses*) with names starting with
    783 // 'input' or that are backed by properties with names starting with 'input'.
    784 // The Dealloc checker needs to take particular care to not warn about missing
    785 // releases in this case -- if the user adds a release quiet the
    786 // warning it may result in an over release.
    787 
    788 @interface ImmediateSubCIFilter : CIFilter {
    789   NSObject *inputIvar;
    790   NSObject *nonInputIvar;
    791   NSObject *notPrefixedButBackingPrefixedProperty;
    792   NSObject *inputPrefixedButBackingNonPrefixedProperty;
    793 }
    794 
    795 @property(retain) NSObject *inputIvar;
    796 @property(retain) NSObject *nonInputIvar;
    797 @property(retain) NSObject *inputAutoSynthesizedIvar;
    798 @property(retain) NSObject *inputExplicitlySynthesizedToNonPrefixedIvar;
    799 @property(retain) NSObject *nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar;
    800 
    801 @end
    802 
    803 @implementation ImmediateSubCIFilter
    804 @synthesize inputIvar = inputIvar;
    805 @synthesize nonInputIvar = nonInputIvar;
    806 @synthesize inputExplicitlySynthesizedToNonPrefixedIvar = notPrefixedButBackingPrefixedProperty;
    807 @synthesize nonPrefixedPropertyBackedByExplicitlySynthesizedPrefixedIvar = inputPrefixedButBackingNonPrefixedProperty;
    808 
    809 - (void)dealloc {
    810 #if NON_ARC
    811   // We don't want warnings here for:
    812   // inputIvar
    813   // inputAutoSynthesizedIvar
    814   // inputExplicitlySynthesizedToNonPrefixedIvar
    815   // inputPrefixedButBackingNonPrefixedProperty
    816   [super dealloc];
    817   // expected-warning@-1 {{The 'nonInputIvar' ivar in 'ImmediateSubCIFilter' was retained by a synthesized property but not released before '[super dealloc]'}}
    818 #endif
    819 }
    820 @end
    821 
    822 @interface SubSubCIFilter : CIFilter {
    823   NSObject *inputIvarInSub;
    824 }
    825 
    826 @property(retain) NSObject *inputIvarInSub;
    827 @end
    828 
    829 @implementation SubSubCIFilter
    830 @synthesize inputIvarInSub = inputIvarInSub;
    831 
    832 - (void)dealloc {
    833 // Don't warn about inputIvarInSub.
    834 #if NON_ARC
    835   [super dealloc];
    836 #endif
    837 }
    838 @end
    839 @interface OverreleasingCIFilter : CIFilter {
    840   NSObject *inputIvar;
    841 }
    842 
    843 @property(retain) NSObject *inputIvar;
    844 @end
    845 
    846 @implementation OverreleasingCIFilter
    847 @synthesize inputIvar = inputIvar;
    848 
    849 - (void)dealloc {
    850 #if NON_ARC
    851   // This is an over release because CIFilter's dealloc will also release it.
    852   [inputIvar release]; // expected-warning {{The 'inputIvar' ivar in 'OverreleasingCIFilter' will be released by '-[CIFilter dealloc]' but also released here}}
    853   [super dealloc]; // no-warning
    854   #endif
    855 }
    856 @end
    857 
    858 
    859 @interface NotMissingDeallocCIFilter : CIFilter {
    860   NSObject *inputIvar;
    861 }
    862 
    863 @property(retain) NSObject *inputIvar;
    864 @end
    865 
    866 @implementation NotMissingDeallocCIFilter // no-warning
    867 @synthesize inputIvar = inputIvar;
    868 @end
    869