1// RUN: %clang_analyze_cc1 -verify -fblocks %s \
2// RUN:   -analyzer-checker=core \
3// RUN:   -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment \
4// RUN:   -analyzer-config \
5// RUN:     alpha.osx.cocoa.DirectIvarAssignment:AnnotatedFunctions=true
6
7typedef signed char BOOL;
8@protocol NSObject  - (BOOL)isEqual:(id)object; @end
9@interface NSObject <NSObject> {}
10+(id)alloc;
11-(id)init;
12-(id)autorelease;
13-(id)copy;
14-(id)retain;
15@end
16
17@interface MyClass;
18@end
19
20@interface AnnotatedClass : NSObject {
21}
22  - (void) someMethod: (MyClass*)In __attribute__((annotate("objc_no_direct_instance_variable_assignment")));
23  - (void) someMethodNotAnnaotated: (MyClass*)In;
24@end
25
26
27@interface TestProperty : AnnotatedClass {
28  MyClass *_Z;
29  id _nonSynth;
30  MyClass* _NotA __attribute__((annotate("objc_allow_direct_instance_variable_assignment")));
31}
32
33  @property (assign, nonatomic) MyClass* A; // explicitly synthesized, not implemented, non-default ivar name
34
35  @property (assign) MyClass* X;  // automatically synthesized, not implemented
36
37  @property (assign, nonatomic) MyClass* Y; // automatically synthesized, implemented
38
39  @property (assign, nonatomic) MyClass* Z; // non-synthesized ivar, implemented setter
40  @property (readonly) id nonSynth;  // non-synthesized, explicitly implemented to return ivar with expected name
41
42  @property (assign) MyClass* NotA;  // warnings should be suppressed, backing ivar is annotated
43  @property (assign) MyClass* NotX __attribute__((annotate("objc_allow_direct_instance_variable_assignment")));  // warnings should be suppressed
44
45  @end
46
47@implementation TestProperty
48  @synthesize A = __A;
49
50  - (void) someMethod: (MyClass*)In {
51    (__A) = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
52    _X = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
53    _Y = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
54    _Z = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
55    _nonSynth = 0; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
56    _NotX = 0; // no-warning
57    _NotA = 0; // no-warning
58  }
59  - (void) someMethodNotAnnaotated: (MyClass*)In {
60    (__A) = In;
61    _X = In; // no-warning
62    _Y = In; // no-warning
63    _Z = In; // no-warning
64    _nonSynth = 0; // no-warning
65  }
66
67  @end
68