blob: 90ba75f6efde730dbd4a0c29fadc67bdb392d17f [file] [log] [blame]
Jordan Rosed3934582012-09-28 22:21:30 +00001// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Warc-repeated-use-of-weak -verify %s
2
3@interface Test {
4@public
5 Test *ivar;
Jordan Rose657b5f42012-09-28 22:21:35 +00006 __weak id weakIvar;
Jordan Rosed3934582012-09-28 22:21:30 +00007}
8@property(weak) Test *weakProp;
9@property(strong) Test *strongProp;
10
11- (__weak id)implicitProp;
12
13+ (__weak id)weakProp;
14@end
15
16extern void use(id);
17extern id get();
18extern bool condition();
19#define nil ((id)0)
20
21void sanity(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +000022 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
Jordan Rosed3934582012-09-28 22:21:30 +000023 use(a.weakProp); // expected-note{{also accessed here}}
24
25 use(a.strongProp);
26 use(a.strongProp); // no-warning
27
28 use(a.weakProp); // expected-note{{also accessed here}}
29}
30
31void singleUse(Test *a) {
32 use(a.weakProp); // no-warning
33 use(a.strongProp); // no-warning
34}
35
36void assignsOnly(Test *a) {
37 a.weakProp = get(); // no-warning
38
39 id next = get();
40 if (next)
41 a.weakProp = next; // no-warning
Jordan Rose657b5f42012-09-28 22:21:35 +000042
43 a->weakIvar = get(); // no-warning
44 next = get();
45 if (next)
46 a->weakIvar = next; // no-warning
47
48 extern __weak id x;
49 x = get(); // no-warning
50 next = get();
51 if (next)
52 x = next; // no-warning
Jordan Rosed3934582012-09-28 22:21:30 +000053}
54
55void assignThenRead(Test *a) {
56 a.weakProp = get(); // expected-note{{also accessed here}}
Jordan Rose657b5f42012-09-28 22:21:35 +000057 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +000058}
59
60void twoVariables(Test *a, Test *b) {
61 use(a.weakProp); // no-warning
62 use(b.weakProp); // no-warning
63}
64
65void doubleLevelAccess(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +000066 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times in this function and may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
Jordan Rosed3934582012-09-28 22:21:30 +000067 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
68}
69
70void doubleLevelAccessIvar(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +000071 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +000072 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
73}
74
75void implicitProperties(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +000076 use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +000077 use(a.implicitProp); // expected-note{{also accessed here}}
78}
79
80void classProperties() {
Jordan Rose657b5f42012-09-28 22:21:35 +000081 use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +000082 use(Test.weakProp); // expected-note{{also accessed here}}
83}
84
85void classPropertiesAreDifferent(Test *a) {
86 use(Test.weakProp); // no-warning
87 use(a.weakProp); // no-warning
88 use(a.strongProp.weakProp); // no-warning
89}
90
Jordan Rose657b5f42012-09-28 22:21:35 +000091void ivars(Test *a) {
92 use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
93 use(a->weakIvar); // expected-note{{also accessed here}}
94}
95
96void globals() {
97 extern __weak id a;
98 use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
99 use(a); // expected-note{{also accessed here}}
100}
101
Jordan Rosed3934582012-09-28 22:21:30 +0000102
103void assignToStrongWrongInit(Test *a) {
104 id val = a.weakProp; // expected-note{{also accessed here}}
Jordan Rose657b5f42012-09-28 22:21:35 +0000105 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000106}
107
108void assignToStrongWrong(Test *a) {
109 id val;
110 val = a.weakProp; // expected-note{{also accessed here}}
Jordan Rose657b5f42012-09-28 22:21:35 +0000111 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
112}
113
114void assignToIvarWrong(Test *a) {
115 a->weakIvar = get(); // expected-note{{also accessed here}}
116 use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
117}
118
119void assignToGlobalWrong() {
120 extern __weak id a;
121 a = get(); // expected-note{{also accessed here}}
122 use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000123}
124
125void assignToStrongOK(Test *a) {
126 if (condition()) {
127 id val = a.weakProp; // no-warning
128 (void)val;
129 } else {
130 id val;
131 val = a.weakProp; // no-warning
132 (void)val;
133 }
134}
135
136void assignToStrongConditional(Test *a) {
137 id val = (condition() ? a.weakProp : a.weakProp); // no-warning
138 id val2 = a.implicitProp ?: a.implicitProp; // no-warning
139}
140
141void testBlock(Test *a) {
142 use(a.weakProp); // no-warning
143
144 use(^{
Jordan Rose657b5f42012-09-28 22:21:35 +0000145 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}
Jordan Rosed3934582012-09-28 22:21:30 +0000146 use(a.weakProp); // expected-note{{also accessed here}}
147 });
148}
149
150
151@interface Test (Methods)
152@end
153
154@implementation Test (Methods)
155- (void)sanity {
Jordan Rose657b5f42012-09-28 22:21:35 +0000156 use(self.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
Jordan Rosed3934582012-09-28 22:21:30 +0000157 use(self.weakProp); // expected-note{{also accessed here}}
158}
159
Jordan Rose657b5f42012-09-28 22:21:35 +0000160- (void)ivars {
161 use(weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
162 use(weakIvar); // expected-note{{also accessed here}}
163}
164
Jordan Rosed3934582012-09-28 22:21:30 +0000165- (void)doubleLevelAccessForSelf {
Jordan Rose657b5f42012-09-28 22:21:35 +0000166 use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000167 use(self.strongProp.weakProp); // expected-note{{also accessed here}}
168
Jordan Rose657b5f42012-09-28 22:21:35 +0000169 use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000170 use(self->ivar.weakProp); // expected-note{{also accessed here}}
Jordan Rose657b5f42012-09-28 22:21:35 +0000171
172 use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
173 use(self->ivar->weakIvar); // expected-note{{also accessed here}}
Jordan Rosed3934582012-09-28 22:21:30 +0000174}
175
176- (void)distinctFromOther:(Test *)other {
177 use(self.strongProp.weakProp); // no-warning
178 use(other.strongProp.weakProp); // no-warning
179
180 use(self->ivar.weakProp); // no-warning
181 use(other->ivar.weakProp); // no-warning
Jordan Rose657b5f42012-09-28 22:21:35 +0000182
183 use(self.strongProp->weakIvar); // no-warning
184 use(other.strongProp->weakIvar); // no-warning
Jordan Rosed3934582012-09-28 22:21:30 +0000185}
186@end
187
188
189class Wrapper {
190 Test *a;
191
192public:
193 void fields() {
Jordan Rose657b5f42012-09-28 22:21:35 +0000194 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
Jordan Rosed3934582012-09-28 22:21:30 +0000195 use(a.weakProp); // expected-note{{also accessed here}}
196 }
197
198 void distinctFromOther(Test *b, const Wrapper &w) {
199 use(a.weakProp); // no-warning
200 use(b.weakProp); // no-warning
201 use(w.a.weakProp); // no-warning
202 }
203
204 static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000205 use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000206 use(y.a.weakProp); // expected-note{{also accessed here}}
207 }
208};
209
210
211// -----------------------
212// False positives
213// -----------------------
214
215// Most of these would require flow-sensitive analysis to silence correctly.
216
217void assignAfterRead(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000218 if (!a.weakProp) // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000219 a.weakProp = get(); // expected-note{{also accessed here}}
220}
221
222void assignNil(Test *a) {
223 if (condition())
224 a.weakProp = nil; // expected-note{{also accessed here}}
225
Jordan Rose657b5f42012-09-28 22:21:35 +0000226 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000227}
228
229void branch(Test *a) {
230 if (condition())
Jordan Rose657b5f42012-09-28 22:21:35 +0000231 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000232 else
233 use(a.weakProp); // expected-note{{also accessed here}}
234}
235
236void doubleLevelAccess(Test *a, Test *b) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000237 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000238 use(b.strongProp.weakProp); // expected-note{{also accessed here}}
239
240 use(a.weakProp.weakProp); // no-warning
241}
242
243void doubleLevelAccessIvar(Test *a, Test *b) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000244 use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000245 use(b->ivar.weakProp); // expected-note{{also accessed here}}
246
247 use(a.strongProp.weakProp); // no-warning
248}