blob: 1c6578ef13138f9b52450698945336f48dd103b2 [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
Jordan Rosee723a272012-10-10 16:43:06 +0000150void assignToStrongWithCasts(Test *a) {
151 if (condition()) {
152 Test *val = (Test *)a.weakProp; // no-warning
153 (void)val;
154 } else {
155 id val;
156 val = (Test *)a.weakProp; // no-warning
157 (void)val;
158 }
159}
160
Jordan Rosed3934582012-09-28 22:21:30 +0000161
162@interface Test (Methods)
163@end
164
165@implementation Test (Methods)
166- (void)sanity {
Jordan Rose657b5f42012-09-28 22:21:35 +0000167 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 +0000168 use(self.weakProp); // expected-note{{also accessed here}}
169}
170
Jordan Rose657b5f42012-09-28 22:21:35 +0000171- (void)ivars {
172 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}}
173 use(weakIvar); // expected-note{{also accessed here}}
174}
175
Jordan Rosed3934582012-09-28 22:21:30 +0000176- (void)doubleLevelAccessForSelf {
Jordan Rose657b5f42012-09-28 22:21:35 +0000177 use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000178 use(self.strongProp.weakProp); // expected-note{{also accessed here}}
179
Jordan Rose657b5f42012-09-28 22:21:35 +0000180 use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000181 use(self->ivar.weakProp); // expected-note{{also accessed here}}
Jordan Rose657b5f42012-09-28 22:21:35 +0000182
183 use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
184 use(self->ivar->weakIvar); // expected-note{{also accessed here}}
Jordan Rosed3934582012-09-28 22:21:30 +0000185}
186
187- (void)distinctFromOther:(Test *)other {
188 use(self.strongProp.weakProp); // no-warning
189 use(other.strongProp.weakProp); // no-warning
190
191 use(self->ivar.weakProp); // no-warning
192 use(other->ivar.weakProp); // no-warning
Jordan Rose657b5f42012-09-28 22:21:35 +0000193
194 use(self.strongProp->weakIvar); // no-warning
195 use(other.strongProp->weakIvar); // no-warning
Jordan Rosed3934582012-09-28 22:21:30 +0000196}
197@end
198
199
200class Wrapper {
201 Test *a;
202
203public:
204 void fields() {
Jordan Rose657b5f42012-09-28 22:21:35 +0000205 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 +0000206 use(a.weakProp); // expected-note{{also accessed here}}
207 }
208
209 void distinctFromOther(Test *b, const Wrapper &w) {
210 use(a.weakProp); // no-warning
211 use(b.weakProp); // no-warning
212 use(w.a.weakProp); // no-warning
213 }
214
215 static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000216 use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000217 use(y.a.weakProp); // expected-note{{also accessed here}}
218 }
219};
220
221
222// -----------------------
223// False positives
224// -----------------------
225
226// Most of these would require flow-sensitive analysis to silence correctly.
227
228void assignAfterRead(Test *a) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000229 if (!a.weakProp) // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000230 a.weakProp = get(); // expected-note{{also accessed here}}
231}
232
233void assignNil(Test *a) {
234 if (condition())
235 a.weakProp = nil; // expected-note{{also accessed here}}
236
Jordan Rose657b5f42012-09-28 22:21:35 +0000237 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000238}
239
240void branch(Test *a) {
241 if (condition())
Jordan Rose657b5f42012-09-28 22:21:35 +0000242 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000243 else
244 use(a.weakProp); // expected-note{{also accessed here}}
245}
246
247void doubleLevelAccess(Test *a, Test *b) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000248 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000249 use(b.strongProp.weakProp); // expected-note{{also accessed here}}
250
251 use(a.weakProp.weakProp); // no-warning
252}
253
254void doubleLevelAccessIvar(Test *a, Test *b) {
Jordan Rose657b5f42012-09-28 22:21:35 +0000255 use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
Jordan Rosed3934582012-09-28 22:21:30 +0000256 use(b->ivar.weakProp); // expected-note{{also accessed here}}
257
258 use(a.strongProp.weakProp); // no-warning
259}