1088 lines · plain
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 %s2// 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 %s3 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; @end17@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end18@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end19@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end20@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@end29@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>30- (NSUInteger)length;31-(id)initWithFormat:(NSString *)f,...;32-(BOOL)isEqualToString:(NSString *)s;33+ (id)string;34@end35@interface NSNumber : NSObject {}36+(id)alloc;37-(id)initWithInteger:(int)i;38@end39 40@interface Test1 : NSObject {41 NSString *text;42}43-(id)myMethod;44@property (nonatomic, assign) NSString *text;45@end46 47 48#if !__has_feature(objc_arc)49 50@implementation Test151 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@end64 65 66@interface MyNumber : NSObject67{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@end77 78@implementation MyNumber79@synthesize myNumber=_myNumber;80 81- (id)initWithNumber:(NSNumber *)number82{83 self = [super init];84 85 if ( self )86 {87 _myNumber = [number copy];88 }89 90 return self;91}92 93- (NSNumber*)newMyNumber94{95 if ( _myNumber )96 return [_myNumber retain];97 98 return [[NSNumber alloc] initWithInteger:1];99}100 101- (id)valueForUndefinedKey:(NSString*)key102{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 release109 else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"])110 value = self.newMyNumber; // this one is ok, since value is returned retained111 else 112 value = [[NSNumber alloc] initWithInteger:0];113 114 return [value autorelease]; // expected-warning {{Object autoreleased too many times}}115}116 117@end118 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#endif127 128 129@interface Person : NSObject {130 NSString *_name;131}132@property (retain) NSString * name;133@property (assign) id friend;134@end135 136@implementation Person137@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#endif145}146@end147 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#endif158 159@interface SubPerson : Person160-(NSString *)foo;161@end162 163@implementation SubPerson164-(NSString *)foo {165 return super.name;166}167@end168 169 170#if !__has_feature(objc_arc)171// Static analyzer doesn't detect uninitialized variable issues for property accesses172@interface RDar9241180173@property (readwrite,assign) id x;174-(id)testAnalyzer1:(int) y;175-(void)testAnalyzer2;176@end177 178@implementation RDar9241180179@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@end191#endif192 193 194//------195// Property accessor synthesis196//------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@end224 225@interface ClassWithShadowedReadWriteProperty ()226@property (readwrite) int someProp;227@end228 229@implementation ClassWithShadowedReadWriteProperty230- (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@end245 246// Tests for the analyzer fix that works around a Sema bug247// where multiple methods are created for properties in class extensions that248// are redeclared in a category method.249@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory250@end251 252@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()253@end254 255@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()256@property (readwrite) int someProp;257@property (readonly) int otherProp;258@end259 260@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat)261@property (readonly) int someProp;262@property (readonly) int otherProp;263@end264 265@implementation ClassWithRedeclaredPropertyInExtensionFollowedByCategory266- (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@end274 275// The relative order of the extension and the category matter, so test both.276@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension277@end278 279@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension ()280@property (readwrite) int someProp;281@end282 283@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat)284@property (readonly) int someProp;285@end286 287@implementation ClassWithRedeclaredPropertyInCategoryFollowedByExtension288- (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@end293 294@interface ClassWithSynthesizedPropertyAndGetter295@property (readonly) int someProp;296@end297 298@implementation ClassWithSynthesizedPropertyAndGetter299@synthesize someProp;300 301// Make sure that the actual getter is inlined and not a getter created302// by BodyFarm303- (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@end312 313__attribute__((objc_root_class))314@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory315@end316 317@protocol HasStuff318@property (nonatomic, readonly) int stuffProperty;319@end320 321@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)322@property (nonatomic, readonly) int stuffProperty;323@end324 325@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>326@end327 328@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>329@end330 331@implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory332@synthesize stuffProperty = _stuffProperty;333 334-(void)foo {335 (void)self.stuffProperty;336}337@end338 339//------340// Setter ivar invalidation.341//------342 343@interface ClassWithSetters344// Note: These properties have implicit @synthesize implementations to be345// backed with ivars.346@property (assign) int propWithIvar1;347@property (assign) int propWithIvar2;348 349@property (retain) NSNumber *retainedProperty;350 351@end352 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@end358 359@implementation ClassWithSetters360- (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; {361 _propWithIvar1 = 1;362 _propWithIvar2 = 2;363 self.propWithIvar1 = 66;364 365 // Calling the setter of a property backed by the instance variable366 // should invalidate the storage for the instance variable but not367 // the rest of the receiver. Ideally we would model the setter completely368 // but doing so would cause the new value to escape when it is bound369 // to the ivar. This would cause bad false negatives in the retain count370 // checker. (There is a test for this scenario in371 // 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#endif406@end407 408//------409// class properties410//------411 412int gBackingForReadWriteClassProp = 0;413 414@interface ClassWithClassProperties415@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 same420// 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@end431 432@interface ClassWithClassProperties (OtherTranslationUnit)433@property(class, assign) id propInOtherTranslationUnit;434@end435 436@implementation ClassWithClassProperties437 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@end500 501@interface SubclassOfClassWithClassProperties : ClassWithClassProperties502@end503 504@implementation SubclassOfClassWithClassProperties505+ (int)dynamicClassProp; {506 return 16;507}508 509- (void)testDynamicClassProp {510 clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}}511}512 513@end514 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-warning538 self->_name = 0;539 540 doSomethingWithName(other->_name);541 [other.name release]; // no-warning542}543 544- (void)deliberateReleaseFalseNegative {545 // This is arguably a false negative because the result of p.friend shouldn't546 // be released, even though we are manipulating the ivar in between the two547 // 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@end566#endif567 568@interface IntWrapper569@property int value;570@end571 572@implementation IntWrapper573@synthesize value;574@end575 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 IntWrapperAuto595@property int value;596@end597 598@implementation IntWrapperAuto599@end600 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 StructWrapper624@property IntWrapperStruct inner;625@end626 627@implementation StructWrapper628@synthesize inner;629@end630 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 OpaqueIntWrapper643@property int value;644@end645 646// For now, don't assume a property is implemented using an ivar unless we can647// 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 RetainCountTesting657@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@end665 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-warning751 752- (void)testOverreleaseIvarOnlyAutoreleaseOkay {753 [_ivarOnly retain];754 [_ivarOnly release];755 [_ivarOnly autorelease];756} // no-warning757 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-warning805}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-warning813}814 815- (void)testPropertyAccessThenReleaseCF {816 CFTypeRef owned = CFRetain(self.cfProp);817 CFRelease(owned);818 CFRelease(_cfProp); // no-warning819 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-warning834}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-warning842}843 844- (void)testPropertyAccessThenReleaseImplicitManual {845 id prop = [self.implicitManualProp retain];846 [prop release];847 [_implicitManualProp release]; // no-warning848}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-warning856}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-warning876}877 878- (id)transferUnownedFromProperty {879 [_ownedProp retain];880 [_ownedProp autorelease];881 return [_ownedProp autorelease]; // no-warning882}883 884- (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) {885 [_ownedProp retain];886 [_ownedProp autorelease];887 return _ownedProp; // no-warning888}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-warning928}929 930- (void)testAssignUnownedOkay:(id)newValue {931 _unownedProp = [newValue retain];932 [_unownedProp release]; // no-warning933}934 935- (void)testAssignIvarOnlyOkay:(id)newValue {936 _ivarOnly = [newValue retain];937 [_ivarOnly release]; // no-warning938}939 940- (void)testAssignCFOkay:(CFTypeRef)newValue {941 _cfProp = CFRetain(newValue);942 CFRelease(_cfProp); // no-warning943}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-warning979}980 981@end982 983@interface Wrapper984@property(nonatomic, readonly) int value;985@end986 987@implementation Wrapper988@synthesize value;989@end990 991void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll(void) {992 union {993 Wrapper *wrapper;994 } u = { 0 };995 [u.wrapper value];996}997 998#endif // non-ARC999 1000@interface ExplicitAccessorInCategory : NSObject1001@property(readonly) int normal;1002- (int)normal;1003@property(readonly) int no_custom_accessor;1004@end1005 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@end1013 1014@interface ExplicitAccessorInCategory ()1015- (int)in_category;1016 1017// This is an ordinary method, not a getter.1018- (int)no_custom_accessor;1019@end1020 1021@implementation ExplicitAccessorInCategory1022- (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@end1035 1036@interface Shadowed1037@property (assign) NSObject *o;1038- (NSObject *)getShadowedIvar;1039- (void)clearShadowedIvar;1040- (NSObject *)getShadowedProp;1041- (void)clearShadowedProp;1042 1043@property (assign) NSObject *o2;1044@end1045 1046@implementation Shadowed1047- (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@end1060 1061@interface Shadowing : Shadowed1062@end1063 1064@implementation Shadowing1065// 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 syntax1069// even from the superclass methods.1070@synthesize o;1071 1072-(void)testPropertyShadowing {1073 NSObject *oo = self.o; // no-crash1074 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-crash1086}1087@end1088