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