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