blob: cb74504a2c90f5f768176b8e1e256965893a5419 [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 Sadowski8bccabe2011-09-08 21:52:50 +0000126 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000127}
128
129void sls_fun_bad_2() {
130 sls_mu.Lock();
131 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000132 // expected-warning{{locking 'sls_mu' that is already locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000133 sls_mu.Unlock();
134}
135
136void sls_fun_bad_3() {
137 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000138 // expected-warning{{mutex 'sls_mu' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000144 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000145 else
146 sls_mu2.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000147 // expected-warning{{mutex 'sls_mu2' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000152 // expected-warning{{mutex 'sls_mu' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000160 // expected-warning{{mutex 'sls_mu' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000169 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000170}
171
172void sls_fun_bad_7() {
173 sls_mu.Lock();
174 while (getBool()) { // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000175 // expected-warning{{expecting lock on '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 Sadowski8bccabe2011-09-08 21:52:50 +0000183 // expected-warning{{mutex 'sls_mu' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000192 // expected-warning{{expecting lock on '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 Sadowski8bccabe2011-09-08 21:52:50 +0000199 // expected-warning{{mutex 'sls_mu' is still held 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 Sadowski8bccabe2011-09-08 21:52:50 +0000206 // expected-warning{{mutex 'sls_mu' is still held at the end of function 'sls_fun_bad_10'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000207 while(getBool()) { // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000208 // expected-warning{{expecting lock on '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 Sadowski8bccabe2011-09-08 21:52:50 +0000216 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000217 }
218 sls_mu.Unlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000219 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000220}
221
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000222//-----------------------------------------//
223// Handling lock expressions in attribute args
224// -------------------------------------------//
225
226Mutex aa_mu;
227
228class GlobalLocker {
229public:
230 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
231 void globalUnlock() __attribute__((unlock_function(aa_mu)));
232};
233
234GlobalLocker glock;
235
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000236void aa_fun_1() {
237 glock.globalLock();
238 glock.globalUnlock();
239}
240
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000241void aa_fun_bad_1() {
242 glock.globalUnlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000243 // expected-warning{{unlocking 'aa_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000244}
245
246void aa_fun_bad_2() {
247 glock.globalLock();
248 glock.globalLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000249 // expected-warning{{locking 'aa_mu' that is already locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000250 glock.globalUnlock();
251}
252
253void aa_fun_bad_3() {
254 glock.globalLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000255 // expected-warning{{mutex 'aa_mu' is still held at the end of function 'aa_fun_bad_3'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000256}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000257
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000258//--------------------------------------------------//
259// Regression tests for unusual method names
260//--------------------------------------------------//
261
262Mutex wmu;
263
264// Test diagnostics for other method names.
265class WeirdMethods {
266 WeirdMethods() {
267 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000268 // expected-warning {{mutex 'wmu' is still held at the end of function 'WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000269 }
270 ~WeirdMethods() {
271 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000272 // expected-warning {{mutex 'wmu' is still held at the end of function '~WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000273 }
274 void operator++() {
275 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000276 // expected-warning {{mutex 'wmu' is still held at the end of function 'operator++'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000277 }
278 operator int*() {
279 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000280 // expected-warning {{mutex 'wmu' is still held at the end of function 'operator int *'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000281 return 0;
282 }
283};
284
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000285//-----------------------------------------------//
286// Errors for guarded by or guarded var variables
287// ----------------------------------------------//
288
289int *pgb_gvar __attribute__((pt_guarded_var));
290int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
291
292class PGBFoo {
293 public:
294 int x;
295 int *pgb_field __attribute__((guarded_by(sls_mu2)))
296 __attribute__((pt_guarded_by(sls_mu)));
297 void testFoo() {
298 pgb_field = &x; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000299 // expected-warning {{writing variable 'pgb_field' requires lock on 'sls_mu2' to be held exclusively}}
300 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
301 // expected-warning {{writing the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held exclusively}}
302 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
303 // expected-warning {{reading the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held}}
304 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
305 // expected-warning {{writing the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000306 }
307};
308
309class GBFoo {
310 public:
311 int gb_field __attribute__((guarded_by(sls_mu)));
312
313 void testFoo() {
314 gb_field = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000315 // expected-warning {{writing variable 'gb_field' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000316 }
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000317
318 void testNoAnal() __attribute__((no_thread_safety_analysis)) {
319 gb_field = 0;
320 }
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000321};
322
323GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
324
325void gb_fun_0() {
326 sls_mu.Lock();
327 int x = *pgb_var;
328 sls_mu.Unlock();
329}
330
331void gb_fun_1() {
332 sls_mu.Lock();
333 *pgb_var = 2;
334 sls_mu.Unlock();
335}
336
337void gb_fun_2() {
338 int x;
339 pgb_var = &x;
340}
341
342void gb_fun_3() {
343 int *x = pgb_var;
344}
345
346void gb_bad_0() {
347 sls_guard_var = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000348 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000349}
350
351void gb_bad_1() {
352 int x = sls_guard_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000353 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000354}
355
356void gb_bad_2() {
357 sls_guardby_var = 1; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000358 // expected-warning {{writing variable 'sls_guardby_var' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000359}
360
361void gb_bad_3() {
362 int x = sls_guardby_var; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000363 // expected-warning {{reading variable 'sls_guardby_var' requires lock on 'sls_mu' to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000364}
365
366void gb_bad_4() {
367 *pgb_gvar = 1; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000368 // expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000369}
370
371void gb_bad_5() {
372 int x = *pgb_gvar; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000373 // expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000374}
375
376void gb_bad_6() {
377 *pgb_var = 1; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000378 // expected-warning {{writing the value pointed to by 'pgb_var' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000379}
380
381void gb_bad_7() {
382 int x = *pgb_var; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000383 // expected-warning {{reading the value pointed to by 'pgb_var' requires lock on 'sls_mu' to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000384}
385
386void gb_bad_8() {
387 GBFoo G;
388 G.gb_field = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000389 // expected-warning {{writing variable 'gb_field' requires lock on 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000390}
391
392void gb_bad_9() {
393 sls_guard_var++; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000394 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000395 sls_guard_var--; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000396 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000397 ++sls_guard_var; // \
Caitlin Sadowski3bb43582011-09-08 18:07:26 +0000398 // expected-warning{{accessing variable 'sls_guard_var' requires some lock}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000399 --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}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000402
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000403//-----------------------------------------------//
404// Warnings on variables with late parsed attributes
405// ----------------------------------------------//
406
407class LateFoo {
408public:
409 int a __attribute__((guarded_by(mu)));
410 int b;
411
412 void foo() __attribute__((exclusive_locks_required(mu))) { }
413
414 void test() {
415 a = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000416 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000417 b = a; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000418 // expected-warning {{reading variable 'a' requires lock on 'mu' to be held}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000419 c = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000420 // expected-warning {{writing variable 'c' requires lock on 'mu' to be held exclusively}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000421 }
422
423 int c __attribute__((guarded_by(mu)));
424
425 Mutex mu;
426};
427
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000428//-----------------------------------------------//
429// Extra warnings for shared vs. exclusive locks
430// ----------------------------------------------//
431
432void shared_fun_0() {
433 sls_mu.Lock();
434 do {
435 sls_mu.Unlock();
436 sls_mu.Lock();
437 } while (getBool());
438 sls_mu.Unlock();
439}
440
441void shared_fun_1() {
442 sls_mu.ReaderLock();
443 do {
444 sls_mu.Unlock();
445 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000446 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000447 } while (getBool());
448 sls_mu.Unlock();
449}
450
451void shared_fun_3() {
452 if (getBool())
453 sls_mu.Lock();
454 else
455 sls_mu.Lock();
456 *pgb_var = 1;
457 sls_mu.Unlock();
458}
459
460void shared_fun_4() {
461 if (getBool())
462 sls_mu.ReaderLock();
463 else
464 sls_mu.ReaderLock();
465 int x = sls_guardby_var;
466 sls_mu.Unlock();
467}
468
469void shared_fun_8() {
470 if (getBool())
471 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000472 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000473 else
474 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000475 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000476 sls_mu.Unlock();
477}
478
479void shared_bad_0() {
480 sls_mu.Lock();
481 do {
482 sls_mu.Unlock();
483 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000484 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000485 } while (getBool());
486 sls_mu.Unlock();
487}
488
489void shared_bad_1() {
490 if (getBool())
491 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000492 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000493 else
494 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000495 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000496 *pgb_var = 1;
497 sls_mu.Unlock();
498}
499
500void shared_bad_2() {
501 if (getBool())
502 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000503 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000504 else
505 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000506 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000507 *pgb_var = 1;
508 sls_mu.Unlock();
509}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000510
511// FIXME: Add support for functions (not only methods)
512class LRBar {
513 public:
514 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
515 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
516 void le_fun() __attribute__((locks_excluded(sls_mu)));
517};
518
519class LRFoo {
520 public:
521 void test() __attribute__((exclusive_locks_required(sls_mu)));
522 void testShared() __attribute__((shared_locks_required(sls_mu2)));
523};
524
525void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
526void elr_fun() {}
527
528LRFoo MyLRFoo;
529LRBar Bar;
530
531void es_fun_0() {
532 aa_mu.Lock();
533 Bar.aa_elr_fun();
534 aa_mu.Unlock();
535}
536
537void es_fun_1() {
538 aa_mu.Lock();
539 Bar.aa_elr_fun_s();
540 aa_mu.Unlock();
541}
542
543void es_fun_2() {
544 aa_mu.ReaderLock();
545 Bar.aa_elr_fun_s();
546 aa_mu.Unlock();
547}
548
549void es_fun_3() {
550 sls_mu.Lock();
551 MyLRFoo.test();
552 sls_mu.Unlock();
553}
554
555void es_fun_4() {
556 sls_mu2.Lock();
557 MyLRFoo.testShared();
558 sls_mu2.Unlock();
559}
560
561void es_fun_5() {
562 sls_mu2.ReaderLock();
563 MyLRFoo.testShared();
564 sls_mu2.Unlock();
565}
566
567void es_fun_6() {
568 Bar.le_fun();
569}
570
571void es_fun_7() {
572 sls_mu.Lock();
573 elr_fun();
574 sls_mu.Unlock();
575}
576
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000577void es_fun_8() __attribute__((no_thread_safety_analysis));
578
579void es_fun_8() {
580 Bar.aa_elr_fun_s();
581}
582
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000583void es_bad_0() {
584 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000585 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000586}
587
588void es_bad_1() {
589 aa_mu.ReaderLock();
590 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000591 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000592 aa_mu.Unlock();
593}
594
595void es_bad_2() {
596 Bar.aa_elr_fun_s(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000597 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000598}
599
600void es_bad_3() {
601 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000602 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000603}
604
605void es_bad_4() {
606 MyLRFoo.testShared(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000607 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000608}
609
610void es_bad_5() {
611 sls_mu.ReaderLock();
612 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000613 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000614 sls_mu.Unlock();
615}
616
617void es_bad_6() {
618 sls_mu.Lock();
619 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000620 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000621 sls_mu.Unlock();
622}
623
624void es_bad_7() {
625 sls_mu.ReaderLock();
626 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000627 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000628 sls_mu.Unlock();
629}