// 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
// 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

void clang_analyzer_eval(int);

#define nil ((id)0)

typedef const void * CFTypeRef;
extern CFTypeRef CFRetain(CFTypeRef cf);
void CFRelease(CFTypeRef cf);

typedef signed char BOOL;
typedef unsigned int NSUInteger;
typedef struct _NSZone NSZone;
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
@protocol NSObject  - (BOOL)isEqual:(id)object; @end
@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
@interface NSObject <NSObject> {}
+(id)alloc;
-(id)init;
-(id)autorelease;
-(id)copy;
-(id)retain;
-(oneway void)release;
-(void)dealloc;
@end
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
- (NSUInteger)length;
-(id)initWithFormat:(NSString *)f,...;
-(BOOL)isEqualToString:(NSString *)s;
+ (id)string;
@end
@interface NSNumber : NSObject {}
+(id)alloc;
-(id)initWithInteger:(int)i;
@end

// rdar://6946338

@interface Test1 : NSObject {
  NSString *text;
}
-(id)myMethod;
@property (nonatomic, assign) NSString *text;
@end


#if !__has_feature(objc_arc)

@implementation Test1

@synthesize text;

-(id)myMethod {
  Test1 *cell = [[[Test1 alloc] init] autorelease];

  NSString *string1 = [[NSString alloc] initWithFormat:@"test %f", 0.0]; // expected-warning {{Potential leak}}
  cell.text = string1;

  return cell;
}

@end


// rdar://8824416

@interface MyNumber : NSObject
{
  NSNumber* _myNumber;
}

- (id)initWithNumber:(NSNumber *)number;

@property (nonatomic, readonly) NSNumber* myNumber;
@property (nonatomic, readonly) NSNumber* newMyNumber;

@end

@implementation MyNumber
@synthesize myNumber=_myNumber;
 
- (id)initWithNumber:(NSNumber *)number
{
  self = [super init];
  
  if ( self )
  {
    _myNumber = [number copy];
  }
  
  return self;
}

- (NSNumber*)newMyNumber
{
  if ( _myNumber )
    return [_myNumber retain];
  
  return [[NSNumber alloc] initWithInteger:1];
}

- (id)valueForUndefinedKey:(NSString*)key
{
  id value = 0;
  
  if ([key isEqualToString:@"MyIvarNumberAsPropertyOverReleased"])
    value = self.myNumber; // _myNumber will be over released, since the value returned from self.myNumber is not retained.
  else if ([key isEqualToString:@"MyIvarNumberAsPropertyOk"])
    value = [self.myNumber retain]; // this line fixes the over release
  else if ([key isEqualToString:@"MyIvarNumberAsNewMyNumber"])
    value = self.newMyNumber; // this one is ok, since value is returned retained
  else 
    value = [[NSNumber alloc] initWithInteger:0];
  
  return [value autorelease]; // expected-warning {{Object autoreleased too many times}}
}

@end

NSNumber* numberFromMyNumberProperty(MyNumber* aMyNumber)
{
  NSNumber* result = aMyNumber.myNumber;
    
  return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
}

#endif


// rdar://6611873

@interface Person : NSObject {
  NSString *_name;
}
@property (retain) NSString * name;
@property (assign) id friend;
@end

@implementation Person
@synthesize name = _name;

-(void)dealloc {
#if !__has_feature(objc_arc)
  self.name = [[NSString alloc] init]; // expected-warning {{leak}}

  [super dealloc]; // expected-warning {{The '_name' ivar in 'Person' was retained by a synthesized property but not released before '[super dealloc]}}
#endif
}
@end

#if !__has_feature(objc_arc)
void rdar6611873(void) {
  Person *p = [[[Person alloc] init] autorelease];
  
  p.name = [[NSString string] retain]; // expected-warning {{leak}}
  p.name = [[NSString alloc] init]; // expected-warning {{leak}}

  p.friend = [[Person alloc] init]; // expected-warning {{leak}}
}
#endif

@interface SubPerson : Person
-(NSString *)foo;
@end

@implementation SubPerson
-(NSString *)foo {
  return super.name;
}
@end


#if !__has_feature(objc_arc)
// <rdar://problem/9241180> Static analyzer doesn't detect uninitialized variable issues for property accesses
@interface RDar9241180
@property (readwrite,assign) id x;
-(id)testAnalyzer1:(int) y;
-(void)testAnalyzer2;
@end

@implementation RDar9241180
@synthesize x;
-(id)testAnalyzer1:(int)y {
    RDar9241180 *o;
    if (y && o.x) // expected-warning {{Property access on an uninitialized object pointer}}
      return o;
    return o; // expected-warning {{Undefined or garbage value returned to caller}}
}
-(void)testAnalyzer2 {
  id y;
  self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
}
@end
#endif


//------
// Property accessor synthesis
//------

extern void doSomethingWithPerson(Person *p);
extern void doSomethingWithName(NSString *name);

void testConsistencyRetain(Person *p) {
  clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}}

  id origName = p.name;
  clang_analyzer_eval(p.name == origName); // expected-warning{{TRUE}}
  doSomethingWithPerson(p);
  clang_analyzer_eval(p.name == origName); // expected-warning{{UNKNOWN}}
}

void testConsistencyAssign(Person *p) {
  clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}}

  id origFriend = p.friend;
  clang_analyzer_eval(p.friend == origFriend); // expected-warning{{TRUE}}
  doSomethingWithPerson(p);
  clang_analyzer_eval(p.friend == origFriend); // expected-warning{{UNKNOWN}}
}

@interface ClassWithShadowedReadWriteProperty {
  int _f;
}
@property (readonly) int someProp;
@end

@interface ClassWithShadowedReadWriteProperty ()
@property (readwrite) int someProp;
@end

@implementation ClassWithShadowedReadWriteProperty
- (void)testSynthesisForShadowedReadWriteProperties; {
  clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}

  _f = 1;

  // Read of shadowed property should not invalidate receiver.
  (void)self.someProp;
  clang_analyzer_eval(_f == 1); // expected-warning{{TRUE}}

  _f = 2;
  // Call to getter of shadowed property should not invalidate receiver.
  (void)[self someProp];
  clang_analyzer_eval(_f == 2); // expected-warning{{TRUE}}
}
@end

// Tests for the analyzer fix that works around a Sema bug
// where multiple methods are created for properties in class extensions that
// are redeclared in a category method.
// The Sema bug is tracked as <rdar://problem/25481164>.
@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory
@end

@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
@end

@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory ()
@property (readwrite) int someProp;
@property (readonly) int otherProp;
@end

@interface ClassWithRedeclaredPropertyInExtensionFollowedByCategory (MyCat)
@property (readonly) int someProp;
@property (readonly) int otherProp;
@end

@implementation ClassWithRedeclaredPropertyInExtensionFollowedByCategory
- (void)testSynthesisForRedeclaredProperties; {
  clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
  clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}

  clang_analyzer_eval(self.otherProp == self.otherProp); // expected-warning{{TRUE}}
  clang_analyzer_eval([self otherProp] == self.otherProp); // expected-warning{{TRUE}}
}
@end

// The relative order of the extension and the category matter, so test both.
@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension
@end

@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension ()
@property (readwrite) int someProp;
@end

@interface ClassWithRedeclaredPropertyInCategoryFollowedByExtension (MyCat)
@property (readonly) int someProp;
@end

@implementation ClassWithRedeclaredPropertyInCategoryFollowedByExtension
- (void)testSynthesisForRedeclaredProperties; {
  clang_analyzer_eval(self.someProp == self.someProp); // expected-warning{{TRUE}}
  clang_analyzer_eval([self someProp] == self.someProp); // expected-warning{{TRUE}}
}
@end

@interface ClassWithSynthesizedPropertyAndGetter
@property (readonly) int someProp;
@end

@implementation ClassWithSynthesizedPropertyAndGetter
@synthesize someProp;

// Make sure that the actual getter is inlined and not a getter created
// by BodyFarm
- (void)testBodyFarmGetterNotUsed {
  int i = self.someProp;
  clang_analyzer_eval(i == 22); // expected-warning {{TRUE}}
}

-(int)someProp {
  return 22;
}
@end

__attribute__((objc_root_class))
@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
@end

@protocol HasStuff
@property (nonatomic, readonly) int stuffProperty;
@end

@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Private)
@property (nonatomic, readonly) int stuffProperty;
@end

@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory (Internal) <HasStuff>
@end

@interface ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory() <HasStuff>
@end

@implementation ClassWithPrivatePropertyInClassExtensionWithProtocolShadowingCategory
@synthesize stuffProperty = _stuffProperty;

-(void)foo {
  (void)self.stuffProperty;
}
@end

//------
// Setter ivar invalidation.
//------

@interface ClassWithSetters
// Note: These properties have implicit @synthesize implementations to be
// backed with ivars.
@property (assign) int propWithIvar1;
@property (assign) int propWithIvar2;

@property (retain) NSNumber *retainedProperty;

@end

@interface ClassWithSetters (InOtherTranslationUnit)
// The implementation of this property is in another translation unit.
// We don't know whether it is backed by an ivar or not.
@property (assign) int propInOther;
@end

@implementation ClassWithSetters
- (void) testSettingPropWithIvarInvalidatesExactlyThatIvar; {
  _propWithIvar1 = 1;
  _propWithIvar2 = 2;
  self.propWithIvar1 = 66;

  // Calling the setter of a property backed by the instance variable
  // should invalidate the storage for the instance variable but not
  // the rest of the receiver. Ideally we would model the setter completely
  // but doing so would cause the new value to escape when it is bound
  // to the ivar. This would cause bad false negatives in the retain count
  // checker. (There is a test for this scenario in
  // testWriteRetainedValueToRetainedProperty below).
  clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}

  _propWithIvar1 = 1;
  [self setPropWithIvar1:66];

  clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{TRUE}}
}

- (void) testSettingPropWithoutIvarInvalidatesEntireInstance; {
  _propWithIvar1 = 1;
  _propWithIvar2 = 2;
  self.propInOther = 66;

  clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}

  _propWithIvar1 = 1;
  _propWithIvar2 = 2;
  [self setPropInOther:66];

  clang_analyzer_eval(_propWithIvar1 == 66); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval(_propWithIvar2 == 2);  // expected-warning{{UNKNOWN}}
}

#if !__has_feature(objc_arc)
- (void) testWriteRetainedValueToRetainedProperty; {
  NSNumber *number = [[NSNumber alloc] initWithInteger:5]; // expected-warning {{Potential leak of an object stored into 'number'}}

  // Make sure we catch this leak.
  self.retainedProperty = number;
}
#endif
@end

//------
// class properties
//------

int gBackingForReadWriteClassProp = 0;

@interface ClassWithClassProperties
@property(class, readonly) int readOnlyClassProp;

@property(class) int readWriteClassProp;

// Make sure we handle when a class and instance property have the same
// name. Test both when instance comes first and when class comes first.
@property(readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;
@property(class, readonly) int classAndInstancePropWithSameNameOrderInstanceFirst;

@property(class, readonly) int classAndInstancePropWithSameNameOrderClassFirst;
@property(readonly) int classAndInstancePropWithSameNameOrderClassFirst;


@property(class, readonly) int dynamicClassProp;

@end

@interface ClassWithClassProperties (OtherTranslationUnit)
@property(class, assign) id propInOtherTranslationUnit;
@end

@implementation ClassWithClassProperties

@dynamic dynamicClassProp;

+ (int)readOnlyClassProp {
  return 1;
}

+ (int)readWriteClassProp {
  return gBackingForReadWriteClassProp;
}

+ (void)setReadWriteClassProp:(int)val {
  gBackingForReadWriteClassProp = val;
}

- (int)classAndInstancePropWithSameNameOrderInstanceFirst {
  return 12;
}

+ (int)classAndInstancePropWithSameNameOrderInstanceFirst {
  return 13;
}

+ (int)classAndInstancePropWithSameNameOrderClassFirst {
  return 14;
}

- (int)classAndInstancePropWithSameNameOrderClassFirst {
  return 15;
}

- (void)testInlineClassProp {
  clang_analyzer_eval(ClassWithClassProperties.readOnlyClassProp == 1); // expected-warning{{TRUE}}

  ClassWithClassProperties.readWriteClassProp = 7;
  clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 7); // expected-warning{{TRUE}}
  ClassWithClassProperties.readWriteClassProp = 8;
  clang_analyzer_eval(ClassWithClassProperties.readWriteClassProp == 8); // expected-warning{{TRUE}}
}

- (void)testUnknownClassProp {
  clang_analyzer_eval(ClassWithClassProperties.propInOtherTranslationUnit == ClassWithClassProperties.propInOtherTranslationUnit); // expected-warning{{UNKNOWN}}
}

- (void)testEscapeGlobalOnUnknownProp {
  gBackingForReadWriteClassProp = 33;
  ClassWithClassProperties.propInOtherTranslationUnit = 0;
  clang_analyzer_eval(gBackingForReadWriteClassProp == 33); // expected-warning{{UNKNOWN}}
}

- (void)testClassAndInstancePropertyWithSameName {
  clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderInstanceFirst == 12); // expected-warning{{TRUE}}
  clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderInstanceFirst == 13); // expected-warning{{TRUE}}

  clang_analyzer_eval(ClassWithClassProperties.classAndInstancePropWithSameNameOrderClassFirst == 14); // expected-warning{{TRUE}}
  clang_analyzer_eval(self.classAndInstancePropWithSameNameOrderClassFirst == 15); // expected-warning{{TRUE}}
}

- (void)testDynamicClassProp {
  clang_analyzer_eval(ClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{UNKNOWN}}
}

@end

@interface SubclassOfClassWithClassProperties : ClassWithClassProperties
@end

@implementation SubclassOfClassWithClassProperties
+ (int)dynamicClassProp; {
 return 16;
}

- (void)testDynamicClassProp {
  clang_analyzer_eval(SubclassOfClassWithClassProperties.dynamicClassProp == 16); // expected-warning{{TRUE}}
}

@end


#if !__has_feature(objc_arc)
void testOverrelease(Person *p, int coin) {
  switch (coin) {
  case 0:
    [p.name release]; // expected-warning{{not owned}}
    break;
  case 1:
    [p.friend release]; // expected-warning{{not owned}}
    break;
  case 2: {
    id friend = p.friend;
    doSomethingWithPerson(p);
    [friend release]; // expected-warning{{not owned}}
  }
  }
}

// <rdar://problem/16333368>
@implementation Person (Rdar16333368)

- (void)testDeliberateRelease:(Person *)other {
  doSomethingWithName(self.name);
  [_name release]; // no-warning
  self->_name = 0;

  doSomethingWithName(other->_name);
  [other.name release]; // no-warning
}

- (void)deliberateReleaseFalseNegative {
  // This is arguably a false negative because the result of p.friend shouldn't
  // be released, even though we are manipulating the ivar in between the two
  // actions.
  id name = self.name;
  _name = 0;
  [name release];
}

- (void)testRetainAndRelease {
  [self.name retain];
  [self.name release];
  [self.name release]; // expected-warning{{not owned}}
}

- (void)testRetainAndReleaseIVar {
  [self.name retain];
  [_name release];
  [_name release];
}

@end
#endif

@interface IntWrapper
@property int value;
@end

@implementation IntWrapper
@synthesize value;
@end

void testConsistencyInt(IntWrapper *w) {
  clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}

  int origValue = w.value;
  if (origValue != 42)
    return;

  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
}

void testConsistencyInt2(IntWrapper *w) {
  if (w.value != 42)
    return;

  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
}


@interface IntWrapperAuto
@property int value;
@end

@implementation IntWrapperAuto
@end

void testConsistencyIntAuto(IntWrapperAuto *w) {
  clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}

  int origValue = w.value;
  if (origValue != 42)
    return;

  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
}

void testConsistencyIntAuto2(IntWrapperAuto *w) {
  if (w.value != 42)
    return;

  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
}


typedef struct {
  int value;
} IntWrapperStruct;

@interface StructWrapper
@property IntWrapperStruct inner;
@end

@implementation StructWrapper
@synthesize inner;
@end

void testConsistencyStruct(StructWrapper *w) {
  clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}

  int origValue = w.inner.value;
  if (origValue != 42)
    return;

  clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
}


@interface OpaqueIntWrapper
@property int value;
@end

// For now, don't assume a property is implemented using an ivar unless we can
// actually see that it is.
void testOpaqueConsistency(OpaqueIntWrapper *w) {
  clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}}
}


#if !__has_feature(objc_arc)
// Test quite a few cases of retain/release issues.

@interface RetainCountTesting
@property (strong) id ownedProp;
@property (unsafe_unretained) id unownedProp;
@property (nonatomic, strong) id manualProp;
@property (readonly) id readonlyProp;
@property (nonatomic, readwrite/*, assign */) id implicitManualProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
@property (nonatomic, readwrite/*, assign */) id implicitSynthProp; // expected-warning {{'assign' is assumed}} expected-warning {{'assign' not appropriate}}
@property CFTypeRef cfProp;
@end

@implementation RetainCountTesting {
  id _ivarOnly;
}

- (id)manualProp {
  return _manualProp;
}

- (void)setImplicitManualProp:(id)newValue {}

- (void)testOverreleaseOwnedIvar {
  [_ownedProp retain];
  [_ownedProp release];
  [_ownedProp release];
  [_ownedProp release]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseUnownedIvar {
  [_unownedProp retain];
  [_unownedProp release];
  [_unownedProp release]; // FIXME-warning{{not owned at this point by the caller}}
}

- (void)testOverreleaseIvarOnly {
  [_ivarOnly retain];
  [_ivarOnly release];
  [_ivarOnly release];
  [_ivarOnly release]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseReadonlyIvar {
  [_readonlyProp retain];
  [_readonlyProp release];
  [_readonlyProp release];
  [_readonlyProp release]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseImplicitManualIvar {
  [_implicitManualProp retain];
  [_implicitManualProp release];
  [_implicitManualProp release];
  [_implicitManualProp release]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseImplicitSynthIvar {
  [_implicitSynthProp retain];
  [_implicitSynthProp release];
  [_implicitSynthProp release]; // FIXME-warning{{not owned at this point by the caller}}
}

- (void)testOverreleaseCF {
  CFRetain(_cfProp);
  CFRelease(_cfProp);
  CFRelease(_cfProp);
  CFRelease(_cfProp); // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseOwnedIvarUse {
  [_ownedProp retain];
  [_ownedProp release];
  [_ownedProp release];
  [_ownedProp myMethod]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseIvarOnlyUse {
  [_ivarOnly retain];
  [_ivarOnly release];
  [_ivarOnly release];
  [_ivarOnly myMethod]; // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseCFUse {
  CFRetain(_cfProp);
  CFRelease(_cfProp);
  CFRelease(_cfProp);

  extern void CFUse(CFTypeRef);
  CFUse(_cfProp); // FIXME-warning{{used after it is released}}
}

- (void)testOverreleaseOwnedIvarAutoreleaseOkay {
  [_ownedProp retain];
  [_ownedProp release];
  [_ownedProp autorelease];
} // no-warning

- (void)testOverreleaseIvarOnlyAutoreleaseOkay {
  [_ivarOnly retain];
  [_ivarOnly release];
  [_ivarOnly autorelease];
} // no-warning

- (void)testOverreleaseOwnedIvarAutorelease {
  [_ownedProp retain];
  [_ownedProp release];
  [_ownedProp autorelease];
  [_ownedProp autorelease];
} // FIXME-warning{{Object autoreleased too many times}}

- (void)testOverreleaseIvarOnlyAutorelease {
  [_ivarOnly retain];
  [_ivarOnly release];
  [_ivarOnly autorelease];
  [_ivarOnly autorelease];
} // FIXME-warning{{Object autoreleased too many times}}

- (void)testPropertyAccessThenReleaseOwned {
  id owned = [self.ownedProp retain];
  [owned release];
  [_ownedProp release];
  clang_analyzer_eval(owned == _ownedProp); // expected-warning{{TRUE}}
}

- (void)testPropertyAccessThenReleaseOwned2 {
  id fromIvar = _ownedProp;
  id owned = [self.ownedProp retain];
  [owned release];
  [fromIvar release];
  clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
}

- (void)testPropertyAccessThenReleaseUnowned {
  id unowned = [self.unownedProp retain];
  [unowned release];
  [_unownedProp release]; // FIXME-warning{{not owned}}
}

- (void)testPropertyAccessThenReleaseUnowned2 {
  id fromIvar = _unownedProp;
  id unowned = [self.unownedProp retain];
  [unowned release];
  clang_analyzer_eval(unowned == fromIvar); // expected-warning{{TRUE}}
  [fromIvar release]; // FIXME-warning{{not owned}}
}

- (void)testPropertyAccessThenReleaseManual {
  id prop = [self.manualProp retain];
  [prop release];
  [_manualProp release]; // no-warning
}

- (void)testPropertyAccessThenReleaseManual2 {
  id fromIvar = _manualProp;
  id prop = [self.manualProp retain];
  [prop release];
  clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
  [fromIvar release]; // no-warning
}

- (void)testPropertyAccessThenReleaseCF {
  CFTypeRef owned = CFRetain(self.cfProp);
  CFRelease(owned);
  CFRelease(_cfProp); // no-warning
  clang_analyzer_eval(owned == _cfProp); // expected-warning{{TRUE}}
}

- (void)testPropertyAccessThenReleaseCF2 {
  CFTypeRef fromIvar = _cfProp;
  CFTypeRef owned = CFRetain(self.cfProp);
  CFRelease(owned);
  CFRelease(fromIvar);
  clang_analyzer_eval(owned == fromIvar); // expected-warning{{TRUE}}
}

- (void)testPropertyAccessThenReleaseReadonly {
  id prop = [self.readonlyProp retain];
  [prop release];
  [_readonlyProp release]; // no-warning
}

- (void)testPropertyAccessThenReleaseReadonly2 {
  id fromIvar = _readonlyProp;
  id prop = [self.readonlyProp retain];
  [prop release];
  clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
  [fromIvar release]; // no-warning
}

- (void)testPropertyAccessThenReleaseImplicitManual {
  id prop = [self.implicitManualProp retain];
  [prop release];
  [_implicitManualProp release]; // no-warning
}

- (void)testPropertyAccessThenReleaseImplicitManual2 {
  id fromIvar = _implicitManualProp;
  id prop = [self.implicitManualProp retain];
  [prop release];
  clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
  [fromIvar release]; // no-warning
}

- (void)testPropertyAccessThenReleaseImplicitSynth {
  id prop = [self.implicitSynthProp retain];
  [prop release];
  [_implicitSynthProp release]; // FIXME-warning{{not owned}}
}

- (void)testPropertyAccessThenReleaseImplicitSynth2 {
  id fromIvar = _implicitSynthProp;
  id prop = [self.implicitSynthProp retain];
  [prop release];
  clang_analyzer_eval(prop == fromIvar); // expected-warning{{TRUE}}
  [fromIvar release]; // FIXME-warning{{not owned}}
}

- (id)getUnownedFromProperty {
  [_ownedProp retain];
  [_ownedProp autorelease];
  return _ownedProp; // no-warning
}

- (id)transferUnownedFromProperty {
  [_ownedProp retain];
  [_ownedProp autorelease];
  return [_ownedProp autorelease]; // no-warning
}

- (id)transferOwnedFromProperty __attribute__((ns_returns_retained)) {
  [_ownedProp retain];
  [_ownedProp autorelease];
  return _ownedProp; // no-warning
}

- (void)testAssignOwned:(id)newValue {
  _ownedProp = newValue;
  [_ownedProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignUnowned:(id)newValue {
  _unownedProp = newValue;
  [_unownedProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignIvarOnly:(id)newValue {
  _ivarOnly = newValue;
  [_ivarOnly release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignCF:(CFTypeRef)newValue {
  _cfProp = newValue;
  CFRelease(_cfProp); // FIXME: no-warning{{not owned}}
}

- (void)testAssignReadonly:(id)newValue {
  _readonlyProp = newValue;
  [_readonlyProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignImplicitManual:(id)newValue {
  _implicitManualProp = newValue;
  [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignImplicitSynth:(id)newValue {
  _implicitSynthProp = newValue;
  [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignOwnedOkay:(id)newValue {
  _ownedProp = [newValue retain];
  [_ownedProp release]; // no-warning
}

- (void)testAssignUnownedOkay:(id)newValue {
  _unownedProp = [newValue retain];
  [_unownedProp release]; // no-warning
}

- (void)testAssignIvarOnlyOkay:(id)newValue {
  _ivarOnly = [newValue retain];
  [_ivarOnly release]; // no-warning
}

- (void)testAssignCFOkay:(CFTypeRef)newValue {
  _cfProp = CFRetain(newValue);
  CFRelease(_cfProp); // no-warning
}

- (void)testAssignReadonlyOkay:(id)newValue {
  _readonlyProp = [newValue retain];
  [_readonlyProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignImplicitManualOkay:(id)newValue {
  _implicitManualProp = [newValue retain];
  [_implicitManualProp release]; // FIXME: no-warning{{not owned}}
}

- (void)testAssignImplicitSynthOkay:(id)newValue {
  _implicitSynthProp = [newValue retain];
  [_implicitSynthProp release]; // FIXME: no-warning{{not owned}}
}

// rdar://problem/19862648
- (void)establishIvarIsNilDuringLoops {
  extern id getRandomObject(void);

  int i = 4; // Must be at least 4 to trigger the bug.
  while (--i) {
    id x = 0;
    if (getRandomObject())
      x = _ivarOnly;
    if (!x)
      x = getRandomObject();
    [x myMethod];
  }
}

// rdar://problem/20335433
- (void)retainIvarAndInvalidateSelf {
  extern void invalidate(id);
  [_unownedProp retain];
  invalidate(self);
  [_unownedProp release]; // no-warning
}

@end

@interface Wrapper
@property(nonatomic, readonly) int value;
@end

@implementation Wrapper
@synthesize value;
@end

void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll(void) {
   union {
    Wrapper *wrapper;
   } u = { 0 };
   [u.wrapper value];
}

#endif // non-ARC

@interface ExplicitAccessorInCategory : NSObject
@property(readonly) int normal;
- (int)normal;
@property(readonly) int no_custom_accessor;
@end

@interface ExplicitAccessorInCategory ()
@property(readonly) int in_category;

@property(readonly) int still_no_custom_accessor;
// This is an ordinary method, not a getter.
- (int)still_no_custom_accessor;
@end

@interface ExplicitAccessorInCategory ()
- (int)in_category;

// This is an ordinary method, not a getter.
- (int)no_custom_accessor;
@end

@implementation ExplicitAccessorInCategory
- (void)foo {
	// Make sure we don't farm bodies for explicit accessors: in particular,
	// we're not sure that the accessor always returns the same value.
	clang_analyzer_eval(self.normal == self.normal); // expected-warning{{UNKNOWN}}
	// Also this used to crash.
	clang_analyzer_eval(self.in_category == self.in_category); // expected-warning{{UNKNOWN}}

	// When there is no explicit accessor defined (even if it looks like there is),
	// farm the getter body and see if it does actually always yield the same value.
	clang_analyzer_eval(self.no_custom_accessor == self.no_custom_accessor); // expected-warning{{TRUE}}
	clang_analyzer_eval(self.still_no_custom_accessor == self.still_no_custom_accessor); // expected-warning{{TRUE}}
}
@end

@interface Shadowed
@property (assign) NSObject *o;
- (NSObject *)getShadowedIvar;
- (void)clearShadowedIvar;
- (NSObject *)getShadowedProp;
- (void)clearShadowedProp;

@property (assign) NSObject *o2;
@end

@implementation Shadowed
- (NSObject *)getShadowedIvar {
  return self->_o;
}
- (void)clearShadowedIvar {
  self->_o = nil;
}
- (NSObject *)getShadowedProp {
  return self.o;
}
- (void)clearShadowedProp {
  self.o = nil;
}
@end

@interface Shadowing : Shadowed
@end

@implementation Shadowing
// Property 'o' is declared in the superclass but synthesized here.
// This creates a separate ivar that shadows the superclass's ivar,
// but the old ivar is still accessible from the methods of the superclass.
// The old property, however, is not accessible with the property syntax
// even from the superclass methods.
@synthesize o;

-(void)testPropertyShadowing {
  NSObject *oo = self.o; // no-crash
  clang_analyzer_eval(self.o == oo); // expected-warning{{TRUE}}
  clang_analyzer_eval([self getShadowedIvar] == oo); // expected-warning{{UNKNOWN}}
  [self clearShadowedIvar];
  clang_analyzer_eval(self.o == oo); // expected-warning{{TRUE}}
  clang_analyzer_eval([self getShadowedIvar] == oo); // expected-warning{{UNKNOWN}}
  clang_analyzer_eval([self getShadowedIvar] == nil); // expected-warning{{TRUE}}
}

@synthesize o2 = ooo2;

-(void)testPropertyShadowingWithExplicitIvar {
  NSObject *oo2 = self.o2; // no-crash
}
@end
