Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
      3 
      4 void clang_analyzer_eval(int);
      5 
      6 typedef const void * CFTypeRef;
      7 extern CFTypeRef CFRetain(CFTypeRef cf);
      8 void CFRelease(CFTypeRef cf);
      9 
     10 typedef signed char BOOL;
     11 typedef unsigned int NSUInteger;
     12 typedef struct _NSZone NSZone;
     13 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
     14 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
     15 @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
     16 @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
     17 @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
     18 @interface NSObject <NSObject> {}
     19 +(id)alloc;
     20 -(id)init;
     21 -(id)autorelease;
     22 -(id)copy;
     23 -(id)retain;
     24 -(oneway void)release;
     25 -(void)dealloc;
     26 @end
     27 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
     28 - (NSUInteger)length;
     29 -(id)initWithFormat:(NSString *)f,...;
     30 -(BOOL)isEqualToString:(NSString *)s;
     31 + (id)string;
     32 @end
     33 @interface NSNumber : NSObject {}
     34 +(id)alloc;
     35 -(id)initWithInteger:(int)i;
     36 @end
     37 
     38 // rdar://6946338
     39 
     40 @interface Test1 : NSObject {
     41   NSString *text;
     42 }
     43 -(id)myMethod;
     44 @property (nonatomic, assign) NSString *text;
     45 @end
     46 
     47 
     48 #if !__has_feature(objc_arc)
     49 
     50 @implementation Test1
     51 
     52 @synthesize text;
     53 
     54 -(id)myMethod {
     55   Test1 *cell = [[[Test1 alloc] init] autorelease];
     56 
     57   NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}}
     58   cell.text = string1;
     59 
     60   return cell;
     61 }
     62 
     63 @end
     64 
     65 
     66 // rdar://8824416
     67 
     68 @interface MyNumber : NSObject
     69 {
     70   NSNumber* _myNumber;
     71 }
     72 
     73 - (id)initWithNumber:(NSNumber *)number;
     74 
     75 @property (nonatomic, readonly) NSNumber* myNumber;
     76 @property (nonatomic, readonly) NSNumber* newMyNumber;
     77 
     78 @end
     79 
     80 @implementation MyNumber
     81 @synthesize myNumber=_myNumber;
     82  
     83 - (id)initWithNumber:(NSNumber *)number
     84 {
     85   self = [super init];
     86   
     87   if ( self )
     88   {
     89     _myNumber = [number copy];
     90   }
     91   
     92   return self;
     93 }
     94 
     95 - (NSNumber*)newMyNumber
     96 {
     97   if ( _myNumber )
     98     return [_myNumber retain];
     99   
    100   return [[NSNumber alloc] initWithInteger:1];
    101 }
    102 
    103 - (id)valueForUndefinedKey:(NSString*)key
    104 {
    105   id value = 0;
    106   
    107   if ([key isEqualToString:@"MyIvarNumberAsPropertyOverReleased"])
    108     value = self.myNumber; // _myNumber will be over released, since the value returned from self.myNumber is not retained.
    109   else if ([key isEqualToString:@"MyIvarNumberAsPropertyOk"])
    110     value = [self.myNumber retain]; // this line fixes the over release
    111   else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"])
    112     value = self.newMyNumber; // this one is ok, since value is returned retained
    113   else 
    114     value = [[NSNumber alloc] initWithInteger:0];
    115   
    116   return [value autorelease]; // expected-warning {{Object autoreleased too many times}}
    117 }
    118 
    119 @end
    120 
    121 NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
    122 {
    123   NSNumber* result = aMyNumber.myNumber;
    124     
    125   return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
    126 }
    127 
    128 #endif
    129 
    130 
    131 // rdar://6611873
    132 
    133 @interface Person : NSObject {
    134   NSString *_name;
    135 }
    136 @property (retain) NSString * name;
    137 @property (assign) id friend;
    138 @end
    139 
    140 @implementation Person
    141 @synthesize name = _name;
    142 
    143 -(void)dealloc {
    144 #if !__has_feature(objc_arc)
    145   self.name = [[NSString alloc] init]; // expected-warning {{leak}}
    146 
    147   [super dealloc]; // expected-warning {{The '_name' ivar in 'Person' was retained by a synthesized property but not released before '[super dealloc]}}
    148 #endif
    149 }
    150 @end
    151 
    152 #if !__has_feature(objc_arc)
    153 void rdar6611873() {
    154   Person *p = [[[Person alloc] init] autorelease];
    155   
    156   p.name = [[NSString string] retain]; // expected-warning {{leak}}
    157   p.name = [[NSString alloc] init]; // expected-warning {{leak}}
    158 
    159   p.friend = [[Person alloc] init]; // expected-warning {{leak}}
    160 }
    161 #endif
    162 
    163 @interface SubPerson : Person
    164 -(NSString *)foo;
    165 @end
    166 
    167 @implementation SubPerson
    168 -(NSString *)foo {
    169   return super.name;
    170 }
    171 @end
    172 
    173 
    174 #if !__has_feature(objc_arc)
    175 // <rdar://problem/9241180> Static analyzer doesn't detect uninitialized variable issues for property accesses
    176 @interface RDar9241180
    177 @property (readwrite,assign) id x;
    178 -(id)testAnalyzer1:(int) y;
    179 -(void)testAnalyzer2;
    180 @end
    181 
    182 @implementation RDar9241180
    183 @synthesize x;
    184 -(id)testAnalyzer1:(int)y {
    185     RDar9241180 *o;
    186     if (y && o.x) // expected-warning {{Property access on an uninitialized object pointer}}
    187       return o;
    188     return o; // expected-warning {{Undefined or garbage value returned to caller}}
    189 }
    190 -(void)testAnalyzer2 {
    191   id y;
    192   self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
    193 }
    194 @end
    195 #endif
    196 
    197 
    198 //------
    199 // Property accessor synthesis
    200 //------
    201 
    202 extern void doSomethingWithPerson(Person *p);
    203 extern void doSomethingWithName(NSString *name);
    204 
    205 void testConsistencyRetain(Person *p) {
    206   clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}}
    207 
    208   id origName = p.name;
    209   clang_analyzer_eval(p.name == origName); // expected-warning{{TRUE}}
    210   doSomethingWithPerson(p);
    211   clang_analyzer_eval(p.name == origName); // expected-warning{{UNKNOWN}}
    212 }
    213 
    214 void testConsistencyAssign(Person *p) {
    215   clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}}
    216 
    217   id origFriend = p.friend;
    218   clang_analyzer_eval(p.friend == origFriend); // expected-warning{{TRUE}}
    219   doSomethingWithPerson(p);
    220   clang_analyzer_eval(p.friend == origFriend); // expected-warning{{UNKNOWN}}
    221 }
    222 
    223 @interface ClassWithShadowedReadWriteProperty {
    224   int _f;
    225 }
    226 @property (readonly) int someProp;
    227 @end
    228 
    229 @interface ClassWithShadowedReadWriteProperty ()
    230 @property (readwrite) int someProp;
    231 @end
    232 
    233 @implementation ClassWithShadowedReadWriteProperty
    234 - (void)testSynthesisForShadowedReadWriteProperties; {
    235   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
    236 
    237   _f = 1;
    238 
    239   // Read of shadowed property should not invalidate receiver.
    240   (void)self.someProp;
    241   clang_analyzer_eval(_f == 1); // expected-warning{{TRUE}}
    242 
    243   _f = 2;
    244   // Call to getter of shadowed property should not invalidate receiver.
    245   (void)[self someProp];
    246   clang_analyzer_eval(_f == 2); // expected-warning{{TRUE}}
    247 }
    248 @end
    249 
    250 // Tests for the analyzer fix that works around a Sema bug
    251 // where multiple methods are created for properties in class extensions that
    252 // are redeclared in a category method.
    253 // The Sema bug is tracked as <rdar://problem/25481164>.
    254 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory
    255 @end
    256 
    257 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
    258 @end
    259 
    260 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
    261 @property (readwrite) int someProp;
    262 @property (readonly) int otherProp;
    263 @end
    264 
    265 @interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat)
    266 @property (readonly) int someProp;
    267 @property (readonly) int otherProp;
    268 @end
    269 
    270 @implementation ClassWithRedeclaredPropertyInExtensionFollowedByCategory
    271 - (void)testSynthesisForRedeclaredProperties; {
    272   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
    273   clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}
    274 
    275   clang_analyzer_eval(self.otherProp == self.otherProp); // expected-warning{{TRUE}}
    276   clang_analyzer_eval([self otherProp] == self.otherProp); // expected-warning{{TRUE}}
    277 }
    278 @end
    279 
    280 // The relative order of the extension and the category matter, so test both.
    281 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension
    282 @end
    283 
    284 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension ()
    285 @property (readwrite) int someProp;
    286 @end
    287 
    288 @interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat)
    289 @property (readonly) int someProp;
    290 @end
    291 
    292 @implementation ClassWithRedeclaredPropertyInCategoryFollowedByExtension
    293 - (void)testSynthesisForRedeclaredProperties; {
    294   clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
    295   clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}
    296 }
    297 @end
    298 
    299 @interface ClassWithSynthesizedPropertyAndGetter
    300 @property (readonly) int someProp;
    301 @end
    302 
    303 @implementation ClassWithSynthesizedPropertyAndGetter
    304 @synthesize someProp;
    305 
    306 // Make sure that the actual getter is inlined and not a getter created
    307 // by BodyFarm
    308 - (void)testBodyFarmGetterNotUsed {
    309   int i = self.someProp;
    310   clang_analyzer_eval(i == 22); // expected-warning {{TRUE}}
    311 }
    312 
    313 -(int)someProp {
    314   return 22;
    315 }
    316 @end
    317 
    318 //------
    319 // Setter ivar invalidation.
    320 //------
    321 
    322 @interface ClassWithSetters
    323 // Note: These properties have implicit @synthesize implementations to be
    324 // backed with ivars.
    325 @property (assign) int propWithIvar1;
    326 @property (assign) int propWithIvar2;
    327 
    328 @property (retain) NSNumber *retainedProperty;
    329 
    330 @end
    331 
    332 @interface ClassWithSetters (InOtherTranslationUnit)
    333 // The implementation of this property is in another translation unit.
    334 // We don't know whether it is backed by an ivar or not.
    335 @property (assign) int propInOther;
    336 @end
    337 
    338 @implementation ClassWithSetters
    339 - (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; {
    340   _propWithIvar1 = 1;
    341   _propWithIvar2 = 2;
    342   self.propWithIvar1 = 66;
    343 
    344   // Calling the setter of a property backed by the instance variable
    345   // should invalidate the storage for the instance variable but not
    346   // the rest of the receiver. Ideally we would model the setter completely
    347   // but doing so would cause the new value to escape when it is bound
    348   // to the ivar. This would cause bad false negatives in the retain count
    349   // checker. (There is a test for this scenario in
    350   // testWriteRetainedValueToRetainedProperty below).
    351   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
    352   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
    353 
    354   _propWithIvar1 = 1;
    355   [self setPropWithIvar1:66];
    356 
    357   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
    358   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
    359 }
    360 
    361 - (void) testSettingPropWithoutIvarInvalidatesEntireInstance; {
    362   _propWithIvar1 = 1;
    363   _propWithIvar2 = 2;
    364   self.propInOther = 66;
    365 
    366   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
    367   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
    368 
    369   _propWithIvar1 = 1;
    370   _propWithIvar2 = 2;
    371   [self setPropInOther:66];
    372 
    373   clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
    374   clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
    375 }
    376 
    377 #if !__has_feature(objc_arc)
    378 - (void) testWriteRetainedValueToRetainedProperty; {
    379   NSNumber *number = [[NSNumber alloc] initWithInteger:5]; // expected-warning {{Potential leak of an object stored into 'number'}}
    380 
    381   // Make sure we catch this leak.
    382   self.retainedProperty = number;
    383 }
    384 #endif
    385 @end
    386 
    387 //------
    388 // class properties
    389 //------
    390 
    391 int gBackingForReadWriteClassProp = 0;
    392 
    393 @interface ClassWithClassProperties
    394 @property(class, readonly) int readOnlyClassProp;
    395 
    396 @property(class) int readWriteClassProp;
    397 
    398 // Make sure we handle when a class and instance property have the same
    399 // name. Test both when instance comes first and when class comes first.
    400 @property(readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;
    401 @property(class, readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;
    402 
    403 @property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst;
    404 @property(readonly) int classAndInstancePropWithSameNameOrderClassFirst;
    405 
    406 
    407 @property(class, readonly) int dynamicClassProp;
    408 
    409 @end
    410 
    411 @interface ClassWithClassProperties (OtherTranslationUnit)
    412 @property(class, assign) id propInOtherTranslationUnit;
    413 @end
    414 
    415 @implementation ClassWithClassProperties
    416 
    417 @dynamic dynamicClassProp;
    418 
    419 + (int)readOnlyClassProp {
    420   return 1;
    421 }
    422 
    423 + (int)readWriteClassProp {
    424   return gBackingForReadWriteClassProp;
    425 }
    426 
    427 + (void)setReadWriteClassProp:(int)val {
    428   gBackingForReadWriteClassProp = val;
    429 }
    430 
    431 - (int)classAndInstancePropWithSameNameOrderInstanceFirst {
    432   return 12;
    433 }
    434 
    435 + (int)classAndInstancePropWithSameNameOrderInstanceFirst {
    436   return 13;
    437 }
    438 
    439 + (int)classAndInstancePropWithSameNameOrderClassFirst {
    440   return 14;
    441 }
    442 
    443 - (int)classAndInstancePropWithSameNameOrderClassFirst {
    444   return 15;
    445 }
    446 
    447 - (void)testInlineClassProp {
    448   clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}}
    449 
    450   ClassWithClassProperties.readWriteClassProp = 7;
    451   clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 7); // expected-warning{{TRUE}}
    452   ClassWithClassProperties.readWriteClassProp = 8;
    453   clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 8); // expected-warning{{TRUE}}
    454 }
    455 
    456 - (void)testUnknownClassProp {
    457   clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}}
    458 }
    459 
    460 - (void)testEscapeGlobalOnUnknownProp {
    461   gBackingForReadWriteClassProp = 33;
    462   ClassWithClassProperties.propInOtherTranslationUnit = 0;
    463   clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}}
    464 }
    465 
    466 - (void)testClassAndInstancePropertyWithSameName {
    467   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}}
    468   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}}
    469 
    470   clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}}
    471   clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}}
    472 }
    473 
    474 - (void)testDynamicClassProp {
    475   clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}}
    476 }
    477 
    478 @end
    479 
    480 @interface SubclassOfClassWithClassProperties : ClassWithClassProperties
    481 @end
    482 
    483 @implementation SubclassOfClassWithClassProperties
    484 + (int)dynamicClassProp; {
    485  return 16;
    486 }
    487 
    488 - (void)testDynamicClassProp {
    489   clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}}
    490 }
    491 
    492 @end
    493 
    494 
    495 #if !__has_feature(objc_arc)
    496 void testOverrelease(Person *p, int coin) {
    497   switch (coin) {
    498   case 0:
    499     [p.name release]; // expected-warning{{not owned}}
    500     break;
    501   case 1:
    502     [p.friend release]; // expected-warning{{not owned}}
    503     break;
    504   case 2: {
    505     id friend = p.friend;
    506     doSomethingWithPerson(p);
    507     [friend release]; // expected-warning{{not owned}}
    508   }
    509   }
    510 }
    511 
    512 // <rdar://problem/16333368>
    513 @implementation Person (Rdar16333368)
    514 
    515 - (void)testDeliberateRelease:(Person *)other {
    516   doSomethingWithName(self.name);
    517   [_name release]; // no-warning
    518   self->_name = 0;
    519 
    520   doSomethingWithName(other->_name);
    521   [other.name release]; // no-warning
    522 }
    523 
    524 - (void)deliberateReleaseFalseNegative {
    525   // This is arguably a false negative because the result of p.friend shouldn't
    526   // be released, even though we are manipulating the ivar in between the two
    527   // actions.
    528   id name = self.name;
    529   _name = 0;
    530   [name release];
    531 }
    532 
    533 - (void)testRetainAndRelease {
    534   [self.name retain];
    535   [self.name release];
    536   [self.name release]; // expected-warning{{not owned}}
    537 }
    538 
    539 - (void)testRetainAndReleaseIVar {
    540   [self.name retain];
    541   [_name release];
    542   [_name release];
    543 }
    544 
    545 @end
    546 #endif
    547 
    548 @interface IntWrapper
    549 @property int value;
    550 @end
    551 
    552 @implementation IntWrapper
    553 @synthesize value;
    554 @end
    555 
    556 void testConsistencyInt(IntWrapper *w) {
    557   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
    558 
    559   int origValue = w.value;
    560   if (origValue != 42)
    561     return;
    562 
    563   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
    564 }
    565 
    566 void testConsistencyInt2(IntWrapper *w) {
    567   if (w.value != 42)
    568     return;
    569 
    570   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
    571 }
    572 
    573 
    574 @interface IntWrapperAuto
    575 @property int value;
    576 @end
    577 
    578 @implementation IntWrapperAuto
    579 @end
    580 
    581 void testConsistencyIntAuto(IntWrapperAuto *w) {
    582   clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
    583 
    584   int origValue = w.value;
    585   if (origValue != 42)
    586     return;
    587 
    588   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
    589 }
    590 
    591 void testConsistencyIntAuto2(IntWrapperAuto *w) {
    592   if (w.value != 42)
    593     return;
    594 
    595   clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
    596 }
    597 
    598 
    599 typedef struct {
    600   int value;
    601 } IntWrapperStruct;
    602 
    603 @interface StructWrapper
    604 @property IntWrapperStruct inner;
    605 @end
    606 
    607 @implementation StructWrapper
    608 @synthesize inner;
    609 @end
    610 
    611 void testConsistencyStruct(StructWrapper *w) {
    612   clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
    613 
    614   int origValue = w.inner.value;
    615   if (origValue != 42)
    616     return;
    617 
    618   clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
    619 }
    620 
    621 
    622 @interface OpaqueIntWrapper
    623 @property int value;
    624 @end
    625 
    626 // For now, don't assume a property is implemented using an ivar unless we can
    627 // actually see that it is.
    628 void testOpaqueConsistency(OpaqueIntWrapper *w) {
    629   clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}}
    630 }
    631 
    632 
    633 #if !__has_feature(objc_arc)
    634 // Test quite a few cases of retain/release issues.
    635 
    636 @interface RetainCountTesting
    637 @property (strong) id ownedProp;
    638 @property (unsafe_unretained) id unownedProp;
    639 @property (nonatomic, strong) id manualProp;
    640 @property (readonly) id readonlyProp;
    641 @property (nonatomic, readwrite/*, assign */) id implicitManualProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
    642 @property (nonatomic, readwrite/*, assign */) id implicitSynthProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
    643 @property CFTypeRef cfProp;
    644 @end
    645 
    646 @implementation RetainCountTesting {
    647   id _ivarOnly;
    648 }
    649 
    650 - (id)manualProp {
    651   return _manualProp;
    652 }
    653 
    654 - (void)setImplicitManualProp:(id)newValue {}
    655 
    656 - (void)testOverreleaseOwnedIvar {
    657   [_ownedProp retain];
    658   [_ownedProp release];
    659   [_ownedProp release];
    660   [_ownedProp release]; // FIXME-warning{{used after it is released}}
    661 }
    662 
    663 - (void)testOverreleaseUnownedIvar {
    664   [_unownedProp retain];
    665   [_unownedProp release];
    666   [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}}
    667 }
    668 
    669 - (void)testOverreleaseIvarOnly {
    670   [_ivarOnly retain];
    671   [_ivarOnly release];
    672   [_ivarOnly release];
    673   [_ivarOnly release]; // FIXME-warning{{used after it is released}}
    674 }
    675 
    676 - (void)testOverreleaseReadonlyIvar {
    677   [_readonlyProp retain];
    678   [_readonlyProp release];
    679   [_readonlyProp release];
    680   [_readonlyProp release]; // FIXME-warning{{used after it is released}}
    681 }
    682 
    683 - (void)testOverreleaseImplicitManualIvar {
    684   [_implicitManualProp retain];
    685   [_implicitManualProp release];
    686   [_implicitManualProp release];
    687   [_implicitManualProp release]; // FIXME-warning{{used after it is released}}
    688 }
    689 
    690 - (void)testOverreleaseImplicitSynthIvar {
    691   [_implicitSynthProp retain];
    692   [_implicitSynthProp release];
    693   [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}}
    694 }
    695 
    696 - (void)testOverreleaseCF {
    697   CFRetain(_cfProp);
    698   CFRelease(_cfProp);
    699   CFRelease(_cfProp);
    700   CFRelease(_cfProp); // FIXME-warning{{used after it is released}}
    701 }
    702 
    703 - (void)testOverreleaseOwnedIvarUse {
    704   [_ownedProp retain];
    705   [_ownedProp release];
    706   [_ownedProp release];
    707   [_ownedProp myMethod]; // FIXME-warning{{used after it is released}}
    708 }
    709 
    710 - (void)testOverreleaseIvarOnlyUse {
    711   [_ivarOnly retain];
    712   [_ivarOnly release];
    713   [_ivarOnly release];
    714   [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}}
    715 }
    716 
    717 - (void)testOverreleaseCFUse {
    718   CFRetain(_cfProp);
    719   CFRelease(_cfProp);
    720   CFRelease(_cfProp);
    721 
    722   extern void CFUse(CFTypeRef);
    723   CFUse(_cfProp); // FIXME-warning{{used after it is released}}
    724 }
    725 
    726 - (void)testOverreleaseOwnedIvarAutoreleaseOkay {
    727   [_ownedProp retain];
    728   [_ownedProp release];
    729   [_ownedProp autorelease];
    730 } // no-warning
    731 
    732 - (void)testOverreleaseIvarOnlyAutoreleaseOkay {
    733   [_ivarOnly retain];
    734   [_ivarOnly release];
    735   [_ivarOnly autorelease];
    736 } // no-warning
    737 
    738 - (void)testOverreleaseOwnedIvarAutorelease {
    739   [_ownedProp retain];
    740   [_ownedProp release];
    741   [_ownedProp autorelease];
    742   [_ownedProp autorelease];
    743 } // FIXME-warning{{Object autoreleased too many times}}
    744 
    745 - (void)testOverreleaseIvarOnlyAutorelease {
    746   [_ivarOnly retain];
    747   [_ivarOnly release];
    748   [_ivarOnly autorelease];
    749   [_ivarOnly autorelease];
    750 } // FIXME-warning{{Object autoreleased too many times}}
    751 
    752 - (void)testPropertyAccessThenReleaseOwned {
    753   id owned = [self.ownedProp retain];
    754   [owned release];
    755   [_ownedProp release];
    756   clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}}
    757 }
    758 
    759 - (void)testPropertyAccessThenReleaseOwned2 {
    760   id fromIvar = _ownedProp;
    761   id owned = [self.ownedProp retain];
    762   [owned release];
    763   [fromIvar release];
    764   clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
    765 }
    766 
    767 - (void)testPropertyAccessThenReleaseUnowned {
    768   id unowned = [self.unownedProp retain];
    769   [unowned release];
    770   [_unownedProp release]; // FIXME-warning{{not owned}}
    771 }
    772 
    773 - (void)testPropertyAccessThenReleaseUnowned2 {
    774   id fromIvar = _unownedProp;
    775   id unowned = [self.unownedProp retain];
    776   [unowned release];
    777   clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}}
    778   [fromIvar release]; // FIXME-warning{{not owned}}
    779 }
    780 
    781 - (void)testPropertyAccessThenReleaseManual {
    782   id prop = [self.manualProp retain];
    783   [prop release];
    784   [_manualProp release]; // no-warning
    785 }
    786 
    787 - (void)testPropertyAccessThenReleaseManual2 {
    788   id fromIvar = _manualProp;
    789   id prop = [self.manualProp retain];
    790   [prop release];
    791   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
    792   [fromIvar release]; // no-warning
    793 }
    794 
    795 - (void)testPropertyAccessThenReleaseCF {
    796   CFTypeRef owned = CFRetain(self.cfProp);
    797   CFRelease(owned);
    798   CFRelease(_cfProp); // no-warning
    799   clang_analyzer_eval(owned == _cfProp); // expected-warning{{TRUE}}
    800 }
    801 
    802 - (void)testPropertyAccessThenReleaseCF2 {
    803   CFTypeRef fromIvar = _cfProp;
    804   CFTypeRef owned = CFRetain(self.cfProp);
    805   CFRelease(owned);
    806   CFRelease(fromIvar);
    807   clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
    808 }
    809 
    810 - (void)testPropertyAccessThenReleaseReadonly {
    811   id prop = [self.readonlyProp retain];
    812   [prop release];
    813   [_readonlyProp release]; // no-warning
    814 }
    815 
    816 - (void)testPropertyAccessThenReleaseReadonly2 {
    817   id fromIvar = _readonlyProp;
    818   id prop = [self.readonlyProp retain];
    819   [prop release];
    820   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
    821   [fromIvar release]; // no-warning
    822 }
    823 
    824 - (void)testPropertyAccessThenReleaseImplicitManual {
    825   id prop = [self.implicitManualProp retain];
    826   [prop release];
    827   [_implicitManualProp release]; // no-warning
    828 }
    829 
    830 - (void)testPropertyAccessThenReleaseImplicitManual2 {
    831   id fromIvar = _implicitManualProp;
    832   id prop = [self.implicitManualProp retain];
    833   [prop release];
    834   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
    835   [fromIvar release]; // no-warning
    836 }
    837 
    838 - (void)testPropertyAccessThenReleaseImplicitSynth {
    839   id prop = [self.implicitSynthProp retain];
    840   [prop release];
    841   [_implicitSynthProp release]; // FIXME-warning{{not owned}}
    842 }
    843 
    844 - (void)testPropertyAccessThenReleaseImplicitSynth2 {
    845   id fromIvar = _implicitSynthProp;
    846   id prop = [self.implicitSynthProp retain];
    847   [prop release];
    848   clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
    849   [fromIvar release]; // FIXME-warning{{not owned}}
    850 }
    851 
    852 - (id)getUnownedFromProperty {
    853   [_ownedProp retain];
    854   [_ownedProp autorelease];
    855   return _ownedProp; // no-warning
    856 }
    857 
    858 - (id)transferUnownedFromProperty {
    859   [_ownedProp retain];
    860   [_ownedProp autorelease];
    861   return [_ownedProp autorelease]; // no-warning
    862 }
    863 
    864 - (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) {
    865   [_ownedProp retain];
    866   [_ownedProp autorelease];
    867   return _ownedProp; // no-warning
    868 }
    869 
    870 - (void)testAssignOwned:(id)newValue {
    871   _ownedProp = newValue;
    872   [_ownedProp release]; // FIXME: no-warning{{not owned}}
    873 }
    874 
    875 - (void)testAssignUnowned:(id)newValue {
    876   _unownedProp = newValue;
    877   [_unownedProp release]; // FIXME: no-warning{{not owned}}
    878 }
    879 
    880 - (void)testAssignIvarOnly:(id)newValue {
    881   _ivarOnly = newValue;
    882   [_ivarOnly release]; // FIXME: no-warning{{not owned}}
    883 }
    884 
    885 - (void)testAssignCF:(CFTypeRef)newValue {
    886   _cfProp = newValue;
    887   CFRelease(_cfProp); // FIXME: no-warning{{not owned}}
    888 }
    889 
    890 - (void)testAssignReadonly:(id)newValue {
    891   _readonlyProp = newValue;
    892   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
    893 }
    894 
    895 - (void)testAssignImplicitManual:(id)newValue {
    896   _implicitManualProp = newValue;
    897   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
    898 }
    899 
    900 - (void)testAssignImplicitSynth:(id)newValue {
    901   _implicitSynthProp = newValue;
    902   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
    903 }
    904 
    905 - (void)testAssignOwnedOkay:(id)newValue {
    906   _ownedProp = [newValue retain];
    907   [_ownedProp release]; // no-warning
    908 }
    909 
    910 - (void)testAssignUnownedOkay:(id)newValue {
    911   _unownedProp = [newValue retain];
    912   [_unownedProp release]; // no-warning
    913 }
    914 
    915 - (void)testAssignIvarOnlyOkay:(id)newValue {
    916   _ivarOnly = [newValue retain];
    917   [_ivarOnly release]; // no-warning
    918 }
    919 
    920 - (void)testAssignCFOkay:(CFTypeRef)newValue {
    921   _cfProp = CFRetain(newValue);
    922   CFRelease(_cfProp); // no-warning
    923 }
    924 
    925 - (void)testAssignReadonlyOkay:(id)newValue {
    926   _readonlyProp = [newValue retain];
    927   [_readonlyProp release]; // FIXME: no-warning{{not owned}}
    928 }
    929 
    930 - (void)testAssignImplicitManualOkay:(id)newValue {
    931   _implicitManualProp = [newValue retain];
    932   [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
    933 }
    934 
    935 - (void)testAssignImplicitSynthOkay:(id)newValue {
    936   _implicitSynthProp = [newValue retain];
    937   [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
    938 }
    939 
    940 // rdar://problem/19862648
    941 - (void)establishIvarIsNilDuringLoops {
    942   extern id getRandomObject();
    943 
    944   int i = 4; // Must be at least 4 to trigger the bug.
    945   while (--i) {
    946     id x = 0;
    947     if (getRandomObject())
    948       x = _ivarOnly;
    949     if (!x)
    950       x = getRandomObject();
    951     [x myMethod];
    952   }
    953 }
    954 
    955 // rdar://problem/20335433
    956 - (void)retainIvarAndInvalidateSelf {
    957   extern void invalidate(id);
    958   [_unownedProp retain];
    959   invalidate(self);
    960   [_unownedProp release]; // no-warning
    961 }
    962 
    963 @end
    964 #endif // non-ARC
    965 
    966