1 | // RUN: %clang_cc1 -x objective-c -fsyntax-only -verify -Wno-objc-root-class %s |
2 | // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s |
3 | // rdar://8843851 |
4 | |
5 | @interface StopAccessingIvarsDirectlyExample |
6 | @property(strong) id name, rank, serialNumber; |
7 | @end |
8 | |
9 | @implementation StopAccessingIvarsDirectlyExample |
10 | |
11 | - (void)identifyYourSelf { |
12 | if (self.name && self.rank && self.serialNumber) |
13 | self.name = 0; |
14 | } |
15 | |
16 | // @synthesize name, rank, serialNumber; |
17 | // default synthesis allows direct access to property ivars. |
18 | - (id)init { |
19 | _name = _rank = _serialNumber = 0; |
20 | return self; |
21 | } |
22 | |
23 | - (void)dealloc { |
24 | } |
25 | @end |
26 | |
27 | |
28 | // Test2 |
29 | @interface Test2 |
30 | @property(strong, nonatomic) id object; |
31 | @end |
32 | |
33 | // object has user declared setter/getter so it won't be |
34 | // default synthesized; thus causing user error. |
35 | @implementation Test2 |
36 | - (id) bar { return object; } // expected-error {{use of undeclared identifier 'object'}} |
37 | - (void)setObject:(id)newObject {} |
38 | - (id)object { return 0; } |
39 | @end |
40 | |
41 | // Test3 |
42 | @interface Test3 |
43 | { |
44 | id uid; // expected-note {{instance variable is declared here}} |
45 | } |
46 | @property (readwrite, assign) id uid; // expected-note {{property declared here}} |
47 | @end |
48 | |
49 | // rdar://11671080 |
50 | @implementation Test3 // expected-warning {{autosynthesized property 'uid' will use synthesized instance variable '_uid', not existing instance variable 'uid'}} |
51 | // Oops, forgot to write @synthesize! will be default synthesized |
52 | - (void) myMethod { |
53 | self.uid = 0; // Use of the “setter” |
54 | uid = 0; // Use of the wrong instance variable |
55 | _uid = 0; // Use of the property instance variable |
56 | } |
57 | @end |
58 | |
59 | @interface Test4 { |
60 | id _var; |
61 | } |
62 | @property (readwrite, assign) id var; |
63 | @end |
64 | |
65 | |
66 | // default synthesize property named 'var' |
67 | @implementation Test4 |
68 | - (id) myMethod { |
69 | return self->_var; // compiles because 'var' is synthesized by default |
70 | } |
71 | @end |
72 | |
73 | @interface Test5 |
74 | { |
75 | id _var; |
76 | } |
77 | @property (readwrite, assign) id var; |
78 | @end |
79 | |
80 | // default synthesis of property 'var' |
81 | @implementation Test5 |
82 | - (id) myMethod { |
83 | Test5 *foo = 0; |
84 | return foo->_var; // OK |
85 | } |
86 | @end |
87 | |
88 | @interface Test6 |
89 | { |
90 | id _var; // expected-note {{'_var' declared here}} |
91 | } |
92 | @property (readwrite, assign) id var; |
93 | @end |
94 | |
95 | // no default synthesis. So error is expected. |
96 | @implementation Test6 |
97 | - (id) myMethod |
98 | { |
99 | return var; // expected-error {{use of undeclared identifier 'var'}} |
100 | } |
101 | @synthesize var = _var; |
102 | @end |
103 | |
104 | int* _object; |
105 | |
106 | @interface Test7 |
107 | @property (readwrite, assign) id object; |
108 | @end |
109 | |
110 | // With default synthesis, '_object' is be the synthesized ivar not the global |
111 | // 'int*' object. So no error. |
112 | @implementation Test7 |
113 | - (id) myMethod { |
114 | return _object; |
115 | } |
116 | @end |
117 | |
118 | // rdar://11671080 |
119 | @interface Test8 |
120 | { |
121 | id _y; |
122 | id y; // expected-note {{instance variable is declared here}} |
123 | } |
124 | @property(copy) id y; // expected-note {{property declared here}} |
125 | @end |
126 | |
127 | |
128 | @implementation Test8 @end // expected-warning {{autosynthesized property 'y' will use instance variable '_y', not existing instance variable 'y'}} |
129 | |
130 | |