1 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s
2
3 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
4 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
5
6 #define LOCKABLE __attribute__ ((lockable))
7 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
8 #define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
9 #define GUARDED_VAR __attribute__ ((guarded_var))
10 #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
11 #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
12 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
13 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
14 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
15 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
16 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
17 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
18 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
19 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
20 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
21 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
22 __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
23 #define SHARED_LOCKS_REQUIRED(...) \
24 __attribute__ ((shared_locks_required(__VA_ARGS__)))
25 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
26
27
28 class __attribute__((lockable)) Mutex {
29 public:
30 void Lock() __attribute__((exclusive_lock_function));
31 void ReaderLock() __attribute__((shared_lock_function));
32 void Unlock() __attribute__((unlock_function));
33 bool TryLock() __attribute__((exclusive_trylock_function(true)));
34 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
35 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
36 };
37
38 class __attribute__((scoped_lockable)) MutexLock {
39 public:
40 MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
41 ~MutexLock() __attribute__((unlock_function));
42 };
43
44 class __attribute__((scoped_lockable)) ReaderMutexLock {
45 public:
46 ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
47 ~ReaderMutexLock() __attribute__((unlock_function));
48 };
49
50 class SCOPED_LOCKABLE ReleasableMutexLock {
51 public:
52 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
53 ~ReleasableMutexLock() UNLOCK_FUNCTION();
54
55 void Release() UNLOCK_FUNCTION();
56 };
57
58
59 // The universal lock, written "*", allows checking to be selectively turned
60 // off for a particular piece of code.
61 void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
62 void endNoWarnOnReads() UNLOCK_FUNCTION("*");
63 void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
64 void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
65
66
67 template<class T>
68 class SmartPtr {
69 public:
SmartPtr(T * p)70 SmartPtr(T* p) : ptr_(p) { }
SmartPtr(const SmartPtr<T> & p)71 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
72 ~SmartPtr();
73
get() const74 T* get() const { return ptr_; }
operator ->() const75 T* operator->() const { return ptr_; }
operator *() const76 T& operator*() const { return *ptr_; }
77
78 private:
79 T* ptr_;
80 };
81
82
83 Mutex sls_mu;
84
85 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
86 int sls_guard_var __attribute__((guarded_var)) = 0;
87 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
88
89 bool getBool();
90
91 class MutexWrapper {
92 public:
93 Mutex mu;
94 int x __attribute__((guarded_by(mu)));
95 void MyLock() __attribute__((exclusive_lock_function(mu)));
96 };
97
98 MutexWrapper sls_mw;
99
sls_fun_0()100 void sls_fun_0() {
101 sls_mw.mu.Lock();
102 sls_mw.x = 5;
103 sls_mw.mu.Unlock();
104 }
105
sls_fun_2()106 void sls_fun_2() {
107 sls_mu.Lock();
108 int x = sls_guard_var;
109 sls_mu.Unlock();
110 }
111
sls_fun_3()112 void sls_fun_3() {
113 sls_mu.Lock();
114 sls_guard_var = 2;
115 sls_mu.Unlock();
116 }
117
sls_fun_4()118 void sls_fun_4() {
119 sls_mu2.Lock();
120 sls_guard_var = 2;
121 sls_mu2.Unlock();
122 }
123
sls_fun_5()124 void sls_fun_5() {
125 sls_mu.Lock();
126 int x = sls_guardby_var;
127 sls_mu.Unlock();
128 }
129
sls_fun_6()130 void sls_fun_6() {
131 sls_mu.Lock();
132 sls_guardby_var = 2;
133 sls_mu.Unlock();
134 }
135
sls_fun_7()136 void sls_fun_7() {
137 sls_mu.Lock();
138 sls_mu2.Lock();
139 sls_mu2.Unlock();
140 sls_mu.Unlock();
141 }
142
sls_fun_8()143 void sls_fun_8() {
144 sls_mu.Lock();
145 if (getBool())
146 sls_mu.Unlock();
147 else
148 sls_mu.Unlock();
149 }
150
sls_fun_9()151 void sls_fun_9() {
152 if (getBool())
153 sls_mu.Lock();
154 else
155 sls_mu.Lock();
156 sls_mu.Unlock();
157 }
158
sls_fun_good_6()159 void sls_fun_good_6() {
160 if (getBool()) {
161 sls_mu.Lock();
162 } else {
163 if (getBool()) {
164 getBool(); // EMPTY
165 } else {
166 getBool(); // EMPTY
167 }
168 sls_mu.Lock();
169 }
170 sls_mu.Unlock();
171 }
172
sls_fun_good_7()173 void sls_fun_good_7() {
174 sls_mu.Lock();
175 while (getBool()) {
176 sls_mu.Unlock();
177 if (getBool()) {
178 if (getBool()) {
179 sls_mu.Lock();
180 continue;
181 }
182 }
183 sls_mu.Lock();
184 }
185 sls_mu.Unlock();
186 }
187
sls_fun_good_8()188 void sls_fun_good_8() {
189 sls_mw.MyLock();
190 sls_mw.mu.Unlock();
191 }
192
sls_fun_bad_1()193 void sls_fun_bad_1() {
194 sls_mu.Unlock(); // \
195 // expected-warning{{unlocking 'sls_mu' that was not locked}}
196 }
197
sls_fun_bad_2()198 void sls_fun_bad_2() {
199 sls_mu.Lock();
200 sls_mu.Lock(); // \
201 // expected-warning{{locking 'sls_mu' that is already locked}}
202 sls_mu.Unlock();
203 }
204
sls_fun_bad_3()205 void sls_fun_bad_3() {
206 sls_mu.Lock(); // expected-note {{mutex acquired here}}
207 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
208
sls_fun_bad_4()209 void sls_fun_bad_4() {
210 if (getBool())
211 sls_mu.Lock(); // expected-note{{mutex acquired here}}
212 else
213 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
214 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \
215 // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
216
sls_fun_bad_5()217 void sls_fun_bad_5() {
218 sls_mu.Lock(); // expected-note {{mutex acquired here}}
219 if (getBool())
220 sls_mu.Unlock();
221 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
222
sls_fun_bad_6()223 void sls_fun_bad_6() {
224 if (getBool()) {
225 sls_mu.Lock(); // expected-note {{mutex acquired here}}
226 } else {
227 if (getBool()) {
228 getBool(); // EMPTY
229 } else {
230 getBool(); // EMPTY
231 }
232 }
233 sls_mu.Unlock(); // \
234 expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
235 expected-warning{{unlocking 'sls_mu' that was not locked}}
236 }
237
sls_fun_bad_7()238 void sls_fun_bad_7() {
239 sls_mu.Lock();
240 while (getBool()) {
241 sls_mu.Unlock();
242 if (getBool()) {
243 if (getBool()) {
244 continue; // \
245 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
246 }
247 }
248 sls_mu.Lock(); // expected-note {{mutex acquired here}}
249 }
250 sls_mu.Unlock();
251 }
252
sls_fun_bad_8()253 void sls_fun_bad_8() {
254 sls_mu.Lock(); // expected-note{{mutex acquired here}}
255
256 do {
257 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
258 } while (getBool());
259 }
260
sls_fun_bad_9()261 void sls_fun_bad_9() {
262 do {
263 sls_mu.Lock(); // \
264 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
265 // expected-note{{mutex acquired here}}
266 } while (getBool());
267 sls_mu.Unlock();
268 }
269
sls_fun_bad_10()270 void sls_fun_bad_10() {
271 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
272 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
273 sls_mu.Unlock();
274 }
275 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
276
sls_fun_bad_11()277 void sls_fun_bad_11() {
278 while (getBool()) { // \
279 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
280 sls_mu.Lock(); // expected-note {{mutex acquired here}}
281 }
282 sls_mu.Unlock(); // \
283 // expected-warning{{unlocking 'sls_mu' that was not locked}}
284 }
285
sls_fun_bad_12()286 void sls_fun_bad_12() {
287 sls_mu.Lock(); // expected-note {{mutex acquired here}}
288 while (getBool()) {
289 sls_mu.Unlock();
290 if (getBool()) {
291 if (getBool()) {
292 break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
293 }
294 }
295 sls_mu.Lock();
296 }
297 sls_mu.Unlock();
298 }
299
300 //-----------------------------------------//
301 // Handling lock expressions in attribute args
302 // -------------------------------------------//
303
304 Mutex aa_mu;
305
306 class GlobalLocker {
307 public:
308 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
309 void globalUnlock() __attribute__((unlock_function(aa_mu)));
310 };
311
312 GlobalLocker glock;
313
aa_fun_1()314 void aa_fun_1() {
315 glock.globalLock();
316 glock.globalUnlock();
317 }
318
aa_fun_bad_1()319 void aa_fun_bad_1() {
320 glock.globalUnlock(); // \
321 // expected-warning{{unlocking 'aa_mu' that was not locked}}
322 }
323
aa_fun_bad_2()324 void aa_fun_bad_2() {
325 glock.globalLock();
326 glock.globalLock(); // \
327 // expected-warning{{locking 'aa_mu' that is already locked}}
328 glock.globalUnlock();
329 }
330
aa_fun_bad_3()331 void aa_fun_bad_3() {
332 glock.globalLock(); // expected-note{{mutex acquired here}}
333 } // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
334
335 //--------------------------------------------------//
336 // Regression tests for unusual method names
337 //--------------------------------------------------//
338
339 Mutex wmu;
340
341 // Test diagnostics for other method names.
342 class WeirdMethods {
343 // FIXME: can't currently check inside constructors and destructors.
WeirdMethods()344 WeirdMethods() {
345 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
346 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
~WeirdMethods()347 ~WeirdMethods() {
348 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
349 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
operator ++()350 void operator++() {
351 wmu.Lock(); // expected-note {{mutex acquired here}}
352 } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
operator int*()353 operator int*() {
354 wmu.Lock(); // expected-note {{mutex acquired here}}
355 return 0;
356 } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
357 };
358
359 //-----------------------------------------------//
360 // Errors for guarded by or guarded var variables
361 // ----------------------------------------------//
362
363 int *pgb_gvar __attribute__((pt_guarded_var));
364 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
365
366 class PGBFoo {
367 public:
368 int x;
369 int *pgb_field __attribute__((guarded_by(sls_mu2)))
370 __attribute__((pt_guarded_by(sls_mu)));
testFoo()371 void testFoo() {
372 pgb_field = &x; // \
373 // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
374 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
375 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
376 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
377 // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
378 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
379 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
380 }
381 };
382
383 class GBFoo {
384 public:
385 int gb_field __attribute__((guarded_by(sls_mu)));
386
testFoo()387 void testFoo() {
388 gb_field = 0; // \
389 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
390 }
391
testNoAnal()392 void testNoAnal() __attribute__((no_thread_safety_analysis)) {
393 gb_field = 0;
394 }
395 };
396
397 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
398
gb_fun_0()399 void gb_fun_0() {
400 sls_mu.Lock();
401 int x = *pgb_var;
402 sls_mu.Unlock();
403 }
404
gb_fun_1()405 void gb_fun_1() {
406 sls_mu.Lock();
407 *pgb_var = 2;
408 sls_mu.Unlock();
409 }
410
gb_fun_2()411 void gb_fun_2() {
412 int x;
413 pgb_var = &x;
414 }
415
gb_fun_3()416 void gb_fun_3() {
417 int *x = pgb_var;
418 }
419
gb_bad_0()420 void gb_bad_0() {
421 sls_guard_var = 1; // \
422 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
423 }
424
gb_bad_1()425 void gb_bad_1() {
426 int x = sls_guard_var; // \
427 // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
428 }
429
gb_bad_2()430 void gb_bad_2() {
431 sls_guardby_var = 1; // \
432 // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
433 }
434
gb_bad_3()435 void gb_bad_3() {
436 int x = sls_guardby_var; // \
437 // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
438 }
439
gb_bad_4()440 void gb_bad_4() {
441 *pgb_gvar = 1; // \
442 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
443 }
444
gb_bad_5()445 void gb_bad_5() {
446 int x = *pgb_gvar; // \
447 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
448 }
449
gb_bad_6()450 void gb_bad_6() {
451 *pgb_var = 1; // \
452 // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
453 }
454
gb_bad_7()455 void gb_bad_7() {
456 int x = *pgb_var; // \
457 // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
458 }
459
gb_bad_8()460 void gb_bad_8() {
461 GBFoo G;
462 G.gb_field = 0; // \
463 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
464 }
465
gb_bad_9()466 void gb_bad_9() {
467 sls_guard_var++; // \
468 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
469 sls_guard_var--; // \
470 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
471 ++sls_guard_var; // \
472 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
473 --sls_guard_var;// \
474 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
475 }
476
477 //-----------------------------------------------//
478 // Warnings on variables with late parsed attributes
479 // ----------------------------------------------//
480
481 class LateFoo {
482 public:
483 int a __attribute__((guarded_by(mu)));
484 int b;
485
foo()486 void foo() __attribute__((exclusive_locks_required(mu))) { }
487
test()488 void test() {
489 a = 0; // \
490 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
491 b = a; // \
492 // expected-warning {{reading variable 'a' requires locking 'mu'}}
493 c = 0; // \
494 // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
495 }
496
497 int c __attribute__((guarded_by(mu)));
498
499 Mutex mu;
500 };
501
502 class LateBar {
503 public:
504 int a_ __attribute__((guarded_by(mu1_)));
505 int b_;
506 int *q __attribute__((pt_guarded_by(mu)));
507 Mutex mu1_;
508 Mutex mu;
509 LateFoo Foo;
510 LateFoo Foo2;
511 LateFoo *FooPointer;
512 };
513
514 LateBar b1, *b3;
515
late_0()516 void late_0() {
517 LateFoo FooA;
518 LateFoo FooB;
519 FooA.mu.Lock();
520 FooA.a = 5;
521 FooA.mu.Unlock();
522 }
523
late_1()524 void late_1() {
525 LateBar BarA;
526 BarA.FooPointer->mu.Lock();
527 BarA.FooPointer->a = 2;
528 BarA.FooPointer->mu.Unlock();
529 }
530
late_bad_0()531 void late_bad_0() {
532 LateFoo fooA;
533 LateFoo fooB;
534 fooA.mu.Lock();
535 fooB.a = 5; // \
536 // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
537 // expected-note{{found near match 'fooA.mu'}}
538 fooA.mu.Unlock();
539 }
540
late_bad_1()541 void late_bad_1() {
542 Mutex mu;
543 mu.Lock();
544 b1.mu1_.Lock();
545 int res = b1.a_ + b3->b_;
546 b3->b_ = *b1.q; // \
547 // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
548 b1.mu1_.Unlock();
549 b1.b_ = res;
550 mu.Unlock();
551 }
552
late_bad_2()553 void late_bad_2() {
554 LateBar BarA;
555 BarA.FooPointer->mu.Lock();
556 BarA.Foo.a = 2; // \
557 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
558 // expected-note{{found near match 'BarA.FooPointer->mu'}}
559 BarA.FooPointer->mu.Unlock();
560 }
561
late_bad_3()562 void late_bad_3() {
563 LateBar BarA;
564 BarA.Foo.mu.Lock();
565 BarA.FooPointer->a = 2; // \
566 // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
567 // expected-note{{found near match 'BarA.Foo.mu'}}
568 BarA.Foo.mu.Unlock();
569 }
570
late_bad_4()571 void late_bad_4() {
572 LateBar BarA;
573 BarA.Foo.mu.Lock();
574 BarA.Foo2.a = 2; // \
575 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
576 // expected-note{{found near match 'BarA.Foo.mu'}}
577 BarA.Foo.mu.Unlock();
578 }
579
580 //-----------------------------------------------//
581 // Extra warnings for shared vs. exclusive locks
582 // ----------------------------------------------//
583
shared_fun_0()584 void shared_fun_0() {
585 sls_mu.Lock();
586 do {
587 sls_mu.Unlock();
588 sls_mu.Lock();
589 } while (getBool());
590 sls_mu.Unlock();
591 }
592
shared_fun_1()593 void shared_fun_1() {
594 sls_mu.ReaderLock(); // \
595 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
596 do {
597 sls_mu.Unlock();
598 sls_mu.Lock(); // \
599 // expected-note {{the other lock of mutex 'sls_mu' is here}}
600 } while (getBool());
601 sls_mu.Unlock();
602 }
603
shared_fun_3()604 void shared_fun_3() {
605 if (getBool())
606 sls_mu.Lock();
607 else
608 sls_mu.Lock();
609 *pgb_var = 1;
610 sls_mu.Unlock();
611 }
612
shared_fun_4()613 void shared_fun_4() {
614 if (getBool())
615 sls_mu.ReaderLock();
616 else
617 sls_mu.ReaderLock();
618 int x = sls_guardby_var;
619 sls_mu.Unlock();
620 }
621
shared_fun_8()622 void shared_fun_8() {
623 if (getBool())
624 sls_mu.Lock(); // \
625 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
626 else
627 sls_mu.ReaderLock(); // \
628 // expected-note {{the other lock of mutex 'sls_mu' is here}}
629 sls_mu.Unlock();
630 }
631
shared_bad_0()632 void shared_bad_0() {
633 sls_mu.Lock(); // \
634 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
635 do {
636 sls_mu.Unlock();
637 sls_mu.ReaderLock(); // \
638 // expected-note {{the other lock of mutex 'sls_mu' is here}}
639 } while (getBool());
640 sls_mu.Unlock();
641 }
642
shared_bad_1()643 void shared_bad_1() {
644 if (getBool())
645 sls_mu.Lock(); // \
646 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
647 else
648 sls_mu.ReaderLock(); // \
649 // expected-note {{the other lock of mutex 'sls_mu' is here}}
650 *pgb_var = 1;
651 sls_mu.Unlock();
652 }
653
shared_bad_2()654 void shared_bad_2() {
655 if (getBool())
656 sls_mu.ReaderLock(); // \
657 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
658 else
659 sls_mu.Lock(); // \
660 // expected-note {{the other lock of mutex 'sls_mu' is here}}
661 *pgb_var = 1;
662 sls_mu.Unlock();
663 }
664
665 // FIXME: Add support for functions (not only methods)
666 class LRBar {
667 public:
668 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
669 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
670 void le_fun() __attribute__((locks_excluded(sls_mu)));
671 };
672
673 class LRFoo {
674 public:
675 void test() __attribute__((exclusive_locks_required(sls_mu)));
676 void testShared() __attribute__((shared_locks_required(sls_mu2)));
677 };
678
679 void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
elr_fun()680 void elr_fun() {}
681
682 LRFoo MyLRFoo;
683 LRBar Bar;
684
es_fun_0()685 void es_fun_0() {
686 aa_mu.Lock();
687 Bar.aa_elr_fun();
688 aa_mu.Unlock();
689 }
690
es_fun_1()691 void es_fun_1() {
692 aa_mu.Lock();
693 Bar.aa_elr_fun_s();
694 aa_mu.Unlock();
695 }
696
es_fun_2()697 void es_fun_2() {
698 aa_mu.ReaderLock();
699 Bar.aa_elr_fun_s();
700 aa_mu.Unlock();
701 }
702
es_fun_3()703 void es_fun_3() {
704 sls_mu.Lock();
705 MyLRFoo.test();
706 sls_mu.Unlock();
707 }
708
es_fun_4()709 void es_fun_4() {
710 sls_mu2.Lock();
711 MyLRFoo.testShared();
712 sls_mu2.Unlock();
713 }
714
es_fun_5()715 void es_fun_5() {
716 sls_mu2.ReaderLock();
717 MyLRFoo.testShared();
718 sls_mu2.Unlock();
719 }
720
es_fun_6()721 void es_fun_6() {
722 Bar.le_fun();
723 }
724
es_fun_7()725 void es_fun_7() {
726 sls_mu.Lock();
727 elr_fun();
728 sls_mu.Unlock();
729 }
730
731 void es_fun_8() __attribute__((no_thread_safety_analysis));
732
es_fun_8()733 void es_fun_8() {
734 Bar.aa_elr_fun_s();
735 }
736
737 void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
es_fun_9()738 void es_fun_9() {
739 Bar.aa_elr_fun_s();
740 }
741
742 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
es_fun_10()743 void es_fun_10() {
744 Bar.aa_elr_fun_s();
745 }
746
es_bad_0()747 void es_bad_0() {
748 Bar.aa_elr_fun(); // \
749 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
750 }
751
es_bad_1()752 void es_bad_1() {
753 aa_mu.ReaderLock();
754 Bar.aa_elr_fun(); // \
755 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
756 aa_mu.Unlock();
757 }
758
es_bad_2()759 void es_bad_2() {
760 Bar.aa_elr_fun_s(); // \
761 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
762 }
763
es_bad_3()764 void es_bad_3() {
765 MyLRFoo.test(); // \
766 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
767 }
768
es_bad_4()769 void es_bad_4() {
770 MyLRFoo.testShared(); // \
771 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
772 }
773
es_bad_5()774 void es_bad_5() {
775 sls_mu.ReaderLock();
776 MyLRFoo.test(); // \
777 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
778 sls_mu.Unlock();
779 }
780
es_bad_6()781 void es_bad_6() {
782 sls_mu.Lock();
783 Bar.le_fun(); // \
784 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
785 sls_mu.Unlock();
786 }
787
es_bad_7()788 void es_bad_7() {
789 sls_mu.ReaderLock();
790 Bar.le_fun(); // \
791 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
792 sls_mu.Unlock();
793 }
794
795
796 //-----------------------------------------------//
797 // Unparseable lock expressions
798 // ----------------------------------------------//
799
800 // FIXME -- derive new tests for unhandled expressions
801
802
803 //----------------------------------------------------------------------------//
804 // The following test cases are ported from the gcc thread safety implementation
805 // They are each wrapped inside a namespace with the test number of the gcc test
806 //
807 // FIXME: add all the gcc tests, once this analysis passes them.
808 //----------------------------------------------------------------------------//
809
810 //-----------------------------------------//
811 // Good testcases (no errors)
812 //-----------------------------------------//
813
814 namespace thread_annot_lock_20 {
815 class Bar {
816 public:
817 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
818 static int b_ GUARDED_BY(mu1_);
819 static Mutex mu1_;
820 static int a_ GUARDED_BY(mu1_);
821 };
822
823 Bar b1;
824
func1()825 int Bar::func1()
826 {
827 int res = 5;
828
829 if (a_ == 4)
830 res = b_;
831 return res;
832 }
833 } // end namespace thread_annot_lock_20
834
835 namespace thread_annot_lock_22 {
836 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
837 // uses in class definitions.
838 Mutex mu;
839
840 class Bar {
841 public:
842 int a_ GUARDED_BY(mu1_);
843 int b_;
844 int *q PT_GUARDED_BY(mu);
845 Mutex mu1_ ACQUIRED_AFTER(mu);
846 };
847
848 Bar b1, *b3;
849 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
850 int res GUARDED_BY(mu) = 5;
851
func(int i)852 int func(int i)
853 {
854 int x;
855 mu.Lock();
856 b1.mu1_.Lock();
857 res = b1.a_ + b3->b_;
858 *p = i;
859 b1.a_ = res + b3->b_;
860 b3->b_ = *b1.q;
861 b1.mu1_.Unlock();
862 b1.b_ = res;
863 x = res;
864 mu.Unlock();
865 return x;
866 }
867 } // end namespace thread_annot_lock_22
868
869 namespace thread_annot_lock_27_modified {
870 // test lock annotations applied to function definitions
871 // Modified: applied annotations only to function declarations
872 Mutex mu1;
873 Mutex mu2 ACQUIRED_AFTER(mu1);
874
875 class Foo {
876 public:
877 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
878 };
879
method1(int i)880 int Foo::method1(int i) {
881 return i;
882 }
883
884
885 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
foo(int i)886 int foo(int i) {
887 return i;
888 }
889
890 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
bar(int i)891 static int bar(int i) {
892 return i;
893 }
894
main()895 void main() {
896 Foo a;
897
898 mu1.Lock();
899 mu2.Lock();
900 a.method1(1);
901 foo(2);
902 mu2.Unlock();
903 bar(3);
904 mu1.Unlock();
905 }
906 } // end namespace thread_annot_lock_27_modified
907
908
909 namespace thread_annot_lock_38 {
910 // Test the case where a template member function is annotated with lock
911 // attributes in a non-template class.
912 class Foo {
913 public:
914 void func1(int y) LOCKS_EXCLUDED(mu_);
915 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
916 private:
917 Mutex mu_;
918 };
919
920 Foo *foo;
921
main()922 void main()
923 {
924 foo->func1(5);
925 foo->func2(5);
926 }
927 } // end namespace thread_annot_lock_38
928
929 namespace thread_annot_lock_43 {
930 // Tests lock canonicalization
931 class Foo {
932 public:
933 Mutex *mu_;
934 };
935
936 class FooBar {
937 public:
938 Foo *foo_;
GetA()939 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
940 int a_ GUARDED_BY(foo_->mu_);
941 };
942
943 FooBar *fb;
944
main()945 void main()
946 {
947 int x;
948 fb->foo_->mu_->Lock();
949 x = fb->GetA();
950 fb->foo_->mu_->Unlock();
951 }
952 } // end namespace thread_annot_lock_43
953
954 namespace thread_annot_lock_49 {
955 // Test the support for use of lock expression in the annotations
956 class Foo {
957 public:
958 Mutex foo_mu_;
959 };
960
961 class Bar {
962 private:
963 Foo *foo;
964 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
965
966 public:
Test1()967 void Test1() {
968 foo->foo_mu_.Lock();
969 bar_mu_.Lock();
970 bar_mu_.Unlock();
971 foo->foo_mu_.Unlock();
972 }
973 };
974
main()975 void main() {
976 Bar bar;
977 bar.Test1();
978 }
979 } // end namespace thread_annot_lock_49
980
981 namespace thread_annot_lock_61_modified {
982 // Modified to fix the compiler errors
983 // Test the fix for a bug introduced by the support of pass-by-reference
984 // paramters.
operator <<thread_annot_lock_61_modified::Foo985 struct Foo { Foo &operator<< (bool) {return *this;} };
986 Foo &getFoo();
functhread_annot_lock_61_modified::Bar987 struct Bar { Foo &func () {return getFoo();} };
operator &thread_annot_lock_61_modified::Bas988 struct Bas { void operator& (Foo &) {} };
mumble()989 void mumble()
990 {
991 Bas() & Bar().func() << "" << "";
992 Bas() & Bar().func() << "";
993 }
994 } // end namespace thread_annot_lock_61_modified
995
996
997 namespace thread_annot_lock_65 {
998 // Test the fix for a bug in the support of allowing reader locks for
999 // non-const, non-modifying overload functions. (We didn't handle the builtin
1000 // properly.)
1001 enum MyFlags {
1002 Zero,
1003 One,
1004 Two,
1005 Three,
1006 Four,
1007 Five,
1008 Six,
1009 Seven,
1010 Eight,
1011 Nine
1012 };
1013
1014 inline MyFlags
operator |(MyFlags a,MyFlags b)1015 operator|(MyFlags a, MyFlags b)
1016 {
1017 return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1018 }
1019
1020 inline MyFlags&
operator |=(MyFlags & a,MyFlags b)1021 operator|=(MyFlags& a, MyFlags b)
1022 {
1023 return a = a | b;
1024 }
1025 } // end namespace thread_annot_lock_65
1026
1027 namespace thread_annot_lock_66_modified {
1028 // Modified: Moved annotation to function defn
1029 // Test annotations on out-of-line definitions of member functions where the
1030 // annotations refer to locks that are also data members in the class.
1031 Mutex mu;
1032
1033 class Foo {
1034 public:
1035 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1036 int data GUARDED_BY(mu1);
1037 Mutex *mu1;
1038 Mutex *mu2;
1039 };
1040
method1(int i)1041 int Foo::method1(int i)
1042 {
1043 return data + i;
1044 }
1045
main()1046 void main()
1047 {
1048 Foo a;
1049
1050 a.mu2->Lock();
1051 a.mu1->Lock();
1052 mu.Lock();
1053 a.method1(1);
1054 mu.Unlock();
1055 a.mu1->Unlock();
1056 a.mu2->Unlock();
1057 }
1058 } // end namespace thread_annot_lock_66_modified
1059
1060 namespace thread_annot_lock_68_modified {
1061 // Test a fix to a bug in the delayed name binding with nested template
1062 // instantiation. We use a stack to make sure a name is not resolved to an
1063 // inner context.
1064 template <typename T>
1065 class Bar {
1066 Mutex mu_;
1067 };
1068
1069 template <typename T>
1070 class Foo {
1071 public:
func(T x)1072 void func(T x) {
1073 mu_.Lock();
1074 count_ = x;
1075 mu_.Unlock();
1076 }
1077
1078 private:
1079 T count_ GUARDED_BY(mu_);
1080 Bar<T> bar_;
1081 Mutex mu_;
1082 };
1083
main()1084 void main()
1085 {
1086 Foo<int> *foo;
1087 foo->func(5);
1088 }
1089 } // end namespace thread_annot_lock_68_modified
1090
1091 namespace thread_annot_lock_30_modified {
1092 // Test delay parsing of lock attribute arguments with nested classes.
1093 // Modified: trylocks replaced with exclusive_lock_fun
1094 int a = 0;
1095
1096 class Bar {
1097 struct Foo;
1098
1099 public:
1100 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1101
func()1102 int func() {
1103 MyLock();
1104 // if (foo == 0) {
1105 // return 0;
1106 // }
1107 a = 5;
1108 mu.Unlock();
1109 return 1;
1110 }
1111
1112 class FooBar {
1113 int x;
1114 int y;
1115 };
1116
1117 private:
1118 Mutex mu;
1119 };
1120
1121 Bar *bar;
1122
main()1123 void main()
1124 {
1125 bar->func();
1126 }
1127 } // end namespace thread_annot_lock_30_modified
1128
1129 namespace thread_annot_lock_47 {
1130 // Test the support for annotations on virtual functions.
1131 // This is a good test case. (i.e. There should be no warning emitted by the
1132 // compiler.)
1133 class Base {
1134 public:
1135 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1136 virtual void func2() LOCKS_EXCLUDED(mu_);
1137 Mutex mu_;
1138 };
1139
1140 class Child : public Base {
1141 public:
1142 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1143 virtual void func2() LOCKS_EXCLUDED(mu_);
1144 };
1145
main()1146 void main() {
1147 Child *c;
1148 Base *b = c;
1149
1150 b->mu_.Lock();
1151 b->func1();
1152 b->mu_.Unlock();
1153 b->func2();
1154
1155 c->mu_.Lock();
1156 c->func1();
1157 c->mu_.Unlock();
1158 c->func2();
1159 }
1160 } // end namespace thread_annot_lock_47
1161
1162 //-----------------------------------------//
1163 // Tests which produce errors
1164 //-----------------------------------------//
1165
1166 namespace thread_annot_lock_13 {
1167 Mutex mu1;
1168 Mutex mu2;
1169
1170 int g GUARDED_BY(mu1);
1171 int w GUARDED_BY(mu2);
1172
1173 class Foo {
1174 public:
1175 void bar() LOCKS_EXCLUDED(mu_, mu1);
1176 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1177
1178 private:
1179 int a_ GUARDED_BY(mu_);
1180 public:
1181 Mutex mu_ ACQUIRED_AFTER(mu1);
1182 };
1183
foo()1184 int Foo::foo()
1185 {
1186 int res;
1187 w = 5;
1188 res = a_ + 5;
1189 return res;
1190 }
1191
bar()1192 void Foo::bar()
1193 {
1194 int x;
1195 mu_.Lock();
1196 x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1197 a_ = x + 1;
1198 mu_.Unlock();
1199 if (x > 5) {
1200 mu1.Lock();
1201 g = 2;
1202 mu1.Unlock();
1203 }
1204 }
1205
main()1206 void main()
1207 {
1208 Foo f1, *f2;
1209 f1.mu_.Lock();
1210 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
1211 mu2.Lock();
1212 f1.foo();
1213 mu2.Unlock();
1214 f1.mu_.Unlock();
1215 f2->mu_.Lock();
1216 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
1217 f2->mu_.Unlock();
1218 mu2.Lock();
1219 w = 2;
1220 mu2.Unlock();
1221 }
1222 } // end namespace thread_annot_lock_13
1223
1224 namespace thread_annot_lock_18_modified {
1225 // Modified: Trylocks removed
1226 // Test the ability to distnguish between the same lock field of
1227 // different objects of a class.
1228 class Bar {
1229 public:
1230 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1231 void MyUnlock() UNLOCK_FUNCTION(mu1_);
1232 int a_ GUARDED_BY(mu1_);
1233
1234 private:
1235 Mutex mu1_;
1236 };
1237
1238 Bar *b1, *b2;
1239
func()1240 void func()
1241 {
1242 b1->MyLock();
1243 b1->a_ = 5;
1244 b2->a_ = 3; // \
1245 // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
1246 // expected-note {{found near match 'b1->mu1_'}}
1247 b2->MyLock();
1248 b2->MyUnlock();
1249 b1->MyUnlock();
1250 }
1251 } // end namespace thread_annot_lock_18_modified
1252
1253 namespace thread_annot_lock_21 {
1254 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1255 // uses in class definitions.
1256 Mutex mu;
1257
1258 class Bar {
1259 public:
1260 int a_ GUARDED_BY(mu1_);
1261 int b_;
1262 int *q PT_GUARDED_BY(mu);
1263 Mutex mu1_ ACQUIRED_AFTER(mu);
1264 };
1265
1266 Bar b1, *b3;
1267 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1268
1269 int res GUARDED_BY(mu) = 5;
1270
func(int i)1271 int func(int i)
1272 {
1273 int x;
1274 b3->mu1_.Lock();
1275 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
1276 // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
1277 // expected-note {{found near match 'b3->mu1_'}}
1278 *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
1279 // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
1280 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
1281 // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
1282 // expected-note {{found near match 'b3->mu1_'}}
1283 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1284 b3->mu1_.Unlock();
1285 b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1286 x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1287 return x;
1288 }
1289 } // end namespace thread_annot_lock_21
1290
1291 namespace thread_annot_lock_35_modified {
1292 // Test the analyzer's ability to distinguish the lock field of different
1293 // objects.
1294 class Foo {
1295 private:
1296 Mutex lock_;
1297 int a_ GUARDED_BY(lock_);
1298
1299 public:
Func(Foo * child)1300 void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1301 Foo *new_foo = new Foo;
1302
1303 lock_.Lock();
1304
1305 child->Func(new_foo); // There shouldn't be any warning here as the
1306 // acquired lock is not in child.
1307 child->bar(7); // \
1308 // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
1309 // expected-note {{found near match 'lock_'}}
1310 child->a_ = 5; // \
1311 // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
1312 // expected-note {{found near match 'lock_'}}
1313 lock_.Unlock();
1314 }
1315
bar(int y)1316 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1317 a_ = y;
1318 }
1319 };
1320
1321 Foo *x;
1322
main()1323 void main() {
1324 Foo *child = new Foo;
1325 x->Func(child);
1326 }
1327 } // end namespace thread_annot_lock_35_modified
1328
1329 namespace thread_annot_lock_36_modified {
1330 // Modified to move the annotations to function defns.
1331 // Test the analyzer's ability to distinguish the lock field of different
1332 // objects
1333 class Foo {
1334 private:
1335 Mutex lock_;
1336 int a_ GUARDED_BY(lock_);
1337
1338 public:
1339 void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1340 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1341 };
1342
Func(Foo * child)1343 void Foo::Func(Foo* child) {
1344 Foo *new_foo = new Foo;
1345
1346 lock_.Lock();
1347
1348 child->lock_.Lock();
1349 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
1350 child->bar(7);
1351 child->a_ = 5;
1352 child->lock_.Unlock();
1353
1354 lock_.Unlock();
1355 }
1356
bar(int y)1357 void Foo::bar(int y) {
1358 a_ = y;
1359 }
1360
1361
1362 Foo *x;
1363
main()1364 void main() {
1365 Foo *child = new Foo;
1366 x->Func(child);
1367 }
1368 } // end namespace thread_annot_lock_36_modified
1369
1370
1371 namespace thread_annot_lock_42 {
1372 // Test support of multiple lock attributes of the same kind on a decl.
1373 class Foo {
1374 private:
1375 Mutex mu1, mu2, mu3;
1376 int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1377 int y GUARDED_BY(mu2);
1378
f2()1379 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1380 mu2.Lock();
1381 y = 2;
1382 mu2.Unlock();
1383 }
1384
1385 public:
f1()1386 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1387 x = 5;
1388 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
1389 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1390 }
1391 };
1392
1393 Foo *foo;
1394
func()1395 void func()
1396 {
1397 foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
1398 // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
1399 }
1400 } // end namespace thread_annot_lock_42
1401
1402 namespace thread_annot_lock_46 {
1403 // Test the support for annotations on virtual functions.
1404 class Base {
1405 public:
1406 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1407 virtual void func2() LOCKS_EXCLUDED(mu_);
1408 Mutex mu_;
1409 };
1410
1411 class Child : public Base {
1412 public:
1413 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1414 virtual void func2() LOCKS_EXCLUDED(mu_);
1415 };
1416
main()1417 void main() {
1418 Child *c;
1419 Base *b = c;
1420
1421 b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
1422 b->mu_.Lock();
1423 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
1424 b->mu_.Unlock();
1425
1426 c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
1427 c->mu_.Lock();
1428 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
1429 c->mu_.Unlock();
1430 }
1431 } // end namespace thread_annot_lock_46
1432
1433 namespace thread_annot_lock_67_modified {
1434 // Modified: attributes on definitions moved to declarations
1435 // Test annotations on out-of-line definitions of member functions where the
1436 // annotations refer to locks that are also data members in the class.
1437 Mutex mu;
1438 Mutex mu3;
1439
1440 class Foo {
1441 public:
1442 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1443 int data GUARDED_BY(mu1);
1444 Mutex *mu1;
1445 Mutex *mu2;
1446 };
1447
method1(int i)1448 int Foo::method1(int i) {
1449 return data + i;
1450 }
1451
main()1452 void main()
1453 {
1454 Foo a;
1455 a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
1456 // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1457 // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
1458 // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1459 }
1460 } // end namespace thread_annot_lock_67_modified
1461
1462
1463 namespace substitution_test {
1464 class MyData {
1465 public:
1466 Mutex mu;
1467
lockData()1468 void lockData() __attribute__((exclusive_lock_function(mu))) { }
unlockData()1469 void unlockData() __attribute__((unlock_function(mu))) { }
1470
doSomething()1471 void doSomething() __attribute__((exclusive_locks_required(mu))) { }
1472 };
1473
1474
1475 class DataLocker {
1476 public:
lockData(MyData * d)1477 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
unlockData(MyData * d)1478 void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { }
1479 };
1480
1481
1482 class Foo {
1483 public:
foo(MyData * d)1484 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
1485
bar1(MyData * d)1486 void bar1(MyData* d) {
1487 d->lockData();
1488 foo(d);
1489 d->unlockData();
1490 }
1491
bar2(MyData * d)1492 void bar2(MyData* d) {
1493 DataLocker dlr;
1494 dlr.lockData(d);
1495 foo(d);
1496 dlr.unlockData(d);
1497 }
1498
bar3(MyData * d1,MyData * d2)1499 void bar3(MyData* d1, MyData* d2) {
1500 DataLocker dlr;
1501 dlr.lockData(d1); // expected-note {{mutex acquired here}}
1502 dlr.unlockData(d2); // \
1503 // expected-warning {{unlocking 'd2->mu' that was not locked}}
1504 } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
1505
bar4(MyData * d1,MyData * d2)1506 void bar4(MyData* d1, MyData* d2) {
1507 DataLocker dlr;
1508 dlr.lockData(d1);
1509 foo(d2); // \
1510 // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
1511 // expected-note {{found near match 'd1->mu'}}
1512 dlr.unlockData(d1);
1513 }
1514 };
1515 } // end namespace substituation_test
1516
1517
1518
1519 namespace constructor_destructor_tests {
1520 Mutex fooMu;
1521 int myVar GUARDED_BY(fooMu);
1522
1523 class Foo {
1524 public:
Foo()1525 Foo() __attribute__((exclusive_lock_function(fooMu))) { }
~Foo()1526 ~Foo() __attribute__((unlock_function(fooMu))) { }
1527 };
1528
fooTest()1529 void fooTest() {
1530 Foo foo;
1531 myVar = 0;
1532 }
1533 }
1534
1535
1536 namespace invalid_lock_expression_test {
1537
1538 class LOCKABLE MyLockable {
1539 public:
MyLockable()1540 MyLockable() __attribute__((exclusive_lock_function)) { }
~MyLockable()1541 ~MyLockable() { }
1542 };
1543
1544 // create an empty lock expression
foo()1545 void foo() {
1546 MyLockable lock; // \
1547 // expected-warning {{cannot resolve lock expression}}
1548 }
1549
1550 } // end namespace invalid_lock_expression_test
1551
1552 namespace template_member_test {
1553
1554 struct S { int n; };
1555 struct T {
1556 Mutex m;
1557 S *s GUARDED_BY(this->m);
1558 };
1559 Mutex m;
1560 struct U {
1561 union {
1562 int n;
1563 };
1564 } *u GUARDED_BY(m);
1565
1566 template<typename U>
1567 struct IndirectLock {
DoNaughtyThingstemplate_member_test::IndirectLock1568 int DoNaughtyThings(T *t) {
1569 u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1570 return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
1571 }
1572 };
1573
1574 template struct IndirectLock<int>; // expected-note {{here}}
1575
1576 struct V {
1577 void f(int);
1578 void f(double);
1579
1580 Mutex m;
1581 V *p GUARDED_BY(this->m);
1582 };
1583 template<typename U> struct W {
1584 V v;
ftemplate_member_test::W1585 void f(U u) {
1586 v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
1587 }
1588 };
1589 template struct W<int>; // expected-note {{here}}
1590
1591 }
1592
1593 namespace test_scoped_lockable {
1594
1595 struct TestScopedLockable {
1596 Mutex mu1;
1597 Mutex mu2;
1598 int a __attribute__((guarded_by(mu1)));
1599 int b __attribute__((guarded_by(mu2)));
1600
1601 bool getBool();
1602
foo1test_scoped_lockable::TestScopedLockable1603 void foo1() {
1604 MutexLock mulock(&mu1);
1605 a = 5;
1606 }
1607
foo2test_scoped_lockable::TestScopedLockable1608 void foo2() {
1609 ReaderMutexLock mulock1(&mu1);
1610 if (getBool()) {
1611 MutexLock mulock2a(&mu2);
1612 b = a + 1;
1613 }
1614 else {
1615 MutexLock mulock2b(&mu2);
1616 b = a + 2;
1617 }
1618 }
1619
foo3test_scoped_lockable::TestScopedLockable1620 void foo3() {
1621 MutexLock mulock_a(&mu1);
1622 MutexLock mulock_b(&mu1); // \
1623 // expected-warning {{locking 'mu1' that is already locked}}
1624 }
1625
foo4test_scoped_lockable::TestScopedLockable1626 void foo4() {
1627 MutexLock mulock1(&mu1), mulock2(&mu2);
1628 a = b+1;
1629 b = a+1;
1630 }
1631 };
1632
1633 } // end namespace test_scoped_lockable
1634
1635
1636 namespace FunctionAttrTest {
1637
1638 class Foo {
1639 public:
1640 Mutex mu_;
1641 int a GUARDED_BY(mu_);
1642 };
1643
1644 Foo fooObj;
1645
1646 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1647
bar()1648 void bar() {
1649 foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
1650 fooObj.mu_.Lock();
1651 foo();
1652 fooObj.mu_.Unlock();
1653 }
1654
1655 }; // end namespace FunctionAttrTest
1656
1657
1658 struct TestTryLock {
1659 Mutex mu;
1660 int a GUARDED_BY(mu);
1661 bool cond;
1662
foo1TestTryLock1663 void foo1() {
1664 if (mu.TryLock()) {
1665 a = 1;
1666 mu.Unlock();
1667 }
1668 }
1669
foo2TestTryLock1670 void foo2() {
1671 if (!mu.TryLock()) return;
1672 a = 2;
1673 mu.Unlock();
1674 }
1675
foo3TestTryLock1676 void foo3() {
1677 bool b = mu.TryLock();
1678 if (b) {
1679 a = 3;
1680 mu.Unlock();
1681 }
1682 }
1683
foo4TestTryLock1684 void foo4() {
1685 bool b = mu.TryLock();
1686 if (!b) return;
1687 a = 4;
1688 mu.Unlock();
1689 }
1690
foo5TestTryLock1691 void foo5() {
1692 while (mu.TryLock()) {
1693 a = a + 1;
1694 mu.Unlock();
1695 }
1696 }
1697
foo6TestTryLock1698 void foo6() {
1699 bool b = mu.TryLock();
1700 b = !b;
1701 if (b) return;
1702 a = 6;
1703 mu.Unlock();
1704 }
1705
foo7TestTryLock1706 void foo7() {
1707 bool b1 = mu.TryLock();
1708 bool b2 = !b1;
1709 bool b3 = !b2;
1710 if (b3) {
1711 a = 7;
1712 mu.Unlock();
1713 }
1714 }
1715
1716 // Test use-def chains: join points
foo8TestTryLock1717 void foo8() {
1718 bool b = mu.TryLock();
1719 bool b2 = b;
1720 if (cond)
1721 b = true;
1722 if (b) { // b should be unknown at this point, because of the join point
1723 a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1724 }
1725 if (b2) { // b2 should be known at this point.
1726 a = 8;
1727 mu.Unlock();
1728 }
1729 }
1730
1731 // Test use-def-chains: back edges
foo9TestTryLock1732 void foo9() {
1733 bool b = mu.TryLock();
1734
1735 for (int i = 0; i < 10; ++i);
1736
1737 if (b) { // b is still known, because the loop doesn't alter it
1738 a = 9;
1739 mu.Unlock();
1740 }
1741 }
1742
1743 // Test use-def chains: back edges
foo10TestTryLock1744 void foo10() {
1745 bool b = mu.TryLock();
1746
1747 while (cond) {
1748 if (b) { // b should be uknown at this point b/c of the loop
1749 a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1750 }
1751 b = !b;
1752 }
1753 }
1754 }; // end TestTrylock
1755
1756
1757 namespace TestTemplateAttributeInstantiation {
1758
1759 class Foo1 {
1760 public:
1761 Mutex mu_;
1762 int a GUARDED_BY(mu_);
1763 };
1764
1765 class Foo2 {
1766 public:
1767 int a GUARDED_BY(mu_);
1768 Mutex mu_;
1769 };
1770
1771
1772 class Bar {
1773 public:
1774 // Test non-dependent expressions in attributes on template functions
1775 template <class T>
barND(Foo1 * foo,T * fooT)1776 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
1777 foo->a = 0;
1778 }
1779
1780 // Test dependent expressions in attributes on template functions
1781 template <class T>
barD(Foo1 * foo,T * fooT)1782 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
1783 fooT->a = 0;
1784 }
1785 };
1786
1787
1788 template <class T>
1789 class BarT {
1790 public:
1791 Foo1 fooBase;
1792 T fooBaseT;
1793
1794 // Test non-dependent expression in ordinary method on template class
barND()1795 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
1796 fooBase.a = 0;
1797 }
1798
1799 // Test dependent expressions in ordinary methods on template class
barD()1800 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
1801 fooBaseT.a = 0;
1802 }
1803
1804 // Test dependent expressions in template method in template class
1805 template <class T2>
barTD(T2 * fooT)1806 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
1807 fooBaseT.a = 0;
1808 fooT->a = 0;
1809 }
1810 };
1811
1812 template <class T>
1813 class Cell {
1814 public:
1815 Mutex mu_;
1816 // Test dependent guarded_by
1817 T data GUARDED_BY(mu_);
1818
fooEx()1819 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1820 data = 0;
1821 }
1822
foo()1823 void foo() {
1824 mu_.Lock();
1825 data = 0;
1826 mu_.Unlock();
1827 }
1828 };
1829
test()1830 void test() {
1831 Bar b;
1832 BarT<Foo2> bt;
1833 Foo1 f1;
1834 Foo2 f2;
1835
1836 f1.mu_.Lock();
1837 f2.mu_.Lock();
1838 bt.fooBase.mu_.Lock();
1839 bt.fooBaseT.mu_.Lock();
1840
1841 b.barND(&f1, &f2);
1842 b.barD(&f1, &f2);
1843 bt.barND();
1844 bt.barD();
1845 bt.barTD(&f2);
1846
1847 f1.mu_.Unlock();
1848 bt.barTD(&f1); // \
1849 // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
1850 // expected-note {{found near match 'bt.fooBase.mu_'}}
1851
1852 bt.fooBase.mu_.Unlock();
1853 bt.fooBaseT.mu_.Unlock();
1854 f2.mu_.Unlock();
1855
1856 Cell<int> cell;
1857 cell.data = 0; // \
1858 // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
1859 cell.foo();
1860 cell.mu_.Lock();
1861 cell.fooEx();
1862 cell.mu_.Unlock();
1863 }
1864
1865
1866 template <class T>
1867 class CellDelayed {
1868 public:
1869 // Test dependent guarded_by
1870 T data GUARDED_BY(mu_);
1871 static T static_data GUARDED_BY(static_mu_);
1872
fooEx(CellDelayed<T> * other)1873 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
1874 this->data = other->data;
1875 }
1876
1877 template <class T2>
fooExT(CellDelayed<T2> * otherT)1878 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
1879 this->data = otherT->data;
1880 }
1881
foo()1882 void foo() {
1883 mu_.Lock();
1884 data = 0;
1885 mu_.Unlock();
1886 }
1887
1888 Mutex mu_;
1889 static Mutex static_mu_;
1890 };
1891
testDelayed()1892 void testDelayed() {
1893 CellDelayed<int> celld;
1894 CellDelayed<int> celld2;
1895 celld.foo();
1896 celld.mu_.Lock();
1897 celld2.mu_.Lock();
1898
1899 celld.fooEx(&celld2);
1900 celld.fooExT(&celld2);
1901
1902 celld2.mu_.Unlock();
1903 celld.mu_.Unlock();
1904 }
1905
1906 }; // end namespace TestTemplateAttributeInstantiation
1907
1908
1909 namespace FunctionDeclDefTest {
1910
1911 class Foo {
1912 public:
1913 Mutex mu_;
1914 int a GUARDED_BY(mu_);
1915
1916 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1917 };
1918
1919 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
foo1(Foo * f_defined)1920 void Foo::foo1(Foo *f_defined) {
1921 f_defined->a = 0;
1922 };
1923
test()1924 void test() {
1925 Foo myfoo;
1926 myfoo.foo1(&myfoo); // \
1927 // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
1928 myfoo.mu_.Lock();
1929 myfoo.foo1(&myfoo);
1930 myfoo.mu_.Unlock();
1931 }
1932
1933 };
1934
1935 namespace GoingNative {
1936
1937 struct __attribute__((lockable)) mutex {
1938 void lock() __attribute__((exclusive_lock_function));
1939 void unlock() __attribute__((unlock_function));
1940 // ...
1941 };
1942 bool foo();
1943 bool bar();
1944 mutex m;
test()1945 void test() {
1946 m.lock();
1947 while (foo()) {
1948 m.unlock();
1949 // ...
1950 if (bar()) {
1951 // ...
1952 if (foo())
1953 continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
1954 //...
1955 }
1956 // ...
1957 m.lock(); // expected-note {{mutex acquired here}}
1958 }
1959 m.unlock();
1960 }
1961
1962 }
1963
1964
1965
1966 namespace FunctionDefinitionTest {
1967
1968 class Foo {
1969 public:
1970 void foo1();
1971 void foo2();
1972 void foo3(Foo *other);
1973
1974 template<class T>
1975 void fooT1(const T& dummy1);
1976
1977 template<class T>
1978 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
1979
1980 Mutex mu_;
1981 int a GUARDED_BY(mu_);
1982 };
1983
1984 template<class T>
1985 class FooT {
1986 public:
1987 void foo();
1988
1989 Mutex mu_;
1990 T a GUARDED_BY(mu_);
1991 };
1992
1993
foo1()1994 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
1995 a = 1;
1996 }
1997
foo2()1998 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1999 a = 2;
2000 }
2001
foo3(Foo * other)2002 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2003 other->a = 3;
2004 }
2005
2006 template<class T>
fooT1(const T & dummy1)2007 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2008 a = dummy1;
2009 }
2010
2011 /* TODO -- uncomment with template instantiation of attributes.
2012 template<class T>
2013 void Foo::fooT2(const T& dummy2) {
2014 a = dummy2;
2015 }
2016 */
2017
fooF1(Foo * f)2018 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2019 f->a = 1;
2020 }
2021
2022 void fooF2(Foo *f);
fooF2(Foo * f)2023 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2024 f->a = 2;
2025 }
2026
2027 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
fooF3(Foo * f)2028 void fooF3(Foo *f) {
2029 f->a = 3;
2030 }
2031
2032 template<class T>
foo()2033 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2034 a = 0;
2035 }
2036
test()2037 void test() {
2038 int dummy = 0;
2039 Foo myFoo;
2040
2041 myFoo.foo2(); // \
2042 // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
2043 myFoo.foo3(&myFoo); // \
2044 // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
2045 myFoo.fooT1(dummy); // \
2046 // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
2047
2048 myFoo.fooT2(dummy); // \
2049 // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
2050
2051 fooF1(&myFoo); // \
2052 // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
2053 fooF2(&myFoo); // \
2054 // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
2055 fooF3(&myFoo); // \
2056 // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
2057
2058 myFoo.mu_.Lock();
2059 myFoo.foo2();
2060 myFoo.foo3(&myFoo);
2061 myFoo.fooT1(dummy);
2062
2063 myFoo.fooT2(dummy);
2064
2065 fooF1(&myFoo);
2066 fooF2(&myFoo);
2067 fooF3(&myFoo);
2068 myFoo.mu_.Unlock();
2069
2070 FooT<int> myFooT;
2071 myFooT.foo(); // \
2072 // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
2073 }
2074
2075 } // end namespace FunctionDefinitionTest
2076
2077
2078 namespace SelfLockingTest {
2079
2080 class LOCKABLE MyLock {
2081 public:
2082 int foo GUARDED_BY(this);
2083
2084 void lock() EXCLUSIVE_LOCK_FUNCTION();
2085 void unlock() UNLOCK_FUNCTION();
2086
doSomething()2087 void doSomething() {
2088 this->lock(); // allow 'this' as a lock expression
2089 foo = 0;
2090 doSomethingElse();
2091 this->unlock();
2092 }
2093
doSomethingElse()2094 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2095 foo = 1;
2096 };
2097
test()2098 void test() {
2099 foo = 2; // \
2100 // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
2101 }
2102 };
2103
2104
2105 class LOCKABLE MyLock2 {
2106 public:
2107 Mutex mu_;
2108 int foo GUARDED_BY(this);
2109
2110 // don't check inside lock and unlock functions
lock()2111 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
unlock()2112 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
2113
2114 // don't check inside constructors and destructors
MyLock2()2115 MyLock2() { foo = 1; }
~MyLock2()2116 ~MyLock2() { foo = 0; }
2117 };
2118
2119
2120 } // end namespace SelfLockingTest
2121
2122
2123 namespace InvalidNonstatic {
2124
2125 // Forward decl here causes bogus "invalid use of non-static data member"
2126 // on reference to mutex_ in guarded_by attribute.
2127 class Foo;
2128
2129 class Foo {
2130 Mutex* mutex_;
2131
2132 int foo __attribute__((guarded_by(mutex_)));
2133 };
2134
2135 } // end namespace InvalidNonStatic
2136
2137
2138 namespace NoReturnTest {
2139
2140 bool condition();
2141 void fatal() __attribute__((noreturn));
2142
2143 Mutex mu_;
2144
test1()2145 void test1() {
2146 MutexLock lock(&mu_);
2147 if (condition()) {
2148 fatal();
2149 return;
2150 }
2151 }
2152
2153 } // end namespace NoReturnTest
2154
2155
2156 namespace TestMultiDecl {
2157
2158 class Foo {
2159 public:
2160 int GUARDED_BY(mu_) a;
2161 int GUARDED_BY(mu_) b, c;
2162
foo()2163 void foo() {
2164 a = 0; // \
2165 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2166 b = 0; // \
2167 // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
2168 c = 0; // \
2169 // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
2170 }
2171
2172 private:
2173 Mutex mu_;
2174 };
2175
2176 } // end namespace TestMultiDecl
2177
2178
2179 namespace WarnNoDecl {
2180
2181 class Foo {
2182 void foo(int a); __attribute__(( // \
2183 // expected-warning {{declaration does not declare anything}}
2184 exclusive_locks_required(a))); // \
2185 // expected-warning {{attribute exclusive_locks_required ignored}}
2186 };
2187
2188 } // end namespace WarnNoDecl
2189
2190
2191
2192 namespace MoreLockExpressions {
2193
2194 class Foo {
2195 public:
2196 Mutex mu_;
2197 int a GUARDED_BY(mu_);
2198 };
2199
2200 class Bar {
2201 public:
2202 int b;
2203 Foo* f;
2204
getFoo()2205 Foo& getFoo() { return *f; }
getFoo2(int c)2206 Foo& getFoo2(int c) { return *f; }
getFoo3(int c,int d)2207 Foo& getFoo3(int c, int d) { return *f; }
2208
getFooey()2209 Foo& getFooey() { return *f; }
2210 };
2211
getBarFoo(Bar & bar,int c)2212 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
2213
test()2214 void test() {
2215 Foo foo;
2216 Foo *fooArray;
2217 Bar bar;
2218 int a;
2219 int b;
2220 int c;
2221
2222 bar.getFoo().mu_.Lock();
2223 bar.getFoo().a = 0;
2224 bar.getFoo().mu_.Unlock();
2225
2226 (bar.getFoo().mu_).Lock(); // test parenthesis
2227 bar.getFoo().a = 0;
2228 (bar.getFoo().mu_).Unlock();
2229
2230 bar.getFoo2(a).mu_.Lock();
2231 bar.getFoo2(a).a = 0;
2232 bar.getFoo2(a).mu_.Unlock();
2233
2234 bar.getFoo3(a, b).mu_.Lock();
2235 bar.getFoo3(a, b).a = 0;
2236 bar.getFoo3(a, b).mu_.Unlock();
2237
2238 getBarFoo(bar, a).mu_.Lock();
2239 getBarFoo(bar, a).a = 0;
2240 getBarFoo(bar, a).mu_.Unlock();
2241
2242 bar.getFoo2(10).mu_.Lock();
2243 bar.getFoo2(10).a = 0;
2244 bar.getFoo2(10).mu_.Unlock();
2245
2246 bar.getFoo2(a + 1).mu_.Lock();
2247 bar.getFoo2(a + 1).a = 0;
2248 bar.getFoo2(a + 1).mu_.Unlock();
2249
2250 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2251 (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
2252 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2253
2254 bar.getFoo().mu_.Lock();
2255 bar.getFooey().a = 0; // \
2256 // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
2257 // expected-note {{found near match 'bar.getFoo().mu_'}}
2258 bar.getFoo().mu_.Unlock();
2259
2260 bar.getFoo2(a).mu_.Lock();
2261 bar.getFoo2(b).a = 0; // \
2262 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
2263 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2264 bar.getFoo2(a).mu_.Unlock();
2265
2266 bar.getFoo3(a, b).mu_.Lock();
2267 bar.getFoo3(a, c).a = 0; // \
2268 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
2269 // expected-note {{'bar.getFoo3(a,b).mu_'}}
2270 bar.getFoo3(a, b).mu_.Unlock();
2271
2272 getBarFoo(bar, a).mu_.Lock();
2273 getBarFoo(bar, b).a = 0; // \
2274 // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
2275 // expected-note {{'getBarFoo(bar,a).mu_'}}
2276 getBarFoo(bar, a).mu_.Unlock();
2277
2278 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2279 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2280 // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
2281 // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
2282 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2283 }
2284
2285
2286 } // end namespace MoreLockExpressions
2287
2288
2289 namespace TrylockJoinPoint {
2290
2291 class Foo {
2292 Mutex mu;
2293 bool c;
2294
foo()2295 void foo() {
2296 if (c) {
2297 if (!mu.TryLock())
2298 return;
2299 } else {
2300 mu.Lock();
2301 }
2302 mu.Unlock();
2303 }
2304 };
2305
2306 } // end namespace TrylockJoinPoint
2307
2308
2309 namespace LockReturned {
2310
2311 class Foo {
2312 public:
2313 int a GUARDED_BY(mu_);
2314 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2315 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2316
2317 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2318
2319 Mutex* getMu() LOCK_RETURNED(mu_);
2320
2321 Mutex mu_;
2322
2323 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2324 };
2325
2326
2327 // Calls getMu() directly to lock and unlock
test1(Foo * f1,Foo * f2)2328 void test1(Foo* f1, Foo* f2) {
2329 f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
2330 f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
2331
2332 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
2333 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
2334 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
2335
2336 f1->getMu()->Lock();
2337
2338 f1->a = 0;
2339 f1->foo();
2340 f1->foo2(f2); // \
2341 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
2342 // expected-note {{found near match 'f1->mu_'}}
2343
2344 Foo::getMu(f2)->Lock();
2345 f1->foo2(f2);
2346 Foo::getMu(f2)->Unlock();
2347
2348 Foo::sfoo(f1);
2349
2350 f1->getMu()->Unlock();
2351 }
2352
2353
2354 Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2355
2356 class Bar : public Foo {
2357 public:
2358 int b GUARDED_BY(getMu());
2359 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2360 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2361
2362 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2363 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2364 };
2365
2366
2367
2368 // Use getMu() within other attributes.
2369 // This requires at lest levels of substitution, more in the case of
test2(Bar * b1,Bar * b2)2370 void test2(Bar* b1, Bar* b2) {
2371 b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
2372 b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
2373 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
2374 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
2375 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
2376 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
2377
2378 b1->getMu()->Lock();
2379
2380 b1->b = 0;
2381 b1->bar();
2382 b1->bar2(b2); // \
2383 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
2384 // // expected-note {{found near match 'b1->mu_'}}
2385
2386 b2->getMu()->Lock();
2387 b1->bar2(b2);
2388
2389 b2->getMu()->Unlock();
2390
2391 Bar::sbar(b1);
2392 Bar::sbar2(b1);
2393
2394 b1->getMu()->Unlock();
2395 }
2396
2397
2398 // Sanity check -- lock the mutex directly, but use attributes that call getMu()
2399 // Also lock the mutex using getFooMu, which calls a lock_returned function.
test3(Bar * b1,Bar * b2)2400 void test3(Bar* b1, Bar* b2) {
2401 b1->mu_.Lock();
2402 b1->b = 0;
2403 b1->bar();
2404
2405 getFooMu(b2)->Lock();
2406 b1->bar2(b2);
2407 getFooMu(b2)->Unlock();
2408
2409 Bar::sbar(b1);
2410 Bar::sbar2(b1);
2411
2412 b1->mu_.Unlock();
2413 }
2414
2415 } // end namespace LockReturned
2416
2417
2418 namespace ReleasableScopedLock {
2419
2420 class Foo {
2421 Mutex mu_;
2422 bool c;
2423 int a GUARDED_BY(mu_);
2424
2425 void test1();
2426 void test2();
2427 void test3();
2428 void test4();
2429 void test5();
2430 };
2431
2432
test1()2433 void Foo::test1() {
2434 ReleasableMutexLock rlock(&mu_);
2435 rlock.Release();
2436 }
2437
test2()2438 void Foo::test2() {
2439 ReleasableMutexLock rlock(&mu_);
2440 if (c) { // test join point -- held/not held during release
2441 rlock.Release();
2442 }
2443 }
2444
test3()2445 void Foo::test3() {
2446 ReleasableMutexLock rlock(&mu_);
2447 a = 0;
2448 rlock.Release();
2449 a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2450 }
2451
test4()2452 void Foo::test4() {
2453 ReleasableMutexLock rlock(&mu_);
2454 rlock.Release();
2455 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
2456 }
2457
test5()2458 void Foo::test5() {
2459 ReleasableMutexLock rlock(&mu_);
2460 if (c) {
2461 rlock.Release();
2462 }
2463 // no warning on join point for managed lock.
2464 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
2465 }
2466
2467
2468 } // end namespace ReleasableScopedLock
2469
2470
2471 namespace TrylockFunctionTest {
2472
2473 class Foo {
2474 public:
2475 Mutex mu1_;
2476 Mutex mu2_;
2477 bool c;
2478
2479 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
2480 };
2481
lockBoth()2482 bool Foo::lockBoth() {
2483 if (!mu1_.TryLock())
2484 return false;
2485
2486 mu2_.Lock();
2487 if (!c) {
2488 mu1_.Unlock();
2489 mu2_.Unlock();
2490 return false;
2491 }
2492
2493 return true;
2494 }
2495
2496
2497 } // end namespace TrylockFunctionTest
2498
2499
2500
2501 namespace DoubleLockBug {
2502
2503 class Foo {
2504 public:
2505 Mutex mu_;
2506 int a GUARDED_BY(mu_);
2507
2508 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2509 int foo2() SHARED_LOCKS_REQUIRED(mu_);
2510 };
2511
2512
foo1()2513 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2514 a = 0;
2515 }
2516
foo2()2517 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
2518 return a;
2519 }
2520
2521 }
2522
2523
2524
2525 namespace UnlockBug {
2526
2527 class Foo {
2528 public:
2529 Mutex mutex_;
2530
foo1()2531 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2532 mutex_.Unlock();
2533 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2534
2535
foo2()2536 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2537 mutex_.Unlock();
2538 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2539 };
2540
2541 } // end namespace UnlockBug
2542
2543
2544
2545 namespace FoolishScopedLockableBug {
2546
2547 class SCOPED_LOCKABLE WTF_ScopedLockable {
2548 public:
2549 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2550
2551 // have to call release() manually;
2552 ~WTF_ScopedLockable();
2553
2554 void release() UNLOCK_FUNCTION();
2555 };
2556
2557
2558 class Foo {
2559 Mutex mu_;
2560 int a GUARDED_BY(mu_);
2561 bool c;
2562
2563 void doSomething();
2564
test1()2565 void test1() {
2566 WTF_ScopedLockable wtf(&mu_);
2567 wtf.release();
2568 }
2569
test2()2570 void test2() {
2571 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2572 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
2573
test3()2574 void test3() {
2575 if (c) {
2576 WTF_ScopedLockable wtf(&mu_);
2577 wtf.release();
2578 }
2579 }
2580
test4()2581 void test4() {
2582 if (c) {
2583 doSomething();
2584 }
2585 else {
2586 WTF_ScopedLockable wtf(&mu_);
2587 wtf.release();
2588 }
2589 }
2590
test5()2591 void test5() {
2592 if (c) {
2593 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2594 }
2595 } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2596
test6()2597 void test6() {
2598 if (c) {
2599 doSomething();
2600 }
2601 else {
2602 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2603 }
2604 } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2605 };
2606
2607
2608 } // end namespace FoolishScopedLockableBug
2609
2610
2611
2612 namespace TemporaryCleanupExpr {
2613
2614 class Foo {
2615 int a GUARDED_BY(getMutexPtr().get());
2616
2617 SmartPtr<Mutex> getMutexPtr();
2618
2619 void test();
2620 };
2621
2622
test()2623 void Foo::test() {
2624 {
2625 ReaderMutexLock lock(getMutexPtr().get());
2626 int b = a;
2627 }
2628 int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
2629 }
2630
2631 } // end namespace TemporaryCleanupExpr
2632
2633
2634
2635 namespace SmartPointerTests {
2636
2637 class Foo {
2638 public:
2639 SmartPtr<Mutex> mu_;
2640 int a GUARDED_BY(mu_);
2641 int b GUARDED_BY(mu_.get());
2642 int c GUARDED_BY(*mu_);
2643
2644 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
2645 void Unlock() UNLOCK_FUNCTION(mu_);
2646
2647 void test0();
2648 void test1();
2649 void test2();
2650 void test3();
2651 void test4();
2652 void test5();
2653 void test6();
2654 void test7();
2655 void test8();
2656 };
2657
test0()2658 void Foo::test0() {
2659 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2660 b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
2661 c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
2662 }
2663
test1()2664 void Foo::test1() {
2665 mu_->Lock();
2666 a = 0;
2667 b = 0;
2668 c = 0;
2669 mu_->Unlock();
2670 }
2671
test2()2672 void Foo::test2() {
2673 (*mu_).Lock();
2674 a = 0;
2675 b = 0;
2676 c = 0;
2677 (*mu_).Unlock();
2678 }
2679
2680
test3()2681 void Foo::test3() {
2682 mu_.get()->Lock();
2683 a = 0;
2684 b = 0;
2685 c = 0;
2686 mu_.get()->Unlock();
2687 }
2688
2689
test4()2690 void Foo::test4() {
2691 MutexLock lock(mu_.get());
2692 a = 0;
2693 b = 0;
2694 c = 0;
2695 }
2696
2697
test5()2698 void Foo::test5() {
2699 MutexLock lock(&(*mu_));
2700 a = 0;
2701 b = 0;
2702 c = 0;
2703 }
2704
2705
test6()2706 void Foo::test6() {
2707 Lock();
2708 a = 0;
2709 b = 0;
2710 c = 0;
2711 Unlock();
2712 }
2713
2714
test7()2715 void Foo::test7() {
2716 {
2717 Lock();
2718 mu_->Unlock();
2719 }
2720 {
2721 mu_->Lock();
2722 Unlock();
2723 }
2724 {
2725 mu_.get()->Lock();
2726 mu_->Unlock();
2727 }
2728 {
2729 mu_->Lock();
2730 mu_.get()->Unlock();
2731 }
2732 {
2733 mu_.get()->Lock();
2734 (*mu_).Unlock();
2735 }
2736 {
2737 (*mu_).Lock();
2738 mu_->Unlock();
2739 }
2740 }
2741
2742
test8()2743 void Foo::test8() {
2744 mu_->Lock();
2745 mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}}
2746 (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}}
2747 mu_.get()->Unlock();
2748 Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}}
2749 }
2750
2751
2752 class Bar {
2753 SmartPtr<Foo> foo;
2754
2755 void test0();
2756 void test1();
2757 void test2();
2758 void test3();
2759 };
2760
2761
test0()2762 void Bar::test0() {
2763 foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
2764 (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
2765 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
2766 }
2767
2768
test1()2769 void Bar::test1() {
2770 foo->mu_->Lock();
2771 foo->a = 0;
2772 (*foo).b = 0;
2773 foo.get()->c = 0;
2774 foo->mu_->Unlock();
2775 }
2776
2777
test2()2778 void Bar::test2() {
2779 (*foo).mu_->Lock();
2780 foo->a = 0;
2781 (*foo).b = 0;
2782 foo.get()->c = 0;
2783 foo.get()->mu_->Unlock();
2784 }
2785
2786
test3()2787 void Bar::test3() {
2788 MutexLock lock(foo->mu_.get());
2789 foo->a = 0;
2790 (*foo).b = 0;
2791 foo.get()->c = 0;
2792 }
2793
2794 } // end namespace SmartPointerTests
2795
2796
2797
2798 namespace DuplicateAttributeTest {
2799
2800 class LOCKABLE Foo {
2801 public:
2802 Mutex mu1_;
2803 Mutex mu2_;
2804 Mutex mu3_;
2805 int a GUARDED_BY(mu1_);
2806 int b GUARDED_BY(mu2_);
2807 int c GUARDED_BY(mu3_);
2808
2809 void lock() EXCLUSIVE_LOCK_FUNCTION();
2810 void unlock() UNLOCK_FUNCTION();
2811
2812 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
2813 void slock1() SHARED_LOCK_FUNCTION(mu1_);
2814 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2815 void locklots()
2816 EXCLUSIVE_LOCK_FUNCTION(mu1_)
2817 EXCLUSIVE_LOCK_FUNCTION(mu2_)
2818 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2819
2820 void unlock1() UNLOCK_FUNCTION(mu1_);
2821 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2822 void unlocklots()
2823 UNLOCK_FUNCTION(mu1_)
2824 UNLOCK_FUNCTION(mu2_)
2825 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2826 };
2827
2828
lock()2829 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
unlock()2830 void Foo::unlock() UNLOCK_FUNCTION() { }
2831
lock1()2832 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
2833 mu1_.Lock();
2834 }
2835
slock1()2836 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
2837 mu1_.Lock();
2838 }
2839
lock3()2840 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
2841 mu1_.Lock();
2842 mu2_.Lock();
2843 mu3_.Lock();
2844 }
2845
locklots()2846 void Foo::locklots()
2847 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
2848 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
2849 mu1_.Lock();
2850 mu2_.Lock();
2851 mu3_.Lock();
2852 }
2853
unlock1()2854 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
2855 mu1_.Unlock();
2856 }
2857
unlock3()2858 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
2859 mu1_.Unlock();
2860 mu2_.Unlock();
2861 mu3_.Unlock();
2862 }
2863
unlocklots()2864 void Foo::unlocklots()
2865 UNLOCK_FUNCTION(mu1_, mu2_)
2866 UNLOCK_FUNCTION(mu2_, mu3_) {
2867 mu1_.Unlock();
2868 mu2_.Unlock();
2869 mu3_.Unlock();
2870 }
2871
2872
test0()2873 void test0() {
2874 Foo foo;
2875 foo.lock();
2876 foo.unlock();
2877
2878 foo.lock();
2879 foo.lock(); // expected-warning {{locking 'foo' that is already locked}}
2880 foo.unlock();
2881 foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}}
2882 }
2883
2884
test1()2885 void test1() {
2886 Foo foo;
2887 foo.lock1();
2888 foo.a = 0;
2889 foo.unlock1();
2890
2891 foo.lock1();
2892 foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
2893 foo.a = 0;
2894 foo.unlock1();
2895 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
2896 }
2897
2898
test2()2899 int test2() {
2900 Foo foo;
2901 foo.slock1();
2902 int d1 = foo.a;
2903 foo.unlock1();
2904
2905 foo.slock1();
2906 foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
2907 int d2 = foo.a;
2908 foo.unlock1();
2909 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
2910 return d1 + d2;
2911 }
2912
2913
test3()2914 void test3() {
2915 Foo foo;
2916 foo.lock3();
2917 foo.a = 0;
2918 foo.b = 0;
2919 foo.c = 0;
2920 foo.unlock3();
2921
2922 foo.lock3();
2923 foo.lock3(); // \
2924 // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2925 // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2926 // expected-warning {{locking 'foo.mu3_' that is already locked}}
2927 foo.a = 0;
2928 foo.b = 0;
2929 foo.c = 0;
2930 foo.unlock3();
2931 foo.unlock3(); // \
2932 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2933 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2934 // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
2935 }
2936
2937
testlots()2938 void testlots() {
2939 Foo foo;
2940 foo.locklots();
2941 foo.a = 0;
2942 foo.b = 0;
2943 foo.c = 0;
2944 foo.unlocklots();
2945
2946 foo.locklots();
2947 foo.locklots(); // \
2948 // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2949 // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2950 // expected-warning {{locking 'foo.mu3_' that is already locked}}
2951 foo.a = 0;
2952 foo.b = 0;
2953 foo.c = 0;
2954 foo.unlocklots();
2955 foo.unlocklots(); // \
2956 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2957 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2958 // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
2959 }
2960
2961 } // end namespace DuplicateAttributeTest
2962
2963
2964
2965 namespace TryLockEqTest {
2966
2967 class Foo {
2968 Mutex mu_;
2969 int a GUARDED_BY(mu_);
2970 bool c;
2971
2972 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
2973 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
2974 void unlock() UNLOCK_FUNCTION(mu_);
2975
2976 void test1();
2977 void test2();
2978 };
2979
2980
test1()2981 void Foo::test1() {
2982 if (tryLockMutexP() == 0) {
2983 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2984 return;
2985 }
2986 a = 0;
2987 unlock();
2988
2989 if (tryLockMutexP() != 0) {
2990 a = 0;
2991 unlock();
2992 }
2993
2994 if (0 != tryLockMutexP()) {
2995 a = 0;
2996 unlock();
2997 }
2998
2999 if (!(tryLockMutexP() == 0)) {
3000 a = 0;
3001 unlock();
3002 }
3003
3004 if (tryLockMutexI() == 0) {
3005 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3006 return;
3007 }
3008 a = 0;
3009 unlock();
3010
3011 if (0 == tryLockMutexI()) {
3012 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3013 return;
3014 }
3015 a = 0;
3016 unlock();
3017
3018 if (tryLockMutexI() == 1) {
3019 a = 0;
3020 unlock();
3021 }
3022
3023 if (mu_.TryLock() == false) {
3024 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3025 return;
3026 }
3027 a = 0;
3028 unlock();
3029
3030 if (mu_.TryLock() == true) {
3031 a = 0;
3032 unlock();
3033 }
3034 else {
3035 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3036 }
3037
3038 #if __has_feature(cxx_nullptr)
3039 if (tryLockMutexP() == nullptr) {
3040 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3041 return;
3042 }
3043 a = 0;
3044 unlock();
3045 #endif
3046 }
3047
3048
test2()3049 void Foo::test2() {
3050 /* FIXME: these tests depend on changes to the CFG.
3051 *
3052 if (mu_.TryLock() && c) {
3053 a = 0;
3054 unlock();
3055 }
3056 else return;
3057
3058 if (c && mu_.TryLock()) {
3059 a = 0;
3060 unlock();
3061 }
3062 else return;
3063
3064 if (!(mu_.TryLock() && c))
3065 return;
3066 a = 0;
3067 unlock();
3068
3069 if (!(c && mu_.TryLock()))
3070 return;
3071 a = 0;
3072 unlock();
3073
3074 if (!(mu_.TryLock() == 0) && c) {
3075 a = 0;
3076 unlock();
3077 }
3078
3079 if (!mu_.TryLock() || c)
3080 return;
3081 a = 0;
3082 unlock();
3083 */
3084 }
3085
3086 } // end namespace TryLockEqTest
3087
3088
3089 namespace ExistentialPatternMatching {
3090
3091 class Graph {
3092 public:
3093 Mutex mu_;
3094 };
3095
3096 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3097 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3098
3099 class Node {
3100 public:
3101 int a GUARDED_BY(&Graph::mu_);
3102
foo()3103 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3104 a = 0;
3105 }
3106 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3107 };
3108
test()3109 void test() {
3110 Graph g1;
3111 Graph g2;
3112 Node n1;
3113
3114 n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3115 n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
3116 n1.foo2();
3117
3118 g1.mu_.Lock();
3119 n1.a = 0;
3120 n1.foo();
3121 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3122 g1.mu_.Unlock();
3123
3124 g2.mu_.Lock();
3125 n1.a = 0;
3126 n1.foo();
3127 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3128 g2.mu_.Unlock();
3129
3130 LockAllGraphs();
3131 n1.a = 0;
3132 n1.foo();
3133 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3134 UnlockAllGraphs();
3135
3136 LockAllGraphs();
3137 g1.mu_.Unlock();
3138
3139 LockAllGraphs();
3140 g2.mu_.Unlock();
3141
3142 LockAllGraphs();
3143 g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}}
3144 g1.mu_.Unlock();
3145 }
3146
3147 } // end namespace ExistentialPatternMatching
3148
3149
3150 namespace StringIgnoreTest {
3151
3152 class Foo {
3153 public:
3154 Mutex mu_;
3155 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3156 void unlock() UNLOCK_FUNCTION("");
3157 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3158 void roober() SHARED_LOCKS_REQUIRED("");
3159 };
3160
3161
3162 class Bar : public Foo {
3163 public:
bar(Foo * f)3164 void bar(Foo* f) {
3165 f->unlock();
3166 f->goober();
3167 f->roober();
3168 f->lock();
3169 };
3170 };
3171
3172 } // end namespace StringIgnoreTest
3173
3174
3175 namespace LockReturnedScopeFix {
3176
3177 class Base {
3178 protected:
3179 struct Inner;
3180 bool c;
3181
3182 const Mutex& getLock(const Inner* i);
3183
3184 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3185 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3186 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3187
3188 void bar(Inner* i);
3189 };
3190
3191
3192 struct Base::Inner {
3193 Mutex lock_;
3194 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3195 };
3196
3197
getLock(const Inner * i)3198 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3199 return i->lock_;
3200 }
3201
3202
foo(Inner * i)3203 void Base::foo(Inner* i) {
3204 i->doSomething();
3205 }
3206
bar(Inner * i)3207 void Base::bar(Inner* i) {
3208 if (c) {
3209 i->lock_.Lock();
3210 unlockInner(i);
3211 }
3212 else {
3213 lockInner(i);
3214 i->lock_.Unlock();
3215 }
3216 }
3217
3218 } // end namespace LockReturnedScopeFix
3219
3220
3221 namespace TrylockWithCleanups {
3222
3223 class MyString {
3224 public:
3225 MyString(const char* s);
3226 ~MyString();
3227 };
3228
3229 struct Foo {
3230 Mutex mu_;
3231 int a GUARDED_BY(mu_);
3232 };
3233
3234 Foo* GetAndLockFoo(const MyString& s)
3235 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3236
test()3237 static void test() {
3238 Foo* lt = GetAndLockFoo("foo");
3239 if (!lt) return;
3240 int a = lt->a;
3241 lt->mu_.Unlock();
3242 }
3243
3244 }
3245
3246
3247 namespace UniversalLock {
3248
3249 class Foo {
3250 Mutex mu_;
3251 bool c;
3252
3253 int a GUARDED_BY(mu_);
3254 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3255 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3256
test1()3257 void test1() {
3258 int b;
3259
3260 beginNoWarnOnReads();
3261 b = a;
3262 r_foo();
3263 endNoWarnOnReads();
3264
3265 beginNoWarnOnWrites();
3266 a = 0;
3267 w_foo();
3268 endNoWarnOnWrites();
3269 }
3270
3271 // don't warn on joins with universal lock
test2()3272 void test2() {
3273 if (c) {
3274 beginNoWarnOnWrites();
3275 }
3276 a = 0; // \
3277 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3278 endNoWarnOnWrites(); // \
3279 // expected-warning {{unlocking '*' that was not locked}}
3280 }
3281
3282
3283 // make sure the universal lock joins properly
test3()3284 void test3() {
3285 if (c) {
3286 mu_.Lock();
3287 beginNoWarnOnWrites();
3288 }
3289 else {
3290 beginNoWarnOnWrites();
3291 mu_.Lock();
3292 }
3293 a = 0;
3294 endNoWarnOnWrites();
3295 mu_.Unlock();
3296 }
3297
3298
3299 // combine universal lock with other locks
test4()3300 void test4() {
3301 beginNoWarnOnWrites();
3302 mu_.Lock();
3303 mu_.Unlock();
3304 endNoWarnOnWrites();
3305
3306 mu_.Lock();
3307 beginNoWarnOnWrites();
3308 endNoWarnOnWrites();
3309 mu_.Unlock();
3310
3311 mu_.Lock();
3312 beginNoWarnOnWrites();
3313 mu_.Unlock();
3314 endNoWarnOnWrites();
3315 }
3316 };
3317
3318 }
3319