1 | // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions -verify -fblocks %s |
2 | |
3 | typedef 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 | |
16 | @interface AnnotatedClass : NSObject { |
17 | } |
18 | - (void) someMethod: (MyClass*)In __attribute__((annotate("objc_no_direct_instance_variable_assignment"))); |
19 | - (void) someMethodNotAnnaotated: (MyClass*)In; |
20 | @end |
21 | |
22 | |
23 | @interface TestProperty : AnnotatedClass { |
24 | MyClass *_Z; |
25 | id _nonSynth; |
26 | MyClass* _NotA __attribute__((annotate("objc_allow_direct_instance_variable_assignment"))); |
27 | } |
28 | |
29 | @property (assign, nonatomic) MyClass* A; // explicitly synthesized, not implemented, non-default ivar name |
30 | |
31 | @property (assign) MyClass* X; // automatically synthesized, not implemented |
32 | |
33 | @property (assign, nonatomic) MyClass* Y; // automatically synthesized, implemented |
34 | |
35 | @property (assign, nonatomic) MyClass* Z; // non-synthesized ivar, implemented setter |
36 | @property (readonly) id nonSynth; // non-synthesized, explicitly implemented to return ivar with expected name |
37 | |
38 | @property (assign) MyClass* NotA; // warnings should be suppressed, backing ivar is annotated |
39 | @property (assign) MyClass* NotX __attribute__((annotate("objc_allow_direct_instance_variable_assignment"))); // warnings should be suppressed |
40 | |
41 | @end |
42 | |
43 | @implementation TestProperty |
44 | @synthesize A = __A; |
45 | |
46 | - (void) someMethod: (MyClass*)In { |
47 | (__A) = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}} |
48 | _X = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}} |
49 | _Y = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}} |
50 | _Z = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}} |
51 | _nonSynth = 0; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}} |
52 | _NotX = 0; // no-warning |
53 | _NotA = 0; // no-warning |
54 | } |
55 | - (void) someMethodNotAnnaotated: (MyClass*)In { |
56 | (__A) = In; |
57 | _X = In; // no-warning |
58 | _Y = In; // no-warning |
59 | _Z = In; // no-warning |
60 | _nonSynth = 0; // no-warning |
61 | } |
62 | |
63 | @end |