1// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment -verify -fblocks %s
2
3typedef signed char BOOL;
4@protocol NSObject  - (BOOL)isEqual:(id)object; @end
5@interface NSObject <NSObject> {}
6+(id)alloc;
7-(id)init;
8-(id)autorelease;
9-(id)copy;
10-(id)retain;
11@end
12
13@interface MyClass;
14@end
15@interface TestProperty :NSObject {
16  MyClass *_Z;
17  id _nonSynth;
18}
19
20  @property (assign, nonatomic) MyClass* A; // explicitely synthesized, not implemented, non-default ivar name
21
22  @property (assign) MyClass* X;  // automatically synthesized, not implemented
23
24  @property (assign, nonatomic) MyClass* Y; // automatically synthesized, implemented
25
26  @property (assign, nonatomic) MyClass* Z; // non-synthesized ivar, implemented setter
27  @property (readonly) id nonSynth;  // non-synthesized, explicitly implemented to return ivar with expected name
28  
29  - (id) initWithPtr:(MyClass*) value;
30  - (id) myInitWithPtr:(MyClass*) value;
31  - (void) someMethod: (MyClass*)In;
32@end
33
34@implementation TestProperty
35  @synthesize A = __A;
36  
37  - (id) initWithPtr: (MyClass*) value {
38    _Y = value; // no-warning
39    return self;
40  }
41
42  - (id) copyWithPtrY: (TestProperty*) value {
43    TestProperty *another = [[TestProperty alloc] init];
44    another->_Y = value->_Y; // no-warning
45    return another;
46  }
47
48  - (id) myInitWithPtr: (MyClass*) value {
49    _Y = value; // no-warning
50    return self;
51  }
52  
53  - (void) setY:(MyClass*) NewValue {
54    _Y = NewValue; // no-warning
55  }
56
57  - (void) setZ:(MyClass*) NewValue {
58    _Z = NewValue; // no-warning
59  }
60
61  - (id)nonSynth {
62      return _nonSynth;
63  }
64
65  - (void) someMethod: (MyClass*)In {
66    (__A) = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
67    _X = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
68    _Y = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
69    _Z = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
70    _nonSynth = 0; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
71  }
72@end