blob: 4990627728f6b5cc734a7c91f963dc60aee74aa9 [file] [log] [blame]
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
2
3
4//-----------------------------------------//
5// Helper fields
6//-----------------------------------------//
7
8
9class __attribute__((lockable)) Mutex {
10 public:
11 void Lock() __attribute__((exclusive_lock_function));
12 void ReaderLock() __attribute__((shared_lock_function));
13 void Unlock() __attribute__((unlock_function));
14 bool TryLock() __attribute__((exclusive_trylock_function(true)));
15 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
16 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
17};
18
19
20Mutex sls_mu;
21
22Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
23int sls_guard_var __attribute__((guarded_var)) = 0;
24int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
25
26bool getBool();
27
28class MutexWrapper {
29public:
30 Mutex mu;
31 // int x __attribute__((guarded_by(mu))); // FIXME: scoping error
32};
33
34MutexWrapper sls_mw;
35
36void sls_fun_0() {
37 sls_mw.mu.Lock();
38 // sls_mw.x = 5; // FIXME: turn mu into sls_mw.mu
39 sls_mw.mu.Unlock();
40}
41
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000042void sls_fun_2() {
43 sls_mu.Lock();
44 int x = sls_guard_var;
45 sls_mu.Unlock();
46}
47
48void sls_fun_3() {
49 sls_mu.Lock();
50 sls_guard_var = 2;
51 sls_mu.Unlock();
52}
53
54void sls_fun_4() {
55 sls_mu2.Lock();
56 sls_guard_var = 2;
57 sls_mu2.Unlock();
58}
59
60void sls_fun_5() {
61 sls_mu.Lock();
62 int x = sls_guardby_var;
63 sls_mu.Unlock();
64}
65
66void sls_fun_6() {
67 sls_mu.Lock();
68 sls_guardby_var = 2;
69 sls_mu.Unlock();
70}
71
72void sls_fun_7() {
73 sls_mu.Lock();
74 sls_mu2.Lock();
75 sls_mu2.Unlock();
76 sls_mu.Unlock();
77}
78
79void sls_fun_8() {
80 sls_mu.Lock();
81 if (getBool())
82 sls_mu.Unlock();
83 else
84 sls_mu.Unlock();
85}
86
87void sls_fun_9() {
88 if (getBool())
89 sls_mu.Lock();
90 else
91 sls_mu.Lock();
92 sls_mu.Unlock();
93}
94
95void sls_fun_good_6() {
96 if (getBool()) {
97 sls_mu.Lock();
98 } else {
99 if (getBool()) {
100 getBool(); // EMPTY
101 } else {
102 getBool(); // EMPTY
103 }
104 sls_mu.Lock();
105 }
106 sls_mu.Unlock();
107}
108
109void sls_fun_good_7() {
110 sls_mu.Lock();
111 while (getBool()) {
112 sls_mu.Unlock();
113 if (getBool()) {
114 if (getBool()) {
115 sls_mu.Lock();
116 continue;
117 }
118 }
119 sls_mu.Lock();
120 }
121 sls_mu.Unlock();
122}
123
124void sls_fun_bad_1() {
125 sls_mu.Unlock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000126 // expected-warning{{unlocking 'sls_mu' that was not acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000127}
128
129void sls_fun_bad_2() {
130 sls_mu.Lock();
131 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000132 // expected-warning{{locking 'sls_mu' that is already acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000133 sls_mu.Unlock();
134}
135
136void sls_fun_bad_3() {
137 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000138 // expected-warning{{lock 'sls_mu' is not released at the end of function 'sls_fun_bad_3'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000139}
140
141void sls_fun_bad_4() {
142 if (getBool())
143 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000144 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000145 else
146 sls_mu2.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000147 // expected-warning{{lock 'sls_mu2' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000148}
149
150void sls_fun_bad_5() {
151 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000152 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000153 if (getBool())
154 sls_mu.Unlock();
155}
156
157void sls_fun_bad_6() {
158 if (getBool()) {
159 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000160 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000161 } else {
162 if (getBool()) {
163 getBool(); // EMPTY
164 } else {
165 getBool(); // EMPTY
166 }
167 }
168 sls_mu.Unlock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000169 // expected-warning{{unlocking 'sls_mu' that was not acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000170}
171
172void sls_fun_bad_7() {
173 sls_mu.Lock();
174 while (getBool()) { // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000175 // expected-warning{{expecting lock 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000176 sls_mu.Unlock();
177 if (getBool()) {
178 if (getBool()) {
179 continue;
180 }
181 }
182 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000183 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000184 }
185 sls_mu.Unlock();
186}
187
188void sls_fun_bad_8() {
189 sls_mu.Lock();
190 do {
191 sls_mu.Unlock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000192 // expected-warning{{expecting lock 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000193 } while (getBool());
194}
195
196void sls_fun_bad_9() {
197 do {
198 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000199 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000200 } while (getBool());
201 sls_mu.Unlock();
202}
203
204void sls_fun_bad_10() {
205 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000206 // expected-warning{{lock 'sls_mu' is not released at the end of function 'sls_fun_bad_10'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000207 while(getBool()) { // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000208 // expected-warning{{expecting lock 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000209 sls_mu.Unlock();
210 }
211}
212
213void sls_fun_bad_11() {
214 while (getBool()) {
215 sls_mu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000216 // expected-warning{{lock 'sls_mu' is not released at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000217 }
218 sls_mu.Unlock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000219 // expected-warning{{unlocking 'sls_mu' that was not acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000220}
221
222
223//-----------------------------------------//
224// Handling lock expressions in attribute args
225// -------------------------------------------//
226
227Mutex aa_mu;
228
229class GlobalLocker {
230public:
231 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
232 void globalUnlock() __attribute__((unlock_function(aa_mu)));
233};
234
235GlobalLocker glock;
236
237void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
238void aa_elr_fun() { }
239
240void aa_fun_1() {
241 glock.globalLock();
242 glock.globalUnlock();
243}
244
245void aa_fun_2() {
246 aa_mu.Lock();
247 aa_elr_fun();
248 aa_mu.Unlock();
249}
250
251void aa_fun_bad_1() {
252 glock.globalUnlock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000253 // expected-warning{{unlocking 'aa_mu' that was not acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000254}
255
256void aa_fun_bad_2() {
257 glock.globalLock();
258 glock.globalLock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000259 // expected-warning{{locking 'aa_mu' that is already acquired}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000260 glock.globalUnlock();
261}
262
263void aa_fun_bad_3() {
264 glock.globalLock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000265 // expected-warning{{lock 'aa_mu' is not released at the end of function 'aa_fun_bad_3'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000266}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000267
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000268//--------------------------------------------------//
269// Regression tests for unusual method names
270//--------------------------------------------------//
271
272Mutex wmu;
273
274// Test diagnostics for other method names.
275class WeirdMethods {
276 WeirdMethods() {
277 wmu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000278 // expected-warning {{lock 'wmu' is not released at the end of function 'WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000279 }
280 ~WeirdMethods() {
281 wmu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000282 // expected-warning {{lock 'wmu' is not released at the end of function '~WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000283 }
284 void operator++() {
285 wmu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000286 // expected-warning {{lock 'wmu' is not released at the end of function 'operator++'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000287 }
288 operator int*() {
289 wmu.Lock(); // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000290 // expected-warning {{lock 'wmu' is not released at the end of function 'operator int *'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000291 return 0;
292 }
293};
294
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000295//-----------------------------------------------//
296// Errors for guarded by or guarded var variables
297// ----------------------------------------------//
298
299int *pgb_gvar __attribute__((pt_guarded_var));
300int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
301
302class PGBFoo {
303 public:
304 int x;
305 int *pgb_field __attribute__((guarded_by(sls_mu2)))
306 __attribute__((pt_guarded_by(sls_mu)));
307 void testFoo() {
308 pgb_field = &x; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000309 // expected-warning{{accessing variable 'pgb_field' requires lock 'sls_mu2'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000310 *pgb_field = x; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000311 // expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000312 x = *pgb_field; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000313 // expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000314 (*pgb_field)++; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000315 // expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000316 }
317};
318
319class GBFoo {
320 public:
321 int gb_field __attribute__((guarded_by(sls_mu)));
322
323 void testFoo() {
324 gb_field = 0; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000325 // expected-warning{{accessing variable 'gb_field' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000326 }
327};
328
329GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
330
331void gb_fun_0() {
332 sls_mu.Lock();
333 int x = *pgb_var;
334 sls_mu.Unlock();
335}
336
337void gb_fun_1() {
338 sls_mu.Lock();
339 *pgb_var = 2;
340 sls_mu.Unlock();
341}
342
343void gb_fun_2() {
344 int x;
345 pgb_var = &x;
346}
347
348void gb_fun_3() {
349 int *x = pgb_var;
350}
351
352void gb_bad_0() {
353 sls_guard_var = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000354 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000355}
356
357void gb_bad_1() {
358 int x = sls_guard_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000359 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000360}
361
362void gb_bad_2() {
363 sls_guardby_var = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000364 // expected-warning{{accessing variable 'sls_guardby_var' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000365}
366
367void gb_bad_3() {
368 int x = sls_guardby_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000369 // expected-warning{{accessing variable 'sls_guardby_var' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000370}
371
372void gb_bad_4() {
373 *pgb_gvar = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000374 // expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000375}
376
377void gb_bad_5() {
378 int x = *pgb_gvar; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000379 // expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000380}
381
382void gb_bad_6() {
383 *pgb_var = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000384 // expected-warning {{accessing the value pointed to by 'pgb_var' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000385}
386
387void gb_bad_7() {
388 int x = *pgb_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000389 // expected-warning {{accessing the value pointed to by 'pgb_var' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000390}
391
392void gb_bad_8() {
393 GBFoo G;
394 G.gb_field = 0; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000395 // expected-warning{{accessing variable 'gb_field' requires lock 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000396}
397
398void gb_bad_9() {
399 sls_guard_var++; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000400 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000401 sls_guard_var--; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000402 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000403 ++sls_guard_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000404 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000405 --sls_guard_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000406 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000407}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000408
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000409//-----------------------------------------------//
410// Warnings on variables with late parsed attributes
411// ----------------------------------------------//
412
413class LateFoo {
414public:
415 int a __attribute__((guarded_by(mu)));
416 int b;
417
418 void foo() __attribute__((exclusive_locks_required(mu))) { }
419
420 void test() {
421 a = 0; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000422 // expected-warning{{accessing variable 'a' requires lock 'mu'}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000423 b = a; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000424 // expected-warning {{accessing variable 'a' requires lock 'mu'}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000425 c = 0; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000426 // expected-warning {{accessing variable 'c' requires lock 'mu'}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000427 }
428
429 int c __attribute__((guarded_by(mu)));
430
431 Mutex mu;
432};
433