blob: 85de91853e599632c284288d7c2c8a32fec5c61a [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 Sadowskia49d1d82011-09-09 16:07:55 +0000348 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000349}
350
351void gb_bad_1() {
352 int x = sls_guard_var; // \
Caitlin Sadowskia49d1d82011-09-09 16:07:55 +0000353 // expected-warning{{reading variable 'sls_guard_var' requires lock on 'any mutex' to be held}}
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 Sadowskia49d1d82011-09-09 16:07:55 +0000368 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires lock on 'any mutex' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000369}
370
371void gb_bad_5() {
372 int x = *pgb_gvar; // \
Caitlin Sadowskia49d1d82011-09-09 16:07:55 +0000373 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires lock on 'any mutex' to be held}}
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 Sadowskia49d1d82011-09-09 16:07:55 +0000394 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000395 sls_guard_var--; // \
Caitlin Sadowskia49d1d82011-09-09 16:07:55 +0000396 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000397 ++sls_guard_var; // \
Caitlin Sadowskia49d1d82011-09-09 16:07:55 +0000398 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
399 --sls_guard_var;// \
400 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
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 Sadowski99107eb2011-09-09 16:21:55 +0000428class LateBar {
429 public:
430 int a_ __attribute__((guarded_by(mu1_)));
431 int b_;
432 int *q __attribute__((pt_guarded_by(mu)));
433 Mutex mu1_;
434 Mutex mu;
435 LateFoo Foo;
436 LateFoo Foo2;
437 LateFoo *FooPointer;
438};
439
440LateBar b1, *b3;
441
442void late_0() {
443 LateFoo FooA;
444 LateFoo FooB;
445 FooA.mu.Lock();
446 FooA.a = 5;
447 FooA.mu.Unlock();
448}
449
450void late_1() {
451 LateBar BarA;
452 BarA.FooPointer->mu.Lock();
453 BarA.FooPointer->a = 2;
454 BarA.FooPointer->mu.Unlock();
455}
456
457void late_bad_0() {
458 LateFoo fooA;
459 LateFoo fooB;
460 fooA.mu.Lock();
461 fooB.a = 5; // \
462 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
463 fooA.mu.Unlock();
464}
465
466void late_bad_1() {
467 Mutex mu;
468 mu.Lock();
469 b1.mu1_.Lock();
470 int res = b1.a_ + b3->b_;
471 b3->b_ = *b1.q; // \
472 // expected-warning{{reading the value pointed to by 'q' requires lock on 'mu' to be held}}
473 b1.mu1_.Unlock();
474 b1.b_ = res;
475 mu.Unlock();
476}
477
478void late_bad_2() {
479 LateBar BarA;
480 BarA.FooPointer->mu.Lock();
481 BarA.Foo.a = 2; // \
482 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
483 BarA.FooPointer->mu.Unlock();
484}
485
486void late_bad_3() {
487 LateBar BarA;
488 BarA.Foo.mu.Lock();
489 BarA.FooPointer->a = 2; // \
490 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
491 BarA.Foo.mu.Unlock();
492}
493
494void late_bad_4() {
495 LateBar BarA;
496 BarA.Foo.mu.Lock();
497 BarA.Foo2.a = 2; // \
498 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
499 BarA.Foo.mu.Unlock();
500}
501
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000502//-----------------------------------------------//
503// Extra warnings for shared vs. exclusive locks
504// ----------------------------------------------//
505
506void shared_fun_0() {
507 sls_mu.Lock();
508 do {
509 sls_mu.Unlock();
510 sls_mu.Lock();
511 } while (getBool());
512 sls_mu.Unlock();
513}
514
515void shared_fun_1() {
516 sls_mu.ReaderLock();
517 do {
518 sls_mu.Unlock();
519 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000520 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000521 } while (getBool());
522 sls_mu.Unlock();
523}
524
525void shared_fun_3() {
526 if (getBool())
527 sls_mu.Lock();
528 else
529 sls_mu.Lock();
530 *pgb_var = 1;
531 sls_mu.Unlock();
532}
533
534void shared_fun_4() {
535 if (getBool())
536 sls_mu.ReaderLock();
537 else
538 sls_mu.ReaderLock();
539 int x = sls_guardby_var;
540 sls_mu.Unlock();
541}
542
543void shared_fun_8() {
544 if (getBool())
545 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000546 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000547 else
548 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000549 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000550 sls_mu.Unlock();
551}
552
553void shared_bad_0() {
554 sls_mu.Lock();
555 do {
556 sls_mu.Unlock();
557 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000558 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000559 } while (getBool());
560 sls_mu.Unlock();
561}
562
563void shared_bad_1() {
564 if (getBool())
565 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000566 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000567 else
568 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000569 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000570 *pgb_var = 1;
571 sls_mu.Unlock();
572}
573
574void shared_bad_2() {
575 if (getBool())
576 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000577 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000578 else
579 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000580 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000581 *pgb_var = 1;
582 sls_mu.Unlock();
583}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000584
585// FIXME: Add support for functions (not only methods)
586class LRBar {
587 public:
588 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
589 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
590 void le_fun() __attribute__((locks_excluded(sls_mu)));
591};
592
593class LRFoo {
594 public:
595 void test() __attribute__((exclusive_locks_required(sls_mu)));
596 void testShared() __attribute__((shared_locks_required(sls_mu2)));
597};
598
599void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
600void elr_fun() {}
601
602LRFoo MyLRFoo;
603LRBar Bar;
604
605void es_fun_0() {
606 aa_mu.Lock();
607 Bar.aa_elr_fun();
608 aa_mu.Unlock();
609}
610
611void es_fun_1() {
612 aa_mu.Lock();
613 Bar.aa_elr_fun_s();
614 aa_mu.Unlock();
615}
616
617void es_fun_2() {
618 aa_mu.ReaderLock();
619 Bar.aa_elr_fun_s();
620 aa_mu.Unlock();
621}
622
623void es_fun_3() {
624 sls_mu.Lock();
625 MyLRFoo.test();
626 sls_mu.Unlock();
627}
628
629void es_fun_4() {
630 sls_mu2.Lock();
631 MyLRFoo.testShared();
632 sls_mu2.Unlock();
633}
634
635void es_fun_5() {
636 sls_mu2.ReaderLock();
637 MyLRFoo.testShared();
638 sls_mu2.Unlock();
639}
640
641void es_fun_6() {
642 Bar.le_fun();
643}
644
645void es_fun_7() {
646 sls_mu.Lock();
647 elr_fun();
648 sls_mu.Unlock();
649}
650
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000651void es_fun_8() __attribute__((no_thread_safety_analysis));
652
653void es_fun_8() {
654 Bar.aa_elr_fun_s();
655}
656
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000657void es_bad_0() {
658 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000659 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000660}
661
662void es_bad_1() {
663 aa_mu.ReaderLock();
664 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000665 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000666 aa_mu.Unlock();
667}
668
669void es_bad_2() {
670 Bar.aa_elr_fun_s(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000671 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000672}
673
674void es_bad_3() {
675 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000676 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000677}
678
679void es_bad_4() {
680 MyLRFoo.testShared(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000681 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000682}
683
684void es_bad_5() {
685 sls_mu.ReaderLock();
686 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000687 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000688 sls_mu.Unlock();
689}
690
691void es_bad_6() {
692 sls_mu.Lock();
693 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000694 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000695 sls_mu.Unlock();
696}
697
698void es_bad_7() {
699 sls_mu.ReaderLock();
700 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000701 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000702 sls_mu.Unlock();
703}