[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-thread-safety-analysis.cpp
blob8477200456d985dc1206a6831c526abf9a7966e9
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
6 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
7 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
9 #include "thread-safety-annotations.h"
11 class LOCKABLE Mutex {
12 public:
13 void Lock() EXCLUSIVE_LOCK_FUNCTION();
14 void ReaderLock() SHARED_LOCK_FUNCTION();
15 void Unlock() UNLOCK_FUNCTION();
16 void ExclusiveUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
17 void ReaderUnlock() SHARED_UNLOCK_FUNCTION();
18 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
19 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
20 void LockWhen(const int &cond) EXCLUSIVE_LOCK_FUNCTION();
22 void PromoteShared() SHARED_UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();
23 void DemoteExclusive() EXCLUSIVE_UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();
25 // for negative capabilities
26 const Mutex& operator!() const { return *this; }
28 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
29 void AssertReaderHeld() ASSERT_SHARED_LOCK();
32 class SCOPED_LOCKABLE MutexLock {
33 public:
34 MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
35 MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu);
36 ~MutexLock() UNLOCK_FUNCTION();
39 class SCOPED_LOCKABLE ReaderMutexLock {
40 public:
41 ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu);
42 ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu);
43 ~ReaderMutexLock() UNLOCK_FUNCTION();
46 class SCOPED_LOCKABLE ReleasableMutexLock {
47 public:
48 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
49 ~ReleasableMutexLock() UNLOCK_FUNCTION();
51 void Release() UNLOCK_FUNCTION();
54 class SCOPED_LOCKABLE DoubleMutexLock {
55 public:
56 DoubleMutexLock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);
57 ~DoubleMutexLock() UNLOCK_FUNCTION();
60 // The universal lock, written "*", allows checking to be selectively turned
61 // off for a particular piece of code.
62 void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
63 void endNoWarnOnReads() UNLOCK_FUNCTION("*");
64 void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
65 void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
68 // For testing handling of smart pointers.
69 template<class T>
70 class SmartPtr {
71 public:
72 SmartPtr(T* p) : ptr_(p) { }
73 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
74 ~SmartPtr();
76 T* get() const { return ptr_; }
77 T* operator->() const { return ptr_; }
78 T& operator*() const { return *ptr_; }
79 T& operator[](int i) const { return ptr_[i]; }
81 private:
82 T* ptr_;
85 template<typename T, typename U>
86 U& operator->*(const SmartPtr<T>& ptr, U T::*p) { return ptr->*p; }
89 // For testing destructor calls and cleanup.
90 class MyString {
91 public:
92 MyString(const char* s);
93 ~MyString();
97 // For testing operator overloading
98 template <class K, class T>
99 class MyMap {
100 public:
101 T& operator[](const K& k);
105 // For testing handling of containers.
106 template <class T>
107 class MyContainer {
108 public:
109 MyContainer();
111 typedef T* iterator;
112 typedef const T* const_iterator;
114 T* begin();
115 T* end();
117 const T* cbegin();
118 const T* cend();
120 T& operator[](int i);
121 const T& operator[](int i) const;
123 private:
124 T* ptr_;
129 Mutex sls_mu;
131 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
132 int sls_guard_var __attribute__((guarded_var)) = 0;
133 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
135 bool getBool();
137 class MutexWrapper {
138 public:
139 Mutex mu;
140 int x __attribute__((guarded_by(mu)));
141 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
144 struct TestingMoreComplexAttributes {
145 Mutex lock;
146 struct { Mutex lock; } strct;
147 union {
148 bool a __attribute__((guarded_by(lock)));
149 bool b __attribute__((guarded_by(strct.lock)));
150 bool *ptr_a __attribute__((pt_guarded_by(lock)));
151 bool *ptr_b __attribute__((pt_guarded_by(strct.lock)));
152 Mutex lock1 __attribute__((acquired_before(lock))) __attribute__((acquired_before(strct.lock)));
153 Mutex lock2 __attribute__((acquired_after(lock))) __attribute__((acquired_after(strct.lock)));
155 } more_complex_atttributes;
157 void more_complex_attributes() {
158 more_complex_atttributes.a = true; // expected-warning{{writing variable 'a' requires holding mutex 'lock' exclusively}}
159 more_complex_atttributes.b = true; // expected-warning{{writing variable 'b' requires holding mutex 'strct.lock' exclusively}}
160 *more_complex_atttributes.ptr_a = true; // expected-warning{{writing the value pointed to by 'ptr_a' requires holding mutex 'lock' exclusively}}
161 *more_complex_atttributes.ptr_b = true; // expected-warning{{writing the value pointed to by 'ptr_b' requires holding mutex 'strct.lock' exclusively}}
163 more_complex_atttributes.lock.Lock();
164 more_complex_atttributes.lock1.Lock(); // expected-warning{{mutex 'lock1' must be acquired before 'lock'}}
165 more_complex_atttributes.lock1.Unlock();
166 more_complex_atttributes.lock.Unlock();
168 more_complex_atttributes.lock2.Lock();
169 more_complex_atttributes.lock.Lock(); // expected-warning{{mutex 'lock' must be acquired before 'lock2'}}
170 more_complex_atttributes.lock.Unlock();
171 more_complex_atttributes.lock2.Unlock();
174 MutexWrapper sls_mw;
176 void sls_fun_0() {
177 sls_mw.mu.Lock();
178 sls_mw.x = 5;
179 sls_mw.mu.Unlock();
182 void sls_fun_2() {
183 sls_mu.Lock();
184 int x = sls_guard_var;
185 sls_mu.Unlock();
188 void sls_fun_3() {
189 sls_mu.Lock();
190 sls_guard_var = 2;
191 sls_mu.Unlock();
194 void sls_fun_4() {
195 sls_mu2.Lock();
196 sls_guard_var = 2;
197 sls_mu2.Unlock();
200 void sls_fun_5() {
201 sls_mu.Lock();
202 int x = sls_guardby_var;
203 sls_mu.Unlock();
206 void sls_fun_6() {
207 sls_mu.Lock();
208 sls_guardby_var = 2;
209 sls_mu.Unlock();
212 void sls_fun_7() {
213 sls_mu.Lock();
214 sls_mu2.Lock();
215 sls_mu2.Unlock();
216 sls_mu.Unlock();
219 void sls_fun_8() {
220 sls_mu.Lock();
221 if (getBool())
222 sls_mu.Unlock();
223 else
224 sls_mu.Unlock();
227 void sls_fun_9() {
228 if (getBool())
229 sls_mu.Lock();
230 else
231 sls_mu.Lock();
232 sls_mu.Unlock();
235 void sls_fun_good_6() {
236 if (getBool()) {
237 sls_mu.Lock();
238 } else {
239 if (getBool()) {
240 getBool(); // EMPTY
241 } else {
242 getBool(); // EMPTY
244 sls_mu.Lock();
246 sls_mu.Unlock();
249 void sls_fun_good_7() {
250 sls_mu.Lock();
251 while (getBool()) {
252 sls_mu.Unlock();
253 if (getBool()) {
254 if (getBool()) {
255 sls_mu.Lock();
256 continue;
259 sls_mu.Lock();
261 sls_mu.Unlock();
264 void sls_fun_good_8() {
265 sls_mw.MyLock();
266 sls_mw.mu.Unlock();
269 void sls_fun_bad_1() {
270 sls_mu.Unlock(); // \
271 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
274 void sls_fun_bad_2() {
275 sls_mu.Lock(); // expected-note{{mutex acquired here}}
276 sls_mu.Lock(); // \
277 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
278 sls_mu.Unlock();
281 void sls_fun_bad_3() {
282 sls_mu.Lock(); // expected-note {{mutex acquired here}}
283 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
285 void sls_fun_bad_4() {
286 if (getBool())
287 sls_mu.Lock(); // expected-note{{mutex acquired here}}
288 else
289 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
290 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
291 // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
293 void sls_fun_bad_5() {
294 sls_mu.Lock(); // expected-note {{mutex acquired here}}
295 if (getBool())
296 sls_mu.Unlock();
297 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
299 void sls_fun_bad_6() {
300 if (getBool()) {
301 sls_mu.Lock(); // expected-note {{mutex acquired here}}
302 } else {
303 if (getBool()) {
304 getBool(); // EMPTY
305 } else {
306 getBool(); // EMPTY
309 sls_mu.Unlock(); // \
310 expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
311 expected-warning{{releasing mutex 'sls_mu' that was not held}}
314 void sls_fun_bad_7() {
315 sls_mu.Lock();
316 while (getBool()) { // \
317 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
318 sls_mu.Unlock();
319 if (getBool()) {
320 if (getBool()) {
321 continue;
324 sls_mu.Lock(); // expected-note {{mutex acquired here}}
326 sls_mu.Unlock();
329 void sls_fun_bad_8() {
330 sls_mu.Lock(); // expected-note{{mutex acquired here}}
332 do {
333 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
334 } while (getBool());
337 void sls_fun_bad_9() {
338 do {
339 sls_mu.Lock(); // \
340 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
341 // expected-note{{mutex acquired here}}
342 } while (getBool());
343 sls_mu.Unlock();
346 void sls_fun_bad_10() {
347 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
348 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
349 sls_mu.Unlock();
351 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
353 void sls_fun_bad_11() {
354 while (getBool()) { // \
355 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
356 sls_mu.Lock(); // expected-note {{mutex acquired here}}
358 sls_mu.Unlock(); // \
359 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
362 void sls_fun_bad_12() {
363 sls_mu.Lock(); // expected-note {{mutex acquired here}}
364 while (getBool()) {
365 sls_mu.Unlock();
366 if (getBool()) {
367 if (getBool()) {
368 break;
371 sls_mu.Lock();
373 sls_mu.Unlock(); // \
374 expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
375 expected-warning{{releasing mutex 'sls_mu' that was not held}}
378 //-----------------------------------------//
379 // Handling lock expressions in attribute args
380 // -------------------------------------------//
382 Mutex aa_mu;
384 class GlobalLocker {
385 public:
386 void globalLock() EXCLUSIVE_LOCK_FUNCTION(aa_mu);
387 void globalUnlock() UNLOCK_FUNCTION(aa_mu);
390 GlobalLocker glock;
392 void aa_fun_1() {
393 glock.globalLock();
394 glock.globalUnlock();
397 void aa_fun_bad_1() {
398 glock.globalUnlock(); // \
399 // expected-warning{{releasing mutex 'aa_mu' that was not held}}
402 void aa_fun_bad_2() {
403 glock.globalLock(); // expected-note{{mutex acquired here}}
404 glock.globalLock(); // \
405 // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
406 glock.globalUnlock();
409 void aa_fun_bad_3() {
410 glock.globalLock(); // expected-note{{mutex acquired here}}
411 } // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
413 //--------------------------------------------------//
414 // Regression tests for unusual method names
415 //--------------------------------------------------//
417 Mutex wmu;
419 // Test diagnostics for other method names.
420 class WeirdMethods {
421 // FIXME: can't currently check inside constructors and destructors.
422 WeirdMethods() {
423 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
424 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
425 ~WeirdMethods() {
426 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
427 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
428 void operator++() {
429 wmu.Lock(); // expected-note {{mutex acquired here}}
430 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
431 operator int*() {
432 wmu.Lock(); // expected-note {{mutex acquired here}}
433 return 0;
434 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
437 //-----------------------------------------------//
438 // Errors for guarded by or guarded var variables
439 // ----------------------------------------------//
441 int *pgb_gvar __attribute__((pt_guarded_var));
442 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
444 class PGBFoo {
445 public:
446 int x;
447 int *pgb_field __attribute__((guarded_by(sls_mu2)))
448 __attribute__((pt_guarded_by(sls_mu)));
449 void testFoo() {
450 pgb_field = &x; // \
451 // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
452 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
453 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
454 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
455 // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
456 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
457 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
461 class GBFoo {
462 public:
463 int gb_field __attribute__((guarded_by(sls_mu)));
465 void testFoo() {
466 gb_field = 0; // \
467 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
470 void testNoAnal() NO_THREAD_SAFETY_ANALYSIS {
471 gb_field = 0;
475 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
477 void gb_fun_0() {
478 sls_mu.Lock();
479 int x = *pgb_var;
480 sls_mu.Unlock();
483 void gb_fun_1() {
484 sls_mu.Lock();
485 *pgb_var = 2;
486 sls_mu.Unlock();
489 void gb_fun_2() {
490 int x;
491 pgb_var = &x;
494 void gb_fun_3() {
495 int *x = pgb_var;
498 void gb_bad_0() {
499 sls_guard_var = 1; // \
500 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
503 void gb_bad_1() {
504 int x = sls_guard_var; // \
505 // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
508 void gb_bad_2() {
509 sls_guardby_var = 1; // \
510 // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
513 void gb_bad_3() {
514 int x = sls_guardby_var; // \
515 // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
518 void gb_bad_4() {
519 *pgb_gvar = 1; // \
520 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
523 void gb_bad_5() {
524 int x = *pgb_gvar; // \
525 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
528 void gb_bad_6() {
529 *pgb_var = 1; // \
530 // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
533 void gb_bad_7() {
534 int x = *pgb_var; // \
535 // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
538 void gb_bad_8() {
539 GBFoo G;
540 G.gb_field = 0; // \
541 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
544 void gb_bad_9() {
545 sls_guard_var++; // \
546 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
547 sls_guard_var--; // \
548 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
549 ++sls_guard_var; // \
550 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
551 --sls_guard_var;// \
552 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
555 //-----------------------------------------------//
556 // Warnings on variables with late parsed attributes
557 // ----------------------------------------------//
559 class LateFoo {
560 public:
561 int a __attribute__((guarded_by(mu)));
562 int b;
564 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu) { }
566 void test() {
567 a = 0; // \
568 // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
569 b = a; // \
570 // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
571 c = 0; // \
572 // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
575 int c __attribute__((guarded_by(mu)));
577 Mutex mu;
580 class LateBar {
581 public:
582 int a_ __attribute__((guarded_by(mu1_)));
583 int b_;
584 int *q __attribute__((pt_guarded_by(mu)));
585 Mutex mu1_;
586 Mutex mu;
587 LateFoo Foo;
588 LateFoo Foo2;
589 LateFoo *FooPointer;
592 LateBar b1, *b3;
594 void late_0() {
595 LateFoo FooA;
596 LateFoo FooB;
597 FooA.mu.Lock();
598 FooA.a = 5;
599 FooA.mu.Unlock();
602 void late_1() {
603 LateBar BarA;
604 BarA.FooPointer->mu.Lock();
605 BarA.FooPointer->a = 2;
606 BarA.FooPointer->mu.Unlock();
609 void late_bad_0() {
610 LateFoo fooA;
611 LateFoo fooB;
612 fooA.mu.Lock();
613 fooB.a = 5; // \
614 // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
615 // expected-note{{found near match 'fooA.mu'}}
616 fooA.mu.Unlock();
619 void late_bad_1() {
620 Mutex mu;
621 mu.Lock();
622 b1.mu1_.Lock();
623 int res = b1.a_ + b3->b_;
624 b3->b_ = *b1.q; // \
625 // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
626 b1.mu1_.Unlock();
627 b1.b_ = res;
628 mu.Unlock();
631 void late_bad_2() {
632 LateBar BarA;
633 BarA.FooPointer->mu.Lock();
634 BarA.Foo.a = 2; // \
635 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
636 // expected-note{{found near match 'BarA.FooPointer->mu'}}
637 BarA.FooPointer->mu.Unlock();
640 void late_bad_3() {
641 LateBar BarA;
642 BarA.Foo.mu.Lock();
643 BarA.FooPointer->a = 2; // \
644 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
645 // expected-note{{found near match 'BarA.Foo.mu'}}
646 BarA.Foo.mu.Unlock();
649 void late_bad_4() {
650 LateBar BarA;
651 BarA.Foo.mu.Lock();
652 BarA.Foo2.a = 2; // \
653 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
654 // expected-note{{found near match 'BarA.Foo.mu'}}
655 BarA.Foo.mu.Unlock();
658 //-----------------------------------------------//
659 // Extra warnings for shared vs. exclusive locks
660 // ----------------------------------------------//
662 void shared_fun_0() {
663 sls_mu.Lock();
664 do {
665 sls_mu.Unlock();
666 sls_mu.Lock();
667 } while (getBool());
668 sls_mu.Unlock();
671 void shared_fun_1() {
672 sls_mu.ReaderLock(); // \
673 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
674 do {
675 sls_mu.Unlock();
676 sls_mu.Lock(); // \
677 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
678 } while (getBool());
679 sls_mu.Unlock();
682 void shared_fun_3() {
683 if (getBool())
684 sls_mu.Lock();
685 else
686 sls_mu.Lock();
687 *pgb_var = 1;
688 sls_mu.Unlock();
691 void shared_fun_4() {
692 if (getBool())
693 sls_mu.ReaderLock();
694 else
695 sls_mu.ReaderLock();
696 int x = sls_guardby_var;
697 sls_mu.Unlock();
700 void shared_fun_8() {
701 if (getBool())
702 sls_mu.Lock(); // \
703 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
704 else
705 sls_mu.ReaderLock(); // \
706 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
707 sls_mu.Unlock();
710 void shared_fun_9() {
711 sls_mu.Lock();
712 sls_mu.ExclusiveUnlock();
714 sls_mu.ReaderLock();
715 sls_mu.ReaderUnlock();
718 void shared_fun_10() {
719 sls_mu.Lock();
720 sls_mu.DemoteExclusive();
721 sls_mu.ReaderUnlock();
724 void shared_fun_11() {
725 sls_mu.ReaderLock();
726 sls_mu.PromoteShared();
727 sls_mu.Unlock();
730 void shared_bad_0() {
731 sls_mu.Lock(); // \
732 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
733 do {
734 sls_mu.Unlock();
735 sls_mu.ReaderLock(); // \
736 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
737 } while (getBool());
738 sls_mu.Unlock();
741 void shared_bad_1() {
742 if (getBool())
743 sls_mu.Lock(); // \
744 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
745 else
746 sls_mu.ReaderLock(); // \
747 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
748 *pgb_var = 1;
749 sls_mu.Unlock();
752 void shared_bad_2() {
753 if (getBool())
754 sls_mu.ReaderLock(); // \
755 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
756 else
757 sls_mu.Lock(); // \
758 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
759 *pgb_var = 1;
760 sls_mu.Unlock();
763 void shared_bad_3() {
764 sls_mu.Lock(); // expected-note {{mutex acquired here}}
765 sls_mu.ReaderUnlock(); // \
766 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
769 void shared_bad_4() {
770 sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
771 sls_mu.ExclusiveUnlock(); // \
772 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
775 void shared_bad_5() {
776 sls_mu.Lock(); // expected-note {{mutex acquired here}}
777 sls_mu.PromoteShared(); // \
778 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
779 sls_mu.ExclusiveUnlock();
782 void shared_bad_6() {
783 sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
784 sls_mu.DemoteExclusive(); // \
785 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
786 sls_mu.ReaderUnlock();
789 // FIXME: Add support for functions (not only methods)
790 class LRBar {
791 public:
792 void aa_elr_fun() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);
793 void aa_elr_fun_s() SHARED_LOCKS_REQUIRED(aa_mu);
794 void le_fun() __attribute__((locks_excluded(sls_mu)));
797 class LRFoo {
798 public:
799 void test() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);
800 void testShared() SHARED_LOCKS_REQUIRED(sls_mu2);
803 void elr_fun() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);
804 void elr_fun() {}
806 LRFoo MyLRFoo;
807 LRBar Bar;
809 void es_fun_0() {
810 aa_mu.Lock();
811 Bar.aa_elr_fun();
812 aa_mu.Unlock();
815 void es_fun_1() {
816 aa_mu.Lock();
817 Bar.aa_elr_fun_s();
818 aa_mu.Unlock();
821 void es_fun_2() {
822 aa_mu.ReaderLock();
823 Bar.aa_elr_fun_s();
824 aa_mu.Unlock();
827 void es_fun_3() {
828 sls_mu.Lock();
829 MyLRFoo.test();
830 sls_mu.Unlock();
833 void es_fun_4() {
834 sls_mu2.Lock();
835 MyLRFoo.testShared();
836 sls_mu2.Unlock();
839 void es_fun_5() {
840 sls_mu2.ReaderLock();
841 MyLRFoo.testShared();
842 sls_mu2.Unlock();
845 void es_fun_6() {
846 Bar.le_fun();
849 void es_fun_7() {
850 sls_mu.Lock();
851 elr_fun();
852 sls_mu.Unlock();
855 void es_fun_8() NO_THREAD_SAFETY_ANALYSIS;
857 void es_fun_8() {
858 Bar.aa_elr_fun_s();
861 void es_fun_9() SHARED_LOCKS_REQUIRED(aa_mu);
862 void es_fun_9() {
863 Bar.aa_elr_fun_s();
866 void es_fun_10() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);
867 void es_fun_10() {
868 Bar.aa_elr_fun_s();
871 void es_bad_0() {
872 Bar.aa_elr_fun(); // \
873 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
876 void es_bad_1() {
877 aa_mu.ReaderLock();
878 Bar.aa_elr_fun(); // \
879 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
880 aa_mu.Unlock();
883 void es_bad_2() {
884 Bar.aa_elr_fun_s(); // \
885 // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
888 void es_bad_3() {
889 MyLRFoo.test(); // \
890 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
893 void es_bad_4() {
894 MyLRFoo.testShared(); // \
895 // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
898 void es_bad_5() {
899 sls_mu.ReaderLock();
900 MyLRFoo.test(); // \
901 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
902 sls_mu.Unlock();
905 void es_bad_6() {
906 sls_mu.Lock();
907 Bar.le_fun(); // \
908 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
909 sls_mu.Unlock();
912 void es_bad_7() {
913 sls_mu.ReaderLock();
914 Bar.le_fun(); // \
915 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
916 sls_mu.Unlock();
920 //-----------------------------------------------//
921 // Unparseable lock expressions
922 // ----------------------------------------------//
924 // FIXME -- derive new tests for unhandled expressions
927 //----------------------------------------------------------------------------//
928 // The following test cases are ported from the gcc thread safety implementation
929 // They are each wrapped inside a namespace with the test number of the gcc test
931 // FIXME: add all the gcc tests, once this analysis passes them.
932 //----------------------------------------------------------------------------//
934 //-----------------------------------------//
935 // Good testcases (no errors)
936 //-----------------------------------------//
938 namespace thread_annot_lock_20 {
939 class Bar {
940 public:
941 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
942 static int b_ GUARDED_BY(mu1_);
943 static Mutex mu1_;
944 static int a_ GUARDED_BY(mu1_);
947 Bar b1;
949 int Bar::func1()
951 int res = 5;
953 if (a_ == 4)
954 res = b_;
955 return res;
957 } // end namespace thread_annot_lock_20
959 namespace thread_annot_lock_22 {
960 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
961 // uses in class definitions.
962 Mutex mu;
964 class Bar {
965 public:
966 int a_ GUARDED_BY(mu1_);
967 int b_;
968 int *q PT_GUARDED_BY(mu);
969 Mutex mu1_ ACQUIRED_AFTER(mu);
972 Bar b1, *b3;
973 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
974 int res GUARDED_BY(mu) = 5;
976 int func(int i)
978 int x;
979 mu.Lock();
980 b1.mu1_.Lock();
981 res = b1.a_ + b3->b_;
982 *p = i;
983 b1.a_ = res + b3->b_;
984 b3->b_ = *b1.q;
985 b1.mu1_.Unlock();
986 b1.b_ = res;
987 x = res;
988 mu.Unlock();
989 return x;
991 } // end namespace thread_annot_lock_22
993 namespace thread_annot_lock_27_modified {
994 // test lock annotations applied to function definitions
995 // Modified: applied annotations only to function declarations
996 Mutex mu1;
997 Mutex mu2 ACQUIRED_AFTER(mu1);
999 class Foo {
1000 public:
1001 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
1004 int Foo::method1(int i) {
1005 return i;
1009 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
1010 int foo(int i) {
1011 return i;
1014 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
1015 static int bar(int i) {
1016 return i;
1019 void main() {
1020 Foo a;
1022 mu1.Lock();
1023 mu2.Lock();
1024 a.method1(1);
1025 foo(2);
1026 mu2.Unlock();
1027 bar(3);
1028 mu1.Unlock();
1030 } // end namespace thread_annot_lock_27_modified
1033 namespace thread_annot_lock_38 {
1034 // Test the case where a template member function is annotated with lock
1035 // attributes in a non-template class.
1036 class Foo {
1037 public:
1038 void func1(int y) LOCKS_EXCLUDED(mu_);
1039 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
1040 private:
1041 Mutex mu_;
1044 Foo *foo;
1046 void main()
1048 foo->func1(5);
1049 foo->func2(5);
1051 } // end namespace thread_annot_lock_38
1053 namespace thread_annot_lock_43 {
1054 // Tests lock canonicalization
1055 class Foo {
1056 public:
1057 Mutex *mu_;
1060 class FooBar {
1061 public:
1062 Foo *foo_;
1063 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
1064 int a_ GUARDED_BY(foo_->mu_);
1067 FooBar *fb;
1069 void main()
1071 int x;
1072 fb->foo_->mu_->Lock();
1073 x = fb->GetA();
1074 fb->foo_->mu_->Unlock();
1076 } // end namespace thread_annot_lock_43
1078 namespace thread_annot_lock_49 {
1079 // Test the support for use of lock expression in the annotations
1080 class Foo {
1081 public:
1082 Mutex foo_mu_;
1085 class Bar {
1086 private:
1087 Foo *foo;
1088 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
1090 public:
1091 void Test1() {
1092 foo->foo_mu_.Lock();
1093 bar_mu_.Lock();
1094 bar_mu_.Unlock();
1095 foo->foo_mu_.Unlock();
1099 void main() {
1100 Bar bar;
1101 bar.Test1();
1103 } // end namespace thread_annot_lock_49
1105 namespace thread_annot_lock_61_modified {
1106 // Modified to fix the compiler errors
1107 // Test the fix for a bug introduced by the support of pass-by-reference
1108 // parameters.
1109 struct Foo { Foo &operator<< (bool) {return *this;} };
1110 Foo &getFoo();
1111 struct Bar { Foo &func () {return getFoo();} };
1112 struct Bas { void operator& (Foo &) {} };
1113 void mumble()
1115 Bas() & Bar().func() << "" << "";
1116 Bas() & Bar().func() << "";
1118 } // end namespace thread_annot_lock_61_modified
1121 namespace thread_annot_lock_65 {
1122 // Test the fix for a bug in the support of allowing reader locks for
1123 // non-const, non-modifying overload functions. (We didn't handle the builtin
1124 // properly.)
1125 enum MyFlags {
1126 Zero,
1127 One,
1128 Two,
1129 Three,
1130 Four,
1131 Five,
1132 Six,
1133 Seven,
1134 Eight,
1135 Nine
1138 inline MyFlags
1139 operator|(MyFlags a, MyFlags b)
1141 return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1144 inline MyFlags&
1145 operator|=(MyFlags& a, MyFlags b)
1147 return a = a | b;
1149 } // end namespace thread_annot_lock_65
1151 namespace thread_annot_lock_66_modified {
1152 // Modified: Moved annotation to function defn
1153 // Test annotations on out-of-line definitions of member functions where the
1154 // annotations refer to locks that are also data members in the class.
1155 Mutex mu;
1157 class Foo {
1158 public:
1159 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1160 int data GUARDED_BY(mu1);
1161 Mutex *mu1;
1162 Mutex *mu2;
1165 int Foo::method1(int i)
1167 return data + i;
1170 void main()
1172 Foo a;
1174 a.mu2->Lock();
1175 a.mu1->Lock();
1176 mu.Lock();
1177 a.method1(1);
1178 mu.Unlock();
1179 a.mu1->Unlock();
1180 a.mu2->Unlock();
1182 } // end namespace thread_annot_lock_66_modified
1184 namespace thread_annot_lock_68_modified {
1185 // Test a fix to a bug in the delayed name binding with nested template
1186 // instantiation. We use a stack to make sure a name is not resolved to an
1187 // inner context.
1188 template <typename T>
1189 class Bar {
1190 Mutex mu_;
1193 template <typename T>
1194 class Foo {
1195 public:
1196 void func(T x) {
1197 mu_.Lock();
1198 count_ = x;
1199 mu_.Unlock();
1202 private:
1203 T count_ GUARDED_BY(mu_);
1204 Bar<T> bar_;
1205 Mutex mu_;
1208 void main()
1210 Foo<int> *foo;
1211 foo->func(5);
1213 } // end namespace thread_annot_lock_68_modified
1215 namespace thread_annot_lock_30_modified {
1216 // Test delay parsing of lock attribute arguments with nested classes.
1217 // Modified: trylocks replaced with exclusive_lock_fun
1218 int a = 0;
1220 class Bar {
1221 struct Foo;
1223 public:
1224 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1226 int func() {
1227 MyLock();
1228 // if (foo == 0) {
1229 // return 0;
1230 // }
1231 a = 5;
1232 mu.Unlock();
1233 return 1;
1236 class FooBar {
1237 int x;
1238 int y;
1241 private:
1242 Mutex mu;
1245 Bar *bar;
1247 void main()
1249 bar->func();
1251 } // end namespace thread_annot_lock_30_modified
1253 namespace thread_annot_lock_47 {
1254 // Test the support for annotations on virtual functions.
1255 // This is a good test case. (i.e. There should be no warning emitted by the
1256 // compiler.)
1257 class Base {
1258 public:
1259 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1260 virtual void func2() LOCKS_EXCLUDED(mu_);
1261 Mutex mu_;
1264 class Child : public Base {
1265 public:
1266 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1267 virtual void func2() LOCKS_EXCLUDED(mu_);
1270 void main() {
1271 Child *c;
1272 Base *b = c;
1274 b->mu_.Lock();
1275 b->func1();
1276 b->mu_.Unlock();
1277 b->func2();
1279 c->mu_.Lock();
1280 c->func1();
1281 c->mu_.Unlock();
1282 c->func2();
1284 } // end namespace thread_annot_lock_47
1286 //-----------------------------------------//
1287 // Tests which produce errors
1288 //-----------------------------------------//
1290 namespace thread_annot_lock_13 {
1291 Mutex mu1;
1292 Mutex mu2;
1294 int g GUARDED_BY(mu1);
1295 int w GUARDED_BY(mu2);
1297 class Foo {
1298 public:
1299 void bar() LOCKS_EXCLUDED(mu_, mu1);
1300 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1302 private:
1303 int a_ GUARDED_BY(mu_);
1304 public:
1305 Mutex mu_ ACQUIRED_AFTER(mu1);
1308 int Foo::foo()
1310 int res;
1311 w = 5;
1312 res = a_ + 5;
1313 return res;
1316 void Foo::bar()
1318 int x;
1319 mu_.Lock();
1320 x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1321 a_ = x + 1;
1322 mu_.Unlock();
1323 if (x > 5) {
1324 mu1.Lock();
1325 g = 2;
1326 mu1.Unlock();
1330 void main()
1332 Foo f1, *f2;
1333 f1.mu_.Lock();
1334 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1335 mu2.Lock();
1336 f1.foo();
1337 mu2.Unlock();
1338 f1.mu_.Unlock();
1339 f2->mu_.Lock();
1340 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1341 f2->mu_.Unlock();
1342 mu2.Lock();
1343 w = 2;
1344 mu2.Unlock();
1346 } // end namespace thread_annot_lock_13
1348 namespace thread_annot_lock_18_modified {
1349 // Modified: Trylocks removed
1350 // Test the ability to distnguish between the same lock field of
1351 // different objects of a class.
1352 class Bar {
1353 public:
1354 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1355 void MyUnlock() UNLOCK_FUNCTION(mu1_);
1356 int a_ GUARDED_BY(mu1_);
1358 private:
1359 Mutex mu1_;
1362 Bar *b1, *b2;
1364 void func()
1366 b1->MyLock();
1367 b1->a_ = 5;
1368 b2->a_ = 3; // \
1369 // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
1370 // expected-note {{found near match 'b1->mu1_'}}
1371 b2->MyLock();
1372 b2->MyUnlock();
1373 b1->MyUnlock();
1375 } // end namespace thread_annot_lock_18_modified
1377 namespace thread_annot_lock_21 {
1378 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1379 // uses in class definitions.
1380 Mutex mu;
1382 class Bar {
1383 public:
1384 int a_ GUARDED_BY(mu1_);
1385 int b_;
1386 int *q PT_GUARDED_BY(mu);
1387 Mutex mu1_ ACQUIRED_AFTER(mu);
1390 Bar b1, *b3;
1391 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1393 int res GUARDED_BY(mu) = 5;
1395 int func(int i)
1397 int x;
1398 b3->mu1_.Lock();
1399 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1400 // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
1401 // expected-note {{found near match 'b3->mu1_'}}
1402 *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1403 // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1404 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1405 // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
1406 // expected-note {{found near match 'b3->mu1_'}}
1407 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1408 b3->mu1_.Unlock();
1409 b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1410 x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1411 return x;
1413 } // end namespace thread_annot_lock_21
1415 namespace thread_annot_lock_35_modified {
1416 // Test the analyzer's ability to distinguish the lock field of different
1417 // objects.
1418 class Foo {
1419 private:
1420 Mutex lock_;
1421 int a_ GUARDED_BY(lock_);
1423 public:
1424 void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1425 Foo *new_foo = new Foo;
1427 lock_.Lock();
1429 child->Func(new_foo); // There shouldn't be any warning here as the
1430 // acquired lock is not in child.
1431 child->bar(7); // \
1432 // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
1433 // expected-note {{found near match 'lock_'}}
1434 child->a_ = 5; // \
1435 // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
1436 // expected-note {{found near match 'lock_'}}
1437 lock_.Unlock();
1440 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1441 a_ = y;
1445 Foo *x;
1447 void main() {
1448 Foo *child = new Foo;
1449 x->Func(child);
1451 } // end namespace thread_annot_lock_35_modified
1453 namespace thread_annot_lock_36_modified {
1454 // Modified to move the annotations to function defns.
1455 // Test the analyzer's ability to distinguish the lock field of different
1456 // objects
1457 class Foo {
1458 private:
1459 Mutex lock_;
1460 int a_ GUARDED_BY(lock_);
1462 public:
1463 void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1464 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1467 void Foo::Func(Foo* child) {
1468 Foo *new_foo = new Foo;
1470 lock_.Lock();
1472 child->lock_.Lock();
1473 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1474 child->bar(7);
1475 child->a_ = 5;
1476 child->lock_.Unlock();
1478 lock_.Unlock();
1481 void Foo::bar(int y) {
1482 a_ = y;
1486 Foo *x;
1488 void main() {
1489 Foo *child = new Foo;
1490 x->Func(child);
1492 } // end namespace thread_annot_lock_36_modified
1495 namespace thread_annot_lock_42 {
1496 // Test support of multiple lock attributes of the same kind on a decl.
1497 class Foo {
1498 private:
1499 Mutex mu1, mu2, mu3;
1500 int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1501 int y GUARDED_BY(mu2);
1503 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1504 mu2.Lock();
1505 y = 2;
1506 mu2.Unlock();
1509 public:
1510 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1511 x = 5;
1512 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1513 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1517 Foo *foo;
1519 void func()
1521 foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1522 // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1524 } // end namespace thread_annot_lock_42
1526 namespace thread_annot_lock_46 {
1527 // Test the support for annotations on virtual functions.
1528 class Base {
1529 public:
1530 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1531 virtual void func2() LOCKS_EXCLUDED(mu_);
1532 Mutex mu_;
1535 class Child : public Base {
1536 public:
1537 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1538 virtual void func2() LOCKS_EXCLUDED(mu_);
1541 void main() {
1542 Child *c;
1543 Base *b = c;
1545 b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1546 b->mu_.Lock();
1547 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1548 b->mu_.Unlock();
1550 c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1551 c->mu_.Lock();
1552 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1553 c->mu_.Unlock();
1555 } // end namespace thread_annot_lock_46
1557 namespace thread_annot_lock_67_modified {
1558 // Modified: attributes on definitions moved to declarations
1559 // Test annotations on out-of-line definitions of member functions where the
1560 // annotations refer to locks that are also data members in the class.
1561 Mutex mu;
1562 Mutex mu3;
1564 class Foo {
1565 public:
1566 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1567 int data GUARDED_BY(mu1);
1568 Mutex *mu1;
1569 Mutex *mu2;
1572 int Foo::method1(int i) {
1573 return data + i;
1576 void main()
1578 Foo a;
1579 a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1580 // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1581 // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1582 // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1584 } // end namespace thread_annot_lock_67_modified
1587 namespace substitution_test {
1588 class MyData {
1589 public:
1590 Mutex mu;
1592 void lockData() EXCLUSIVE_LOCK_FUNCTION(mu);
1593 void unlockData() UNLOCK_FUNCTION(mu);
1595 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu) { }
1599 class DataLocker {
1600 public:
1601 void lockData (MyData *d) EXCLUSIVE_LOCK_FUNCTION(d->mu);
1602 void unlockData(MyData *d) UNLOCK_FUNCTION(d->mu);
1606 class Foo {
1607 public:
1608 void foo(MyData* d) EXCLUSIVE_LOCKS_REQUIRED(d->mu) { }
1610 void bar1(MyData* d) {
1611 d->lockData();
1612 foo(d);
1613 d->unlockData();
1616 void bar2(MyData* d) {
1617 DataLocker dlr;
1618 dlr.lockData(d);
1619 foo(d);
1620 dlr.unlockData(d);
1623 void bar3(MyData* d1, MyData* d2) {
1624 DataLocker dlr;
1625 dlr.lockData(d1); // expected-note {{mutex acquired here}}
1626 dlr.unlockData(d2); // \
1627 // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1628 } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
1630 void bar4(MyData* d1, MyData* d2) {
1631 DataLocker dlr;
1632 dlr.lockData(d1);
1633 foo(d2); // \
1634 // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
1635 // expected-note {{found near match 'd1->mu'}}
1636 dlr.unlockData(d1);
1640 // Automatic object destructor calls don't appear as expressions in the CFG,
1641 // so we have to handle them separately whenever substitutions are required.
1642 struct DestructorRequires {
1643 Mutex mu;
1644 ~DestructorRequires() EXCLUSIVE_LOCKS_REQUIRED(mu);
1647 void destructorRequires() {
1648 DestructorRequires rd;
1649 rd.mu.AssertHeld();
1652 struct DestructorExcludes {
1653 Mutex mu;
1654 ~DestructorExcludes() LOCKS_EXCLUDED(mu);
1657 void destructorExcludes() {
1658 DestructorExcludes ed;
1659 ed.mu.Lock(); // expected-note {{mutex acquired here}}
1660 } // expected-warning {{cannot call function '~DestructorExcludes' while mutex 'ed.mu' is held}}
1661 // expected-warning@-1 {{mutex 'ed.mu' is still held at the end of function}}
1663 } // end namespace substituation_test
1667 namespace constructor_destructor_tests {
1668 Mutex fooMu;
1669 int myVar GUARDED_BY(fooMu);
1671 class Foo {
1672 public:
1673 Foo() EXCLUSIVE_LOCK_FUNCTION(fooMu) { }
1674 ~Foo() UNLOCK_FUNCTION(fooMu) { }
1677 void fooTest() {
1678 Foo foo;
1679 myVar = 0;
1684 namespace template_member_test {
1686 struct S { int n; };
1687 struct T {
1688 Mutex m;
1689 S *s GUARDED_BY(this->m);
1691 Mutex m;
1692 struct U {
1693 union {
1694 int n;
1696 } *u GUARDED_BY(m);
1698 template<typename U>
1699 struct IndirectLock {
1700 int DoNaughtyThings(T *t) {
1701 u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1702 return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
1706 template struct IndirectLock<int>; // expected-note {{here}}
1708 struct V {
1709 void f(int);
1710 void f(double);
1712 Mutex m;
1713 V *p GUARDED_BY(this->m);
1715 template<typename U> struct W {
1716 V v;
1717 void f(U u) {
1718 v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1721 template struct W<int>; // expected-note {{here}}
1725 namespace test_scoped_lockable {
1727 struct TestScopedLockable {
1728 Mutex mu1;
1729 Mutex mu2;
1730 int a __attribute__((guarded_by(mu1)));
1731 int b __attribute__((guarded_by(mu2)));
1733 bool getBool();
1735 bool lock2Bool(MutexLock);
1737 void foo1() {
1738 MutexLock mulock(&mu1);
1739 a = 5;
1742 #ifdef __cpp_guaranteed_copy_elision
1743 void const_lock() {
1744 const MutexLock mulock = MutexLock(&mu1);
1745 a = 5;
1747 #endif
1749 void temporary() {
1750 MutexLock{&mu1}, a = 5;
1753 void temporary_cfg(int x) {
1754 // test the case where a pair of temporary Ctor and Dtor is in different CFG blocks
1755 lock2Bool(MutexLock{&mu1}) || x;
1756 MutexLock{&mu1}; // no-warn
1759 void lifetime_extension() {
1760 const MutexLock &mulock = MutexLock(&mu1);
1761 a = 5;
1764 void foo2() {
1765 ReaderMutexLock mulock1(&mu1);
1766 if (getBool()) {
1767 MutexLock mulock2a(&mu2);
1768 b = a + 1;
1770 else {
1771 MutexLock mulock2b(&mu2);
1772 b = a + 2;
1776 void foo3() {
1777 MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}
1778 MutexLock mulock_b(&mu1); // \
1779 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1782 void temporary_double_lock() {
1783 MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}
1784 MutexLock{&mu1}; // \
1785 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1788 void foo4() {
1789 MutexLock mulock1(&mu1), mulock2(&mu2);
1790 a = b+1;
1791 b = a+1;
1794 void foo5() {
1795 DoubleMutexLock mulock(&mu1, &mu2);
1796 a = b + 1;
1797 b = a + 1;
1801 } // end namespace test_scoped_lockable
1804 namespace FunctionAttrTest {
1806 class Foo {
1807 public:
1808 Mutex mu_;
1809 int a GUARDED_BY(mu_);
1812 Foo fooObj;
1814 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1816 void bar() {
1817 foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1818 fooObj.mu_.Lock();
1819 foo();
1820 fooObj.mu_.Unlock();
1823 }; // end namespace FunctionAttrTest
1826 namespace TryLockTest {
1828 struct TestTryLock {
1829 Mutex mu;
1830 int a GUARDED_BY(mu);
1831 bool cond;
1833 void foo1() {
1834 if (mu.TryLock()) {
1835 a = 1;
1836 mu.Unlock();
1840 void foo2() {
1841 if (!mu.TryLock()) return;
1842 a = 2;
1843 mu.Unlock();
1846 void foo2_builtin_expect() {
1847 if (__builtin_expect(!mu.TryLock(), false))
1848 return;
1849 a = 2;
1850 mu.Unlock();
1853 void foo3() {
1854 bool b = mu.TryLock();
1855 if (b) {
1856 a = 3;
1857 mu.Unlock();
1861 void foo3_builtin_expect() {
1862 bool b = mu.TryLock();
1863 if (__builtin_expect(b, true)) {
1864 a = 3;
1865 mu.Unlock();
1869 void foo4() {
1870 bool b = mu.TryLock();
1871 if (!b) return;
1872 a = 4;
1873 mu.Unlock();
1876 void foo5() {
1877 while (mu.TryLock()) {
1878 a = a + 1;
1879 mu.Unlock();
1883 void foo6() {
1884 bool b = mu.TryLock();
1885 b = !b;
1886 if (b) return;
1887 a = 6;
1888 mu.Unlock();
1891 void foo7() {
1892 bool b1 = mu.TryLock();
1893 bool b2 = !b1;
1894 bool b3 = !b2;
1895 if (b3) {
1896 a = 7;
1897 mu.Unlock();
1901 // Test use-def chains: join points
1902 void foo8() {
1903 bool b = mu.TryLock();
1904 bool b2 = b;
1905 if (cond)
1906 b = true;
1907 if (b) { // b should be unknown at this point, because of the join point
1908 a = 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1910 if (b2) { // b2 should be known at this point.
1911 a = 8;
1912 mu.Unlock();
1916 // Test use-def-chains: back edges
1917 void foo9() {
1918 bool b = mu.TryLock();
1920 for (int i = 0; i < 10; ++i);
1922 if (b) { // b is still known, because the loop doesn't alter it
1923 a = 9;
1924 mu.Unlock();
1928 // Test use-def chains: back edges
1929 void foo10() {
1930 bool b = mu.TryLock();
1932 while (cond) {
1933 if (b) { // b should be unknown at this point b/c of the loop
1934 a = 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1936 b = !b;
1940 // Test merge of exclusive trylock
1941 void foo11() {
1942 if (cond) {
1943 if (!mu.TryLock())
1944 return;
1946 else {
1947 mu.Lock();
1949 a = 10;
1950 mu.Unlock();
1953 // Test merge of shared trylock
1954 void foo12() {
1955 if (cond) {
1956 if (!mu.ReaderTryLock())
1957 return;
1959 else {
1960 mu.ReaderLock();
1962 int i = a;
1963 mu.Unlock();
1966 // Test with conditional operator
1967 void foo13() {
1968 if (mu.TryLock() ? 1 : 0)
1969 mu.Unlock();
1972 void foo14() {
1973 if (mu.TryLock() ? 0 : 1)
1974 return;
1975 mu.Unlock();
1978 void foo15() {
1979 if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}}
1980 mu.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}}
1981 } // expected-warning{{mutex 'mu' is not held on every path through here}}
1982 }; // end TestTrylock
1984 } // end namespace TrylockTest
1987 namespace TestTemplateAttributeInstantiation {
1989 class Foo1 {
1990 public:
1991 Mutex mu_;
1992 int a GUARDED_BY(mu_);
1995 class Foo2 {
1996 public:
1997 int a GUARDED_BY(mu_);
1998 Mutex mu_;
2002 class Bar {
2003 public:
2004 // Test non-dependent expressions in attributes on template functions
2005 template <class T>
2006 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
2007 foo->a = 0;
2010 // Test dependent expressions in attributes on template functions
2011 template <class T>
2012 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
2013 fooT->a = 0;
2018 template <class T>
2019 class BarT {
2020 public:
2021 Foo1 fooBase;
2022 T fooBaseT;
2024 // Test non-dependent expression in ordinary method on template class
2025 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
2026 fooBase.a = 0;
2029 // Test dependent expressions in ordinary methods on template class
2030 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
2031 fooBaseT.a = 0;
2034 // Test dependent expressions in template method in template class
2035 template <class T2>
2036 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
2037 fooBaseT.a = 0;
2038 fooT->a = 0;
2042 template <class T>
2043 class Cell {
2044 public:
2045 Mutex mu_;
2046 // Test dependent guarded_by
2047 T data GUARDED_BY(mu_);
2049 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2050 data = 0;
2053 void foo() {
2054 mu_.Lock();
2055 data = 0;
2056 mu_.Unlock();
2060 void test() {
2061 Bar b;
2062 BarT<Foo2> bt;
2063 Foo1 f1;
2064 Foo2 f2;
2066 f1.mu_.Lock();
2067 f2.mu_.Lock();
2068 bt.fooBase.mu_.Lock();
2069 bt.fooBaseT.mu_.Lock();
2071 b.barND(&f1, &f2);
2072 b.barD(&f1, &f2);
2073 bt.barND();
2074 bt.barD();
2075 bt.barTD(&f2);
2077 f1.mu_.Unlock();
2078 bt.barTD(&f1); // \
2079 // expected-warning {{calling function 'barTD<TestTemplateAttributeInstantiation::Foo1>' requires holding mutex 'f1.mu_' exclusively}} \
2080 // expected-note {{found near match 'bt.fooBase.mu_'}}
2082 bt.fooBase.mu_.Unlock();
2083 bt.fooBaseT.mu_.Unlock();
2084 f2.mu_.Unlock();
2086 Cell<int> cell;
2087 cell.data = 0; // \
2088 // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
2089 cell.foo();
2090 cell.mu_.Lock();
2091 cell.fooEx();
2092 cell.mu_.Unlock();
2096 template <class T>
2097 class CellDelayed {
2098 public:
2099 // Test dependent guarded_by
2100 T data GUARDED_BY(mu_);
2101 static T static_data GUARDED_BY(static_mu_);
2103 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
2104 this->data = other->data;
2107 template <class T2>
2108 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
2109 this->data = otherT->data;
2112 void foo() {
2113 mu_.Lock();
2114 data = 0;
2115 mu_.Unlock();
2118 Mutex mu_;
2119 static Mutex static_mu_;
2122 void testDelayed() {
2123 CellDelayed<int> celld;
2124 CellDelayed<int> celld2;
2125 celld.foo();
2126 celld.mu_.Lock();
2127 celld2.mu_.Lock();
2129 celld.fooEx(&celld2);
2130 celld.fooExT(&celld2);
2132 celld2.mu_.Unlock();
2133 celld.mu_.Unlock();
2136 }; // end namespace TestTemplateAttributeInstantiation
2139 namespace FunctionDeclDefTest {
2141 class Foo {
2142 public:
2143 Mutex mu_;
2144 int a GUARDED_BY(mu_);
2146 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
2149 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
2150 void Foo::foo1(Foo *f_defined) {
2151 f_defined->a = 0;
2154 void test() {
2155 Foo myfoo;
2156 myfoo.foo1(&myfoo); // \
2157 // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2158 myfoo.mu_.Lock();
2159 myfoo.foo1(&myfoo);
2160 myfoo.mu_.Unlock();
2165 namespace GoingNative {
2167 struct LOCKABLE mutex {
2168 void lock() EXCLUSIVE_LOCK_FUNCTION();
2169 void unlock() UNLOCK_FUNCTION();
2170 // ...
2172 bool foo();
2173 bool bar();
2174 mutex m;
2175 void test() {
2176 m.lock();
2177 while (foo()) { // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
2178 m.unlock();
2179 // ...
2180 if (bar()) {
2181 // ...
2182 if (foo())
2183 continue;
2184 //...
2186 // ...
2187 m.lock(); // expected-note {{mutex acquired here}}
2189 m.unlock();
2196 namespace FunctionDefinitionTest {
2198 class Foo {
2199 public:
2200 void foo1();
2201 void foo2();
2202 void foo3(Foo *other);
2204 template<class T>
2205 void fooT1(const T& dummy1);
2207 template<class T>
2208 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2210 Mutex mu_;
2211 int a GUARDED_BY(mu_);
2214 template<class T>
2215 class FooT {
2216 public:
2217 void foo();
2219 Mutex mu_;
2220 T a GUARDED_BY(mu_);
2224 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2225 a = 1;
2228 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2229 a = 2;
2232 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2233 other->a = 3;
2236 template<class T>
2237 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2238 a = dummy1;
2241 /* TODO -- uncomment with template instantiation of attributes.
2242 template<class T>
2243 void Foo::fooT2(const T& dummy2) {
2244 a = dummy2;
2248 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2249 f->a = 1;
2252 void fooF2(Foo *f);
2253 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2254 f->a = 2;
2257 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2258 void fooF3(Foo *f) {
2259 f->a = 3;
2262 template<class T>
2263 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2264 a = 0;
2267 void test() {
2268 int dummy = 0;
2269 Foo myFoo;
2271 myFoo.foo2(); // \
2272 // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2273 myFoo.foo3(&myFoo); // \
2274 // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2275 myFoo.fooT1(dummy); // \
2276 // expected-warning {{calling function 'fooT1<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2278 myFoo.fooT2(dummy); // \
2279 // expected-warning {{calling function 'fooT2<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2281 fooF1(&myFoo); // \
2282 // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2283 fooF2(&myFoo); // \
2284 // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2285 fooF3(&myFoo); // \
2286 // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2288 myFoo.mu_.Lock();
2289 myFoo.foo2();
2290 myFoo.foo3(&myFoo);
2291 myFoo.fooT1(dummy);
2293 myFoo.fooT2(dummy);
2295 fooF1(&myFoo);
2296 fooF2(&myFoo);
2297 fooF3(&myFoo);
2298 myFoo.mu_.Unlock();
2300 FooT<int> myFooT;
2301 myFooT.foo(); // \
2302 // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2305 } // end namespace FunctionDefinitionTest
2308 namespace SelfLockingTest {
2310 class LOCKABLE MyLock {
2311 public:
2312 int foo GUARDED_BY(this);
2314 void lock() EXCLUSIVE_LOCK_FUNCTION();
2315 void unlock() UNLOCK_FUNCTION();
2317 void doSomething() {
2318 this->lock(); // allow 'this' as a lock expression
2319 foo = 0;
2320 doSomethingElse();
2321 this->unlock();
2324 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2325 foo = 1;
2328 void test() {
2329 foo = 2; // \
2330 // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
2335 class LOCKABLE MyLock2 {
2336 public:
2337 Mutex mu_;
2338 int foo GUARDED_BY(this);
2340 // don't check inside lock and unlock functions
2341 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
2342 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
2344 // don't check inside constructors and destructors
2345 MyLock2() { foo = 1; }
2346 ~MyLock2() { foo = 0; }
2350 } // end namespace SelfLockingTest
2353 namespace InvalidNonstatic {
2355 // Forward decl here causes bogus "invalid use of non-static data member"
2356 // on reference to mutex_ in guarded_by attribute.
2357 class Foo;
2359 class Foo {
2360 Mutex* mutex_;
2362 int foo __attribute__((guarded_by(mutex_)));
2365 } // end namespace InvalidNonStatic
2368 namespace NoReturnTest {
2370 bool condition();
2371 void fatal() __attribute__((noreturn));
2373 Mutex mu_;
2375 void test1() {
2376 MutexLock lock(&mu_);
2377 if (condition()) {
2378 fatal();
2379 return;
2383 } // end namespace NoReturnTest
2386 namespace TestMultiDecl {
2388 class Foo {
2389 public:
2390 int GUARDED_BY(mu_) a;
2391 int GUARDED_BY(mu_) b, c;
2393 void foo() {
2394 a = 0; // \
2395 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2396 b = 0; // \
2397 // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2398 c = 0; // \
2399 // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2402 private:
2403 Mutex mu_;
2406 } // end namespace TestMultiDecl
2409 namespace WarnNoDecl {
2411 class Foo {
2412 void foo(int a); __attribute__(( // \
2413 // expected-warning {{declaration does not declare anything}}
2414 exclusive_locks_required(a))); // \
2415 // expected-warning {{attribute exclusive_locks_required ignored}}
2418 } // end namespace WarnNoDecl
2422 namespace MoreLockExpressions {
2424 class Foo {
2425 public:
2426 Mutex mu_;
2427 int a GUARDED_BY(mu_);
2430 class Bar {
2431 public:
2432 int b;
2433 Foo* f;
2435 Foo& getFoo() { return *f; }
2436 Foo& getFoo2(int c) { return *f; }
2437 Foo& getFoo3(int c, int d) { return *f; }
2439 Foo& getFooey() { return *f; }
2442 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
2444 void test() {
2445 Foo foo;
2446 Foo *fooArray;
2447 Foo &(*fooFuncPtr)();
2448 Bar bar;
2449 int a;
2450 int b;
2451 int c;
2453 bar.getFoo().mu_.Lock();
2454 bar.getFoo().a = 0;
2455 bar.getFoo().mu_.Unlock();
2457 (bar.getFoo().mu_).Lock(); // test parenthesis
2458 bar.getFoo().a = 0;
2459 (bar.getFoo().mu_).Unlock();
2461 bar.getFoo2(a).mu_.Lock();
2462 bar.getFoo2(a).a = 0;
2463 bar.getFoo2(a).mu_.Unlock();
2465 bar.getFoo3(a, b).mu_.Lock();
2466 bar.getFoo3(a, b).a = 0;
2467 bar.getFoo3(a, b).mu_.Unlock();
2469 getBarFoo(bar, a).mu_.Lock();
2470 getBarFoo(bar, a).a = 0;
2471 getBarFoo(bar, a).mu_.Unlock();
2473 bar.getFoo2(10).mu_.Lock();
2474 bar.getFoo2(10).a = 0;
2475 bar.getFoo2(10).mu_.Unlock();
2477 bar.getFoo2(a + 1).mu_.Lock();
2478 bar.getFoo2(a + 1).a = 0;
2479 bar.getFoo2(a + 1).mu_.Unlock();
2481 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2482 (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
2483 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2485 fooFuncPtr().mu_.Lock();
2486 fooFuncPtr().a = 0;
2487 fooFuncPtr().mu_.Unlock();
2491 void test2() {
2492 Foo *fooArray;
2493 Bar bar;
2494 int a;
2495 int b;
2496 int c;
2498 bar.getFoo().mu_.Lock();
2499 bar.getFooey().a = 0; // \
2500 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
2501 // expected-note {{found near match 'bar.getFoo().mu_'}}
2502 bar.getFoo().mu_.Unlock();
2504 bar.getFoo2(a).mu_.Lock();
2505 bar.getFoo2(b).a = 0; // \
2506 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
2507 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2508 bar.getFoo2(a).mu_.Unlock();
2510 bar.getFoo3(a, b).mu_.Lock();
2511 bar.getFoo3(a, c).a = 0; // \
2512 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \
2513 // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}
2514 bar.getFoo3(a, b).mu_.Unlock();
2516 getBarFoo(bar, a).mu_.Lock();
2517 getBarFoo(bar, b).a = 0; // \
2518 // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \
2519 // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}
2520 getBarFoo(bar, a).mu_.Unlock();
2522 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2523 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2524 // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \
2525 // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}
2526 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2530 } // end namespace MoreLockExpressions
2533 namespace TrylockJoinPoint {
2535 class Foo {
2536 Mutex mu;
2537 bool c;
2539 void foo() {
2540 if (c) {
2541 if (!mu.TryLock())
2542 return;
2543 } else {
2544 mu.Lock();
2546 mu.Unlock();
2550 } // end namespace TrylockJoinPoint
2553 namespace LockReturned {
2555 class Foo {
2556 public:
2557 int a GUARDED_BY(mu_);
2558 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2559 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2561 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2563 Mutex* getMu() LOCK_RETURNED(mu_);
2565 Mutex mu_;
2567 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2571 // Calls getMu() directly to lock and unlock
2572 void test1(Foo* f1, Foo* f2) {
2573 f1->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2574 f1->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2576 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2577 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2578 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2580 f1->getMu()->Lock();
2582 f1->a = 0;
2583 f1->foo();
2584 f1->foo2(f2); // \
2585 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
2586 // expected-note {{found near match 'f1->mu_'}}
2588 Foo::getMu(f2)->Lock();
2589 f1->foo2(f2);
2590 Foo::getMu(f2)->Unlock();
2592 Foo::sfoo(f1);
2594 f1->getMu()->Unlock();
2598 Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2600 class Bar : public Foo {
2601 public:
2602 int b GUARDED_BY(getMu());
2603 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2604 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2606 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2607 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2612 // Use getMu() within other attributes.
2613 // This requires at lest levels of substitution, more in the case of
2614 void test2(Bar* b1, Bar* b2) {
2615 b1->b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2616 b1->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2617 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2618 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2619 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2620 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2622 b1->getMu()->Lock();
2624 b1->b = 0;
2625 b1->bar();
2626 b1->bar2(b2); // \
2627 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
2628 // // expected-note {{found near match 'b1->mu_'}}
2630 b2->getMu()->Lock();
2631 b1->bar2(b2);
2633 b2->getMu()->Unlock();
2635 Bar::sbar(b1);
2636 Bar::sbar2(b1);
2638 b1->getMu()->Unlock();
2642 // Lock the mutex directly, but use attributes that call getMu()
2643 // Also lock the mutex using getFooMu, which calls a lock_returned function.
2644 void test3(Bar* b1, Bar* b2) {
2645 b1->mu_.Lock();
2646 b1->b = 0;
2647 b1->bar();
2649 getFooMu(b2)->Lock();
2650 b1->bar2(b2);
2651 getFooMu(b2)->Unlock();
2653 Bar::sbar(b1);
2654 Bar::sbar2(b1);
2656 b1->mu_.Unlock();
2659 } // end namespace LockReturned
2662 namespace ReleasableScopedLock {
2664 class Foo {
2665 Mutex mu_;
2666 bool c;
2667 int a GUARDED_BY(mu_);
2669 void test1();
2670 void test2();
2671 void test3();
2672 void test4();
2673 void test5();
2674 void test6();
2678 void Foo::test1() {
2679 ReleasableMutexLock rlock(&mu_);
2680 rlock.Release();
2683 void Foo::test2() {
2684 ReleasableMutexLock rlock(&mu_);
2685 if (c) { // test join point -- held/not held during release
2686 rlock.Release();
2688 // No warning on join point because the lock will be released by the scope object anyway.
2691 void Foo::test3() {
2692 ReleasableMutexLock rlock(&mu_);
2693 a = 0;
2694 rlock.Release();
2695 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2698 void Foo::test4() {
2699 ReleasableMutexLock rlock(&mu_);
2700 rlock.Release(); // expected-note{{mutex released here}}
2701 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2704 void Foo::test5() {
2705 ReleasableMutexLock rlock(&mu_);
2706 if (c) {
2707 rlock.Release();
2709 // No warning on join point because the lock will be released by the scope object anyway.
2710 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2713 void Foo::test6() {
2714 ReleasableMutexLock rlock(&mu_);
2715 do {
2716 if (c) {
2717 rlock.Release();
2718 break;
2720 } while (c);
2721 // No warning on join point because the lock will be released by the scope object anyway
2722 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2726 } // end namespace ReleasableScopedLock
2729 namespace RelockableScopedLock {
2731 class DeferTraits {};
2733 class SCOPED_LOCKABLE RelockableExclusiveMutexLock {
2734 public:
2735 RelockableExclusiveMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2736 RelockableExclusiveMutexLock(Mutex *mu, DeferTraits) LOCKS_EXCLUDED(mu);
2737 ~RelockableExclusiveMutexLock() EXCLUSIVE_UNLOCK_FUNCTION();
2739 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2740 void Unlock() UNLOCK_FUNCTION();
2743 struct SharedTraits {};
2744 struct ExclusiveTraits {};
2746 class SCOPED_LOCKABLE RelockableMutexLock {
2747 public:
2748 RelockableMutexLock(Mutex *mu, DeferTraits) LOCKS_EXCLUDED(mu);
2749 RelockableMutexLock(Mutex *mu, SharedTraits) SHARED_LOCK_FUNCTION(mu);
2750 RelockableMutexLock(Mutex *mu, ExclusiveTraits) EXCLUSIVE_LOCK_FUNCTION(mu);
2751 ~RelockableMutexLock() UNLOCK_FUNCTION();
2753 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2754 void Unlock() UNLOCK_FUNCTION();
2756 void ReaderLock() SHARED_LOCK_FUNCTION();
2757 void ReaderUnlock() UNLOCK_FUNCTION();
2759 void PromoteShared() UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();
2760 void DemoteExclusive() UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();
2763 Mutex mu;
2764 int x GUARDED_BY(mu);
2765 bool b;
2767 void print(int);
2769 void relock() {
2770 RelockableExclusiveMutexLock scope(&mu);
2771 x = 2;
2772 scope.Unlock();
2774 x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2776 scope.Lock();
2777 x = 4;
2780 void deferLock() {
2781 RelockableExclusiveMutexLock scope(&mu, DeferTraits{});
2782 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2783 scope.Lock();
2784 x = 3;
2787 void relockExclusive() {
2788 RelockableMutexLock scope(&mu, SharedTraits{});
2789 print(x);
2790 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2791 scope.ReaderUnlock();
2793 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2795 scope.Lock();
2796 print(x);
2797 x = 4;
2799 scope.DemoteExclusive();
2800 print(x);
2801 x = 5; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2804 void relockShared() {
2805 RelockableMutexLock scope(&mu, ExclusiveTraits{});
2806 print(x);
2807 x = 2;
2808 scope.Unlock();
2810 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2812 scope.ReaderLock();
2813 print(x);
2814 x = 4; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2816 scope.PromoteShared();
2817 print(x);
2818 x = 5;
2821 void deferLockShared() {
2822 RelockableMutexLock scope(&mu, DeferTraits{});
2823 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2824 scope.ReaderLock();
2825 print(x);
2826 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2829 void doubleUnlock() {
2830 RelockableExclusiveMutexLock scope(&mu);
2831 scope.Unlock(); // expected-note{{mutex released here}}
2832 scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
2835 void doubleLock1() {
2836 RelockableExclusiveMutexLock scope(&mu); // expected-note{{mutex acquired here}}
2837 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2840 void doubleLock2() {
2841 RelockableExclusiveMutexLock scope(&mu);
2842 scope.Unlock();
2843 scope.Lock(); // expected-note{{mutex acquired here}}
2844 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2847 void lockJoin() {
2848 RelockableMutexLock scope(&mu, DeferTraits{});
2849 if (b)
2850 scope.Lock();
2851 // No warning on join point because the lock will be released by the scope object anyway.
2852 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2855 void unlockJoin() {
2856 RelockableMutexLock scope(&mu, DeferTraits{});
2857 scope.Lock();
2858 if (b)
2859 scope.Unlock();
2860 // No warning on join point because the lock will be released by the scope object anyway.
2861 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2864 void loopAcquire() {
2865 RelockableMutexLock scope(&mu, DeferTraits{});
2866 for (unsigned i = 1; i < 10; ++i)
2867 scope.Lock(); // We could catch this double lock with negative capabilities.
2870 void loopRelease() {
2871 RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{mutex acquired here}}
2872 // We have to warn on this join point despite the lock being managed ...
2873 for (unsigned i = 1; i < 10; ++i) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}
2874 x = 1; // ... because we might miss that this doesn't always happen under lock.
2875 if (i == 5)
2876 scope.Unlock();
2880 void loopPromote() {
2881 RelockableMutexLock scope(&mu, SharedTraits{});
2882 for (unsigned i = 1; i < 10; ++i) {
2883 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2884 if (i == 5)
2885 scope.PromoteShared();
2889 void loopDemote() {
2890 RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{the other acquisition of mutex 'mu' is here}}
2891 // We have to warn on this join point despite the lock being managed ...
2892 for (unsigned i = 1; i < 10; ++i) {
2893 x = 1; // ... because we might miss that this doesn't always happen under exclusive lock.
2894 if (i == 5)
2895 scope.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}
2899 void loopAcquireContinue() {
2900 RelockableMutexLock scope(&mu, DeferTraits{});
2901 for (unsigned i = 1; i < 10; ++i) {
2902 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2903 if (i == 5) {
2904 scope.Lock();
2905 continue;
2910 void loopReleaseContinue() {
2911 RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{mutex acquired here}}
2912 // We have to warn on this join point despite the lock being managed ...
2913 for (unsigned i = 1; i < 10; ++i) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}
2914 x = 1; // ... because we might miss that this doesn't always happen under lock.
2915 if (i == 5) {
2916 scope.Unlock();
2917 continue;
2922 void loopPromoteContinue() {
2923 RelockableMutexLock scope(&mu, SharedTraits{});
2924 for (unsigned i = 1; i < 10; ++i) {
2925 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2926 if (i == 5) {
2927 scope.PromoteShared();
2928 continue;
2933 void loopDemoteContinue() {
2934 RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{the other acquisition of mutex 'mu' is here}}
2935 // We have to warn on this join point despite the lock being managed ...
2936 for (unsigned i = 1; i < 10; ++i) {
2937 x = 1; // ... because we might miss that this doesn't always happen under exclusive lock.
2938 if (i == 5) {
2939 scope.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}
2940 continue;
2945 void exclusiveSharedJoin() {
2946 RelockableMutexLock scope(&mu, DeferTraits{});
2947 if (b)
2948 scope.Lock();
2949 else
2950 scope.ReaderLock();
2951 // No warning on join point because the lock will be released by the scope object anyway.
2952 print(x);
2953 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2956 void sharedExclusiveJoin() {
2957 RelockableMutexLock scope(&mu, DeferTraits{});
2958 if (b)
2959 scope.ReaderLock();
2960 else
2961 scope.Lock();
2962 // No warning on join point because the lock will be released by the scope object anyway.
2963 print(x);
2964 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2967 void assertJoin() {
2968 RelockableMutexLock scope(&mu, DeferTraits{});
2969 if (b)
2970 scope.Lock();
2971 else
2972 mu.AssertHeld();
2973 x = 2;
2976 void assertSharedJoin() {
2977 RelockableMutexLock scope(&mu, DeferTraits{});
2978 if (b)
2979 scope.ReaderLock();
2980 else
2981 mu.AssertReaderHeld();
2982 print(x);
2983 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2986 void assertStrongerJoin() {
2987 RelockableMutexLock scope(&mu, DeferTraits{});
2988 if (b)
2989 scope.ReaderLock();
2990 else
2991 mu.AssertHeld();
2992 print(x);
2993 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2996 void assertWeakerJoin() {
2997 RelockableMutexLock scope(&mu, DeferTraits{});
2998 if (b)
2999 scope.Lock();
3000 else
3001 mu.AssertReaderHeld();
3002 print(x);
3003 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3006 void directUnlock() {
3007 RelockableExclusiveMutexLock scope(&mu);
3008 mu.Unlock();
3009 // Debatable that there is no warning. Currently we don't track in the scoped
3010 // object whether it is active, but just check if the contained locks can be
3011 // reacquired. Here they can, because mu has been unlocked manually.
3012 scope.Lock();
3015 void directRelock() {
3016 RelockableExclusiveMutexLock scope(&mu);
3017 scope.Unlock();
3018 mu.Lock();
3019 // Similarly debatable that there is no warning.
3020 scope.Unlock();
3023 // Doesn't make a lot of sense, just making sure there is no crash.
3024 void destructLock() {
3025 RelockableExclusiveMutexLock scope(&mu);
3026 scope.~RelockableExclusiveMutexLock();
3027 scope.Lock(); // Should be UB, so we don't really care.
3030 class SCOPED_LOCKABLE MemberLock {
3031 public:
3032 MemberLock() EXCLUSIVE_LOCK_FUNCTION(mutex);
3033 ~MemberLock() UNLOCK_FUNCTION(mutex);
3034 void Lock() EXCLUSIVE_LOCK_FUNCTION(mutex);
3035 Mutex mutex;
3038 void relockShared2() {
3039 MemberLock lock; // expected-note{{mutex acquired here}}
3040 lock.Lock(); // expected-warning {{acquiring mutex 'lock.mutex' that is already held}}
3043 class SCOPED_LOCKABLE WeirdScope {
3044 private:
3045 Mutex *other;
3047 public:
3048 WeirdScope(Mutex *mutex) EXCLUSIVE_LOCK_FUNCTION(mutex);
3049 void unlock() EXCLUSIVE_UNLOCK_FUNCTION() EXCLUSIVE_UNLOCK_FUNCTION(other);
3050 void lock() EXCLUSIVE_LOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION(other);
3051 ~WeirdScope() EXCLUSIVE_UNLOCK_FUNCTION();
3053 void requireOther() EXCLUSIVE_LOCKS_REQUIRED(other);
3056 void relockWeird() {
3057 WeirdScope scope(&mu);
3058 x = 1;
3059 scope.unlock(); // expected-warning {{releasing mutex 'scope.other' that was not held}}
3060 x = 2; // \
3061 // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3062 scope.requireOther(); // \
3063 // expected-warning {{calling function 'requireOther' requires holding mutex 'scope.other' exclusively}}
3064 scope.lock(); // expected-note {{mutex acquired here}}
3065 x = 3;
3066 scope.requireOther();
3067 } // expected-warning {{mutex 'scope.other' is still held at the end of function}}
3069 } // end namespace RelockableScopedLock
3072 namespace ScopedUnlock {
3074 class SCOPED_LOCKABLE MutexUnlock {
3075 public:
3076 MutexUnlock(Mutex *mu) EXCLUSIVE_UNLOCK_FUNCTION(mu);
3077 ~MutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3079 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
3080 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
3083 class SCOPED_LOCKABLE ReaderMutexUnlock {
3084 public:
3085 ReaderMutexUnlock(Mutex *mu) SHARED_UNLOCK_FUNCTION(mu);
3086 ~ReaderMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3088 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
3089 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
3092 Mutex mu;
3093 int x GUARDED_BY(mu);
3094 bool c;
3095 void print(int);
3097 void simple() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3098 x = 1;
3099 MutexUnlock scope(&mu);
3100 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3103 void simpleShared() SHARED_LOCKS_REQUIRED(mu) {
3104 print(x);
3105 ReaderMutexUnlock scope(&mu);
3106 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3109 void innerUnlock() {
3110 MutexLock outer(&mu);
3111 if (x == 0) {
3112 MutexUnlock inner(&mu);
3113 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3115 x = 2;
3118 void innerUnlockShared() {
3119 ReaderMutexLock outer(&mu);
3120 if (x == 0) {
3121 ReaderMutexUnlock inner(&mu);
3122 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3124 print(x);
3127 void manual() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3128 MutexUnlock scope(&mu);
3129 scope.Lock();
3130 x = 2;
3131 scope.Unlock();
3132 x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3135 void join() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3136 MutexUnlock scope(&mu);
3137 if (c)
3138 scope.Lock();
3139 // No warning on join point because the lock will be released by the scope object anyway.
3140 scope.Lock();
3143 void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3144 MutexUnlock scope(&mu);
3145 scope.Lock(); // expected-note{{mutex acquired here}}
3146 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
3149 void doubleUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3150 MutexUnlock scope(&mu); // expected-note{{mutex released here}}
3151 scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
3154 class SCOPED_LOCKABLE MutexLockUnlock {
3155 public:
3156 MutexLockUnlock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_UNLOCK_FUNCTION(mu1) EXCLUSIVE_LOCK_FUNCTION(mu2);
3157 ~MutexLockUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3159 void Release() EXCLUSIVE_UNLOCK_FUNCTION();
3160 void Acquire() EXCLUSIVE_LOCK_FUNCTION();
3163 Mutex other;
3164 void fn() EXCLUSIVE_LOCKS_REQUIRED(other);
3166 void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
3167 MutexLockUnlock scope(&mu, &other);
3168 fn();
3169 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3172 } // end namespace ScopedUnlock
3175 namespace TrylockFunctionTest {
3177 class Foo {
3178 public:
3179 Mutex mu1_;
3180 Mutex mu2_;
3181 bool c;
3183 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
3186 bool Foo::lockBoth() {
3187 if (!mu1_.TryLock())
3188 return false;
3190 mu2_.Lock();
3191 if (!c) {
3192 mu1_.Unlock();
3193 mu2_.Unlock();
3194 return false;
3197 return true;
3201 } // end namespace TrylockFunctionTest
3205 namespace DoubleLockBug {
3207 class Foo {
3208 public:
3209 Mutex mu_;
3210 int a GUARDED_BY(mu_);
3212 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3213 int foo2() SHARED_LOCKS_REQUIRED(mu_);
3217 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
3218 a = 0;
3221 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
3222 return a;
3229 namespace UnlockBug {
3231 class Foo {
3232 public:
3233 Mutex mutex_;
3235 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
3236 mutex_.Unlock();
3237 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
3240 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
3241 mutex_.Unlock();
3242 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
3245 } // end namespace UnlockBug
3249 namespace FoolishScopedLockableBug {
3251 class SCOPED_LOCKABLE WTF_ScopedLockable {
3252 public:
3253 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
3255 // have to call release() manually;
3256 ~WTF_ScopedLockable();
3258 void release() UNLOCK_FUNCTION();
3262 class Foo {
3263 Mutex mu_;
3264 int a GUARDED_BY(mu_);
3265 bool c;
3267 void doSomething();
3269 void test1() {
3270 WTF_ScopedLockable wtf(&mu_);
3271 wtf.release();
3274 void test2() {
3275 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
3276 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
3278 void test3() {
3279 if (c) {
3280 WTF_ScopedLockable wtf(&mu_);
3281 wtf.release();
3285 void test4() {
3286 if (c) {
3287 doSomething();
3289 else {
3290 WTF_ScopedLockable wtf(&mu_);
3291 wtf.release();
3295 void test5() {
3296 if (c) {
3297 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
3299 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3301 void test6() {
3302 if (c) {
3303 doSomething();
3305 else {
3306 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
3308 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3312 } // end namespace FoolishScopedLockableBug
3316 namespace TemporaryCleanupExpr {
3318 class Foo {
3319 int a GUARDED_BY(getMutexPtr().get());
3321 SmartPtr<Mutex> getMutexPtr();
3323 void test();
3327 void Foo::test() {
3329 ReaderMutexLock lock(getMutexPtr().get());
3330 int b = a;
3332 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
3335 #ifdef __cpp_guaranteed_copy_elision
3337 void guaranteed_copy_elision() {
3338 MutexLock lock = MutexLock{&sls_mu};
3339 sls_guard_var = 0;
3342 void guaranteed_copy_elision_const() {
3343 const MutexLock lock = MutexLock{&sls_mu};
3344 sls_guard_var = 0;
3347 #endif
3349 } // end namespace TemporaryCleanupExpr
3353 namespace SmartPointerTests {
3355 class Foo {
3356 public:
3357 SmartPtr<Mutex> mu_;
3358 int a GUARDED_BY(mu_);
3359 int b GUARDED_BY(mu_.get());
3360 int c GUARDED_BY(*mu_);
3362 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3363 void Unlock() UNLOCK_FUNCTION(mu_);
3365 void test0();
3366 void test1();
3367 void test2();
3368 void test3();
3369 void test4();
3370 void test5();
3371 void test6();
3372 void test7();
3373 void test8();
3376 void Foo::test0() {
3377 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3378 b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
3379 c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
3382 void Foo::test1() {
3383 mu_->Lock();
3384 a = 0;
3385 b = 0;
3386 c = 0;
3387 mu_->Unlock();
3390 void Foo::test2() {
3391 (*mu_).Lock();
3392 a = 0;
3393 b = 0;
3394 c = 0;
3395 (*mu_).Unlock();
3399 void Foo::test3() {
3400 mu_.get()->Lock();
3401 a = 0;
3402 b = 0;
3403 c = 0;
3404 mu_.get()->Unlock();
3408 void Foo::test4() {
3409 MutexLock lock(mu_.get());
3410 a = 0;
3411 b = 0;
3412 c = 0;
3416 void Foo::test5() {
3417 MutexLock lock(&(*mu_));
3418 a = 0;
3419 b = 0;
3420 c = 0;
3424 void Foo::test6() {
3425 Lock();
3426 a = 0;
3427 b = 0;
3428 c = 0;
3429 Unlock();
3433 void Foo::test7() {
3435 Lock();
3436 mu_->Unlock();
3439 mu_->Lock();
3440 Unlock();
3443 mu_.get()->Lock();
3444 mu_->Unlock();
3447 mu_->Lock();
3448 mu_.get()->Unlock();
3451 mu_.get()->Lock();
3452 (*mu_).Unlock();
3455 (*mu_).Lock();
3456 mu_->Unlock();
3461 void Foo::test8() {
3462 mu_->Lock(); // expected-note 2 {{mutex acquired here}}
3463 mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3464 (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3465 mu_.get()->Unlock(); // expected-note {{mutex released here}}
3466 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
3470 class Bar {
3471 SmartPtr<Foo> foo;
3473 void test0();
3474 void test1();
3475 void test2();
3476 void test3();
3480 void Bar::test0() {
3481 foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
3482 (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
3483 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
3487 void Bar::test1() {
3488 foo->mu_->Lock();
3489 foo->a = 0;
3490 (*foo).b = 0;
3491 foo.get()->c = 0;
3492 foo->mu_->Unlock();
3496 void Bar::test2() {
3497 (*foo).mu_->Lock();
3498 foo->a = 0;
3499 (*foo).b = 0;
3500 foo.get()->c = 0;
3501 foo.get()->mu_->Unlock();
3505 void Bar::test3() {
3506 MutexLock lock(foo->mu_.get());
3507 foo->a = 0;
3508 (*foo).b = 0;
3509 foo.get()->c = 0;
3512 } // end namespace SmartPointerTests
3516 namespace DuplicateAttributeTest {
3518 class LOCKABLE Foo {
3519 public:
3520 Mutex mu1_;
3521 Mutex mu2_;
3522 Mutex mu3_;
3523 int a GUARDED_BY(mu1_);
3524 int b GUARDED_BY(mu2_);
3525 int c GUARDED_BY(mu3_);
3527 void lock() EXCLUSIVE_LOCK_FUNCTION();
3528 void unlock() UNLOCK_FUNCTION();
3530 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
3531 void slock1() SHARED_LOCK_FUNCTION(mu1_);
3532 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3533 void locklots()
3534 EXCLUSIVE_LOCK_FUNCTION(mu1_)
3535 EXCLUSIVE_LOCK_FUNCTION(mu2_)
3536 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3538 void unlock1() UNLOCK_FUNCTION(mu1_);
3539 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3540 void unlocklots()
3541 UNLOCK_FUNCTION(mu1_)
3542 UNLOCK_FUNCTION(mu2_)
3543 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3547 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
3548 void Foo::unlock() UNLOCK_FUNCTION() { }
3550 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
3551 mu1_.Lock();
3554 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
3555 mu1_.ReaderLock();
3558 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
3559 mu1_.Lock();
3560 mu2_.Lock();
3561 mu3_.Lock();
3564 void Foo::locklots()
3565 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
3566 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
3567 mu1_.Lock();
3568 mu2_.Lock();
3569 mu3_.Lock();
3572 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
3573 mu1_.Unlock();
3576 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
3577 mu1_.Unlock();
3578 mu2_.Unlock();
3579 mu3_.Unlock();
3582 void Foo::unlocklots()
3583 UNLOCK_FUNCTION(mu1_, mu2_)
3584 UNLOCK_FUNCTION(mu2_, mu3_) {
3585 mu1_.Unlock();
3586 mu2_.Unlock();
3587 mu3_.Unlock();
3591 void test0() {
3592 Foo foo;
3593 foo.lock();
3594 foo.unlock();
3596 foo.lock(); // expected-note{{mutex acquired here}}
3597 foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
3598 foo.unlock(); // expected-note{{mutex released here}}
3599 foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
3603 void test1() {
3604 Foo foo;
3605 foo.lock1();
3606 foo.a = 0;
3607 foo.unlock1();
3609 foo.lock1(); // expected-note{{mutex acquired here}}
3610 foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3611 foo.a = 0;
3612 foo.unlock1(); // expected-note{{mutex released here}}
3613 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3617 int test2() {
3618 Foo foo;
3619 foo.slock1();
3620 int d1 = foo.a;
3621 foo.unlock1();
3623 foo.slock1(); // expected-note{{mutex acquired here}}
3624 foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3625 int d2 = foo.a;
3626 foo.unlock1(); // expected-note{{mutex released here}}
3627 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3628 return d1 + d2;
3632 void test3() {
3633 Foo foo;
3634 foo.lock3();
3635 foo.a = 0;
3636 foo.b = 0;
3637 foo.c = 0;
3638 foo.unlock3();
3640 foo.lock3(); // expected-note 3 {{mutex acquired here}}
3641 foo.lock3(); // \
3642 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3643 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3644 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3645 foo.a = 0;
3646 foo.b = 0;
3647 foo.c = 0;
3648 foo.unlock3(); // expected-note 3 {{mutex released here}}
3649 foo.unlock3(); // \
3650 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3651 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3652 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3656 void testlots() {
3657 Foo foo;
3658 foo.locklots();
3659 foo.a = 0;
3660 foo.b = 0;
3661 foo.c = 0;
3662 foo.unlocklots();
3664 foo.locklots(); // expected-note 3 {{mutex acquired here}}
3665 foo.locklots(); // \
3666 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3667 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3668 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3669 foo.a = 0;
3670 foo.b = 0;
3671 foo.c = 0;
3672 foo.unlocklots(); // expected-note 3 {{mutex released here}}
3673 foo.unlocklots(); // \
3674 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3675 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3676 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3679 } // end namespace DuplicateAttributeTest
3683 namespace TryLockEqTest {
3685 class Foo {
3686 Mutex mu_;
3687 int a GUARDED_BY(mu_);
3688 bool c;
3690 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3691 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3692 void unlock() UNLOCK_FUNCTION(mu_);
3694 void test1();
3695 void test2();
3699 void Foo::test1() {
3700 if (tryLockMutexP() == 0) {
3701 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3702 return;
3704 a = 0;
3705 unlock();
3707 if (tryLockMutexP() != 0) {
3708 a = 0;
3709 unlock();
3712 if (0 != tryLockMutexP()) {
3713 a = 0;
3714 unlock();
3717 if (!(tryLockMutexP() == 0)) {
3718 a = 0;
3719 unlock();
3722 if (tryLockMutexI() == 0) {
3723 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3724 return;
3726 a = 0;
3727 unlock();
3729 if (0 == tryLockMutexI()) {
3730 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3731 return;
3733 a = 0;
3734 unlock();
3736 if (tryLockMutexI() == 1) {
3737 a = 0;
3738 unlock();
3741 if (mu_.TryLock() == false) {
3742 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3743 return;
3745 a = 0;
3746 unlock();
3748 if (mu_.TryLock() == true) {
3749 a = 0;
3750 unlock();
3752 else {
3753 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3756 #if __has_feature(cxx_nullptr)
3757 if (tryLockMutexP() == nullptr) {
3758 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3759 return;
3761 a = 0;
3762 unlock();
3763 #endif
3766 } // end namespace TryLockEqTest
3769 namespace ExistentialPatternMatching {
3771 class Graph {
3772 public:
3773 Mutex mu_;
3776 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3777 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3779 class Node {
3780 public:
3781 int a GUARDED_BY(&Graph::mu_);
3783 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3784 a = 0;
3786 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3789 void test() {
3790 Graph g1;
3791 Graph g2;
3792 Node n1;
3794 n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3795 n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3796 n1.foo2();
3798 g1.mu_.Lock();
3799 n1.a = 0;
3800 n1.foo();
3801 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3802 g1.mu_.Unlock();
3804 g2.mu_.Lock();
3805 n1.a = 0;
3806 n1.foo();
3807 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3808 g2.mu_.Unlock();
3810 LockAllGraphs();
3811 n1.a = 0;
3812 n1.foo();
3813 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3814 UnlockAllGraphs();
3816 LockAllGraphs();
3817 g1.mu_.Unlock();
3819 LockAllGraphs();
3820 g2.mu_.Unlock();
3822 LockAllGraphs(); // expected-note{{mutex acquired here}}
3823 g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3824 g1.mu_.Unlock();
3827 } // end namespace ExistentialPatternMatching
3830 namespace StringIgnoreTest {
3832 class Foo {
3833 public:
3834 Mutex mu_;
3835 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3836 void unlock() UNLOCK_FUNCTION("");
3837 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3838 void roober() SHARED_LOCKS_REQUIRED("");
3842 class Bar : public Foo {
3843 public:
3844 void bar(Foo* f) {
3845 f->unlock();
3846 f->goober();
3847 f->roober();
3848 f->lock();
3852 } // end namespace StringIgnoreTest
3855 namespace LockReturnedScopeFix {
3857 class Base {
3858 protected:
3859 struct Inner;
3860 bool c;
3862 const Mutex& getLock(const Inner* i);
3864 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3865 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3866 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3868 void bar(Inner* i);
3872 struct Base::Inner {
3873 Mutex lock_;
3874 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3878 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3879 return i->lock_;
3883 void Base::foo(Inner* i) {
3884 i->doSomething();
3887 void Base::bar(Inner* i) {
3888 if (c) {
3889 i->lock_.Lock();
3890 unlockInner(i);
3892 else {
3893 lockInner(i);
3894 i->lock_.Unlock();
3898 } // end namespace LockReturnedScopeFix
3901 namespace TrylockWithCleanups {
3903 struct Foo {
3904 Mutex mu_;
3905 int a GUARDED_BY(mu_);
3908 Foo* GetAndLockFoo(const MyString& s)
3909 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3911 static void test() {
3912 Foo* lt = GetAndLockFoo("foo");
3913 if (!lt) return;
3914 int a = lt->a;
3915 lt->mu_.Unlock();
3918 } // end namespace TrylockWithCleanups
3921 namespace UniversalLock {
3923 class Foo {
3924 Mutex mu_;
3925 bool c;
3927 int a GUARDED_BY(mu_);
3928 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3929 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3931 void test1() {
3932 int b;
3934 beginNoWarnOnReads();
3935 b = a;
3936 r_foo();
3937 endNoWarnOnReads();
3939 beginNoWarnOnWrites();
3940 a = 0;
3941 w_foo();
3942 endNoWarnOnWrites();
3945 // don't warn on joins with universal lock
3946 void test2() {
3947 if (c) {
3948 beginNoWarnOnWrites();
3950 a = 0; // \
3951 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3952 endNoWarnOnWrites(); // \
3953 // expected-warning {{releasing wildcard '*' that was not held}}
3957 // make sure the universal lock joins properly
3958 void test3() {
3959 if (c) {
3960 mu_.Lock();
3961 beginNoWarnOnWrites();
3963 else {
3964 beginNoWarnOnWrites();
3965 mu_.Lock();
3967 a = 0;
3968 endNoWarnOnWrites();
3969 mu_.Unlock();
3973 // combine universal lock with other locks
3974 void test4() {
3975 beginNoWarnOnWrites();
3976 mu_.Lock();
3977 mu_.Unlock();
3978 endNoWarnOnWrites();
3980 mu_.Lock();
3981 beginNoWarnOnWrites();
3982 endNoWarnOnWrites();
3983 mu_.Unlock();
3985 mu_.Lock();
3986 beginNoWarnOnWrites();
3987 mu_.Unlock();
3988 endNoWarnOnWrites();
3992 } // end namespace UniversalLock
3995 namespace TemplateLockReturned {
3997 template<class T>
3998 class BaseT {
3999 public:
4000 virtual void baseMethod() = 0;
4001 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
4003 Mutex mutex_;
4004 int a GUARDED_BY(mutex_);
4008 class Derived : public BaseT<int> {
4009 public:
4010 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
4011 a = 0;
4015 } // end namespace TemplateLockReturned
4018 namespace ExprMatchingBugFix {
4020 class Foo {
4021 public:
4022 Mutex mu_;
4026 class Bar {
4027 public:
4028 bool c;
4029 Foo* foo;
4030 Bar(Foo* f) : foo(f) { }
4032 struct Nested {
4033 Foo* foo;
4034 Nested(Foo* f) : foo(f) { }
4036 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
4039 void test();
4043 void Bar::test() {
4044 foo->mu_.Lock();
4045 if (c) {
4046 Nested *n = new Nested(foo);
4047 n->unlockFoo();
4049 else {
4050 foo->mu_.Unlock();
4054 }; // end namespace ExprMatchingBugfix
4057 namespace ComplexNameTest {
4059 class Foo {
4060 public:
4061 static Mutex mu_;
4063 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
4064 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
4066 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
4069 class Bar {
4070 public:
4071 static Mutex mu_;
4073 Bar() LOCKS_EXCLUDED(mu_) { }
4074 ~Bar() LOCKS_EXCLUDED(mu_) { }
4076 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
4080 void test1() {
4081 Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
4082 int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
4083 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
4086 void test2() {
4087 Bar::mu_.Lock();
4089 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
4090 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
4091 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
4092 Bar::mu_.Unlock();
4095 }; // end namespace ComplexNameTest
4098 namespace UnreachableExitTest {
4100 class FemmeFatale {
4101 public:
4102 FemmeFatale();
4103 ~FemmeFatale() __attribute__((noreturn));
4106 void exitNow() __attribute__((noreturn));
4107 void exitDestruct(const MyString& ms) __attribute__((noreturn));
4109 Mutex fatalmu_;
4111 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
4112 exitNow();
4115 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
4116 FemmeFatale femme;
4119 bool c;
4121 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
4122 if (c) {
4123 exitNow();
4125 else {
4126 FemmeFatale femme;
4130 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
4131 exitDestruct("foo");
4134 } // end namespace UnreachableExitTest
4137 namespace VirtualMethodCanonicalizationTest {
4139 class Base {
4140 public:
4141 virtual Mutex* getMutex() = 0;
4144 class Base2 : public Base {
4145 public:
4146 Mutex* getMutex();
4149 class Base3 : public Base2 {
4150 public:
4151 Mutex* getMutex();
4154 class Derived : public Base3 {
4155 public:
4156 Mutex* getMutex(); // overrides Base::getMutex()
4159 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
4161 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
4162 baseFun(d);
4165 } // end namespace VirtualMethodCanonicalizationTest
4168 namespace TemplateFunctionParamRemapTest {
4170 template <class T>
4171 struct Cell {
4172 T dummy_;
4173 Mutex* mu_;
4176 class Foo {
4177 public:
4178 template <class T>
4179 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
4181 void test();
4184 template<class T>
4185 void Foo::elr(Cell<T>* c1) { }
4187 void Foo::test() {
4188 Cell<int> cell;
4189 elr(&cell); // \
4190 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}
4194 template<class T>
4195 void globalELR(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
4197 template<class T>
4198 void globalELR(Cell<T>* c1) { }
4200 void globalTest() {
4201 Cell<int> cell;
4202 globalELR(&cell); // \
4203 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}
4207 template<class T>
4208 void globalELR2(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
4210 // second declaration
4211 template<class T>
4212 void globalELR2(Cell<T>* c2);
4214 template<class T>
4215 void globalELR2(Cell<T>* c3) { }
4217 // re-declaration after definition
4218 template<class T>
4219 void globalELR2(Cell<T>* c4);
4221 void globalTest2() {
4222 Cell<int> cell;
4223 globalELR2(&cell); // \
4224 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}
4228 template<class T>
4229 class FooT {
4230 public:
4231 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
4234 template<class T>
4235 void FooT<T>::elr(Cell<T>* c1) { }
4237 void testFooT() {
4238 Cell<int> cell;
4239 FooT<int> foo;
4240 foo.elr(&cell); // \
4241 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
4244 } // end namespace TemplateFunctionParamRemapTest
4247 namespace SelfConstructorTest {
4249 class SelfLock {
4250 public:
4251 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_);
4252 ~SelfLock() UNLOCK_FUNCTION(mu_);
4254 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4256 Mutex mu_;
4259 class LOCKABLE SelfLock2 {
4260 public:
4261 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
4262 ~SelfLock2() UNLOCK_FUNCTION();
4264 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
4267 class SelfLockDeferred {
4268 public:
4269 SelfLockDeferred() LOCKS_EXCLUDED(mu_);
4270 ~SelfLockDeferred() UNLOCK_FUNCTION(mu_);
4272 Mutex mu_;
4275 class LOCKABLE SelfLockDeferred2 {
4276 public:
4277 SelfLockDeferred2() LOCKS_EXCLUDED(this);
4278 ~SelfLockDeferred2() UNLOCK_FUNCTION();
4282 void test() {
4283 SelfLock s;
4284 s.foo();
4287 void test2() {
4288 SelfLock2 s2;
4289 s2.foo();
4292 void testDeferredTemporary() {
4293 SelfLockDeferred(); // expected-warning {{releasing mutex '<temporary>.mu_' that was not held}}
4296 void testDeferredTemporary2() {
4297 SelfLockDeferred2(); // expected-warning {{releasing mutex '<temporary>' that was not held}}
4300 } // end namespace SelfConstructorTest
4303 namespace MultipleAttributeTest {
4305 class Foo {
4306 Mutex mu1_;
4307 Mutex mu2_;
4308 int a GUARDED_BY(mu1_);
4309 int b GUARDED_BY(mu2_);
4310 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_);
4311 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
4313 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_)
4314 EXCLUSIVE_LOCKS_REQUIRED(mu2_);
4315 void foo2() SHARED_LOCKS_REQUIRED(mu1_)
4316 SHARED_LOCKS_REQUIRED(mu2_);
4317 void foo3() LOCKS_EXCLUDED(mu1_)
4318 LOCKS_EXCLUDED(mu2_);
4319 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
4320 EXCLUSIVE_LOCK_FUNCTION(mu2_);
4321 void readerlock() SHARED_LOCK_FUNCTION(mu1_)
4322 SHARED_LOCK_FUNCTION(mu2_);
4323 void unlock() UNLOCK_FUNCTION(mu1_)
4324 UNLOCK_FUNCTION(mu2_);
4325 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
4326 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
4327 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
4328 SHARED_TRYLOCK_FUNCTION(true, mu2_);
4329 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
4330 ASSERT_EXCLUSIVE_LOCK(mu2_);
4332 void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);
4334 void assertShared() ASSERT_SHARED_LOCK(mu1_)
4335 ASSERT_SHARED_LOCK(mu2_);
4337 void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);
4339 void test();
4340 void testAssert();
4341 void testAssertShared();
4345 void Foo::foo1() {
4346 a = 1;
4347 b = 2;
4350 void Foo::foo2() {
4351 int result = a + b;
4354 void Foo::foo3() { }
4355 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
4356 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
4357 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
4358 bool Foo::trylock() { return true; }
4359 bool Foo::readertrylock() { return true; }
4362 void Foo::test() {
4363 mu1_.Lock();
4364 foo1(); // expected-warning {{}}
4365 c = 0; // expected-warning {{}}
4366 *d = 0; // expected-warning {{}}
4367 mu1_.Unlock();
4369 mu1_.ReaderLock();
4370 foo2(); // expected-warning {{}}
4371 int x = c; // expected-warning {{}}
4372 int y = *d; // expected-warning {{}}
4373 mu1_.Unlock();
4375 mu2_.Lock();
4376 foo3(); // expected-warning {{}}
4377 mu2_.Unlock();
4379 lock();
4380 a = 0;
4381 b = 0;
4382 unlock();
4384 readerlock();
4385 int z = a + b;
4386 unlock();
4388 if (trylock()) {
4389 a = 0;
4390 b = 0;
4391 unlock();
4394 if (readertrylock()) {
4395 int zz = a + b;
4396 unlock();
4400 // Force duplication of attributes
4401 void Foo::assertBoth() { }
4402 void Foo::alsoAssertBoth() { }
4403 void Foo::assertShared() { }
4404 void Foo::alsoAssertShared() { }
4406 void Foo::testAssert() {
4408 assertBoth();
4409 a = 0;
4410 b = 0;
4413 alsoAssertBoth();
4414 a = 0;
4415 b = 0;
4419 void Foo::testAssertShared() {
4421 assertShared();
4422 int zz = a + b;
4426 alsoAssertShared();
4427 int zz = a + b;
4432 } // end namespace MultipleAttributeTest
4435 namespace GuardedNonPrimitiveTypeTest {
4438 class Data {
4439 public:
4440 Data(int i) : dat(i) { }
4442 int getValue() const { return dat; }
4443 void setValue(int i) { dat = i; }
4445 int operator[](int i) const { return dat; }
4446 int& operator[](int i) { return dat; }
4448 void operator()() { }
4450 Data& operator+=(int);
4451 Data& operator-=(int);
4452 Data& operator*=(int);
4453 Data& operator/=(int);
4454 Data& operator%=(int);
4455 Data& operator^=(int);
4456 Data& operator&=(int);
4457 Data& operator|=(int);
4458 Data& operator<<=(int);
4459 Data& operator>>=(int);
4460 Data& operator++();
4461 Data& operator++(int);
4462 Data& operator--();
4463 Data& operator--(int);
4465 private:
4466 int dat;
4470 class DataCell {
4471 public:
4472 DataCell(const Data& d) : dat(d) { }
4474 private:
4475 Data dat;
4479 void showDataCell(const DataCell& dc);
4482 class Foo {
4483 public:
4484 // method call tests
4485 void test() {
4486 data_.setValue(0); // FIXME -- should be writing \
4487 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4488 int a = data_.getValue(); // \
4489 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4491 datap1_->setValue(0); // FIXME -- should be writing \
4492 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4493 a = datap1_->getValue(); // \
4494 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4496 datap2_->setValue(0); // FIXME -- should be writing \
4497 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4498 a = datap2_->getValue(); // \
4499 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4501 (*datap2_).setValue(0); // FIXME -- should be writing \
4502 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4503 a = (*datap2_).getValue(); // \
4504 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4506 mu_.Lock();
4507 data_.setValue(1);
4508 datap1_->setValue(1);
4509 datap2_->setValue(1);
4510 mu_.Unlock();
4512 mu_.ReaderLock();
4513 a = data_.getValue();
4514 datap1_->setValue(0); // reads datap1_, writes *datap1_
4515 a = datap1_->getValue();
4516 a = datap2_->getValue();
4517 mu_.Unlock();
4520 // operator tests
4521 void test2() {
4522 data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4523 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
4524 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4525 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
4526 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4527 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4528 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4529 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4530 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4531 data_ += 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4532 data_ -= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4533 data_ *= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4534 data_ /= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4535 data_ %= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4536 data_ ^= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4537 data_ &= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4538 data_ |= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4539 data_ <<= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4540 data_ >>= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4541 ++data_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4542 data_++; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4543 --data_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4544 data_--; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4546 data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4547 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4549 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4552 // const operator tests
4553 void test3() const {
4554 Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4556 //FIXME
4557 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4558 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4560 int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4563 private:
4564 Mutex mu_;
4565 Data data_ GUARDED_BY(mu_);
4566 Data* datap1_ GUARDED_BY(mu_);
4567 Data* datap2_ PT_GUARDED_BY(mu_);
4570 } // end namespace GuardedNonPrimitiveTypeTest
4573 namespace GuardedNonPrimitive_MemberAccess {
4575 class Cell {
4576 public:
4577 Cell(int i);
4579 void cellMethod();
4581 int a;
4585 class Foo {
4586 public:
4587 int a;
4588 Cell c GUARDED_BY(cell_mu_);
4589 Cell* cp PT_GUARDED_BY(cell_mu_);
4591 void myMethod();
4593 Mutex cell_mu_;
4597 class Bar {
4598 private:
4599 Mutex mu_;
4600 Foo foo GUARDED_BY(mu_);
4601 Foo* foop PT_GUARDED_BY(mu_);
4603 void test() {
4604 foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4606 int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4607 foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
4609 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4610 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4612 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4613 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4615 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
4616 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
4617 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
4618 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
4620 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4621 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4622 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4623 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4625 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4626 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4627 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4628 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4632 } // namespace GuardedNonPrimitive_MemberAccess
4635 namespace TestThrowExpr {
4637 class Foo {
4638 Mutex mu_;
4640 bool hasError();
4642 void test() {
4643 mu_.Lock();
4644 if (hasError()) {
4645 throw "ugly";
4647 mu_.Unlock();
4651 } // end namespace TestThrowExpr
4654 namespace UnevaluatedContextTest {
4656 // parse attribute expressions in an unevaluated context.
4658 static inline Mutex* getMutex1();
4659 static inline Mutex* getMutex2();
4661 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
4663 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
4665 } // end namespace UnevaluatedContextTest
4668 namespace LockUnlockFunctionTest {
4670 // Check built-in lock functions
4671 class LOCKABLE MyLockable {
4672 public:
4673 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
4674 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
4675 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
4677 private:
4678 Mutex mu_;
4682 class Foo {
4683 public:
4684 // Correct lock/unlock functions
4685 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4686 mu_.Lock();
4689 void readerLock() SHARED_LOCK_FUNCTION(mu_) {
4690 mu_.ReaderLock();
4693 void unlock() UNLOCK_FUNCTION(mu_) {
4694 mu_.Unlock();
4697 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_) {
4698 mu_.Unlock();
4701 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_) {
4702 mu_.ReaderUnlock();
4705 // Check failure to lock.
4706 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4707 mu2_.Lock();
4708 mu2_.Unlock();
4709 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4711 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4712 mu2_.Lock();
4713 mu2_.Unlock();
4714 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4716 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4717 mu2_.Lock();
4718 mu2_.Unlock();
4719 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4721 // Check locking the wrong thing.
4722 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4723 mu2_.Lock(); // expected-note {{mutex acquired here}}
4724 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4725 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4728 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4729 mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
4730 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4731 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4734 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4735 mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
4736 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4738 private:
4739 Mutex mu_;
4740 Mutex mu2_;
4743 } // end namespace LockUnlockFunctionTest
4746 namespace AssertHeldTest {
4748 class Foo {
4749 public:
4750 int c;
4751 int a GUARDED_BY(mu_);
4752 Mutex mu_;
4754 void test1() {
4755 mu_.AssertHeld();
4756 int b = a;
4757 a = 0;
4760 void test2() {
4761 mu_.AssertReaderHeld();
4762 int b = a;
4763 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4766 void test3() {
4767 if (c) {
4768 mu_.AssertHeld();
4770 else {
4771 mu_.AssertHeld();
4773 int b = a;
4774 a = 0;
4777 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4778 mu_.AssertHeld();
4779 int b = a;
4780 a = 0;
4783 void test5() UNLOCK_FUNCTION(mu_) {
4784 mu_.AssertHeld();
4785 mu_.Unlock();
4788 void test6() {
4789 mu_.AssertHeld();
4790 mu_.Unlock(); // should this be a warning?
4793 void test7() {
4794 if (c) {
4795 mu_.AssertHeld();
4797 else {
4798 mu_.Lock();
4800 int b = a;
4801 a = 0;
4802 mu_.Unlock();
4805 void test8() {
4806 if (c) {
4807 mu_.Lock();
4809 else {
4810 mu_.AssertHeld();
4812 // FIXME: should warn, because it's unclear whether we need to release or not.
4813 int b = a;
4814 a = 0;
4815 mu_.Unlock(); // should this be a warning?
4818 void test9() {
4819 if (c) {
4820 mu_.AssertHeld();
4822 else {
4823 mu_.Lock(); // expected-note {{mutex acquired here}}
4825 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4827 void test10() {
4828 if (c) {
4829 mu_.Lock(); // expected-note {{mutex acquired here}}
4831 else {
4832 mu_.AssertHeld();
4834 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4836 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
4838 void test11() {
4839 assertMu();
4840 int b = a;
4841 a = 0;
4844 void test12() {
4845 if (c)
4846 mu_.ReaderLock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
4847 else
4848 mu_.AssertHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}
4849 // FIXME: should instead warn because it's unclear whether we need to release or not.
4850 int b = a;
4851 a = 0;
4852 mu_.Unlock();
4855 void test13() {
4856 if (c)
4857 mu_.Lock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
4858 else
4859 mu_.AssertReaderHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}
4860 // FIXME: should instead warn because it's unclear whether we need to release or not.
4861 int b = a;
4862 a = 0;
4863 mu_.Unlock();
4867 } // end namespace AssertHeldTest
4870 namespace LogicalConditionalTryLock {
4872 class Foo {
4873 public:
4874 Mutex mu;
4875 int a GUARDED_BY(mu);
4876 bool c;
4878 bool newc();
4880 void test1() {
4881 if (c && mu.TryLock()) {
4882 a = 0;
4883 mu.Unlock();
4887 void test2() {
4888 bool b = mu.TryLock();
4889 if (c && b) {
4890 a = 0;
4891 mu.Unlock();
4895 void test3() {
4896 if (c || !mu.TryLock())
4897 return;
4898 a = 0;
4899 mu.Unlock();
4902 void test4() {
4903 while (c && mu.TryLock()) {
4904 a = 0;
4905 c = newc();
4906 mu.Unlock();
4910 void test5() {
4911 while (c) {
4912 if (newc() || !mu.TryLock())
4913 break;
4914 a = 0;
4915 mu.Unlock();
4919 void test6() {
4920 mu.Lock();
4921 do {
4922 a = 0;
4923 mu.Unlock();
4924 } while (newc() && mu.TryLock());
4927 void test7() {
4928 for (bool b = mu.TryLock(); c && b;) {
4929 a = 0;
4930 mu.Unlock();
4934 void test8() {
4935 if (c && newc() && mu.TryLock()) {
4936 a = 0;
4937 mu.Unlock();
4941 void test9() {
4942 if (!(c && newc() && mu.TryLock()))
4943 return;
4944 a = 0;
4945 mu.Unlock();
4948 void test10() {
4949 if (!(c || !mu.TryLock())) {
4950 a = 0;
4951 mu.Unlock();
4956 } // end namespace LogicalConditionalTryLock
4960 namespace PtGuardedByTest {
4962 void doSomething();
4964 class Cell {
4965 public:
4966 int a;
4970 // This mainly duplicates earlier tests, but just to make sure...
4971 class PtGuardedByCorrectnessTest {
4972 Mutex mu1;
4973 Mutex mu2;
4974 int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4975 Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4976 int sa[10] GUARDED_BY(mu1);
4977 Cell sc[10] GUARDED_BY(mu1);
4979 static constexpr int Cell::*pa = &Cell::a;
4981 void test1() {
4982 mu1.Lock();
4983 if (a == 0) doSomething(); // OK, we don't dereference.
4984 a = 0;
4985 c = 0;
4986 if (sa[0] == 42) doSomething();
4987 sa[0] = 57;
4988 if (sc[0].a == 42) doSomething();
4989 sc[0].a = 57;
4990 mu1.Unlock();
4993 void test2() {
4994 mu1.ReaderLock();
4995 if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4996 *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4998 if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4999 c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
5000 c->*pa = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
5002 if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
5003 (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
5004 (*c).*pa = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
5006 if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
5007 a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
5008 if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
5009 c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
5010 mu1.Unlock();
5013 void test3() {
5014 mu2.Lock();
5015 if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
5016 *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
5018 if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5019 c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5021 if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5022 (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5024 if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
5025 a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
5026 if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5027 c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
5028 mu2.Unlock();
5031 void test4() { // Literal arrays
5032 if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
5033 sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
5034 if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
5035 sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5036 sc[0].*pa = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5038 if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
5039 *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
5040 if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
5041 (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5042 if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
5043 sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5046 void test5() {
5047 mu1.ReaderLock(); // OK -- correct use.
5048 mu2.Lock();
5049 if (*a == 0) doSomething();
5050 *a = 0;
5052 if (c->a == 0) doSomething();
5053 c->a = 0;
5055 if ((*c).a == 0) doSomething();
5056 (*c).a = 0;
5057 mu2.Unlock();
5058 mu1.Unlock();
5063 class SmartPtr_PtGuardedBy_Test {
5064 Mutex mu1;
5065 Mutex mu2;
5066 SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
5067 SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
5069 static constexpr int Cell::*pa = &Cell::a;
5071 void test1() {
5072 mu1.ReaderLock();
5073 mu2.Lock();
5075 sp.get();
5076 if (*sp == 0) doSomething();
5077 *sp = 0;
5078 sq->a = 0;
5079 sq->*pa = 0;
5081 if (sp[0] == 0) doSomething();
5082 sp[0] = 0;
5084 mu2.Unlock();
5085 mu1.Unlock();
5088 void test2() {
5089 mu2.Lock();
5091 sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5092 if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5093 *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5094 sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5095 sq->*pa = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5097 if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5098 sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5099 if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5100 sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5102 mu2.Unlock();
5105 void test3() {
5106 mu1.Lock();
5108 sp.get();
5109 if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5110 *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5111 sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5112 sq->*pa = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5114 if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5115 sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5116 if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5117 sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5119 mu1.Unlock();
5123 } // end namespace PtGuardedByTest
5126 namespace NonMemberCalleeICETest {
5128 class A {
5129 void Run() {
5130 (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
5133 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M);
5134 Mutex M;
5137 } // end namespace NonMemberCalleeICETest
5140 namespace pt_guard_attribute_type {
5141 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
5142 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
5144 void test() {
5145 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
5146 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
5148 typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}}
5149 typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}}
5151 } // end namespace pt_guard_attribute_type
5154 namespace ThreadAttributesOnLambdas {
5156 class Foo {
5157 Mutex mu_;
5159 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
5161 void test() {
5162 auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
5163 LockedFunction();
5166 auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
5167 LockedFunction();
5170 auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
5171 mu_.Lock();
5174 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
5175 func2();
5176 func3();
5177 mu_.Unlock();
5181 } // end namespace ThreadAttributesOnLambdas
5185 namespace AttributeExpressionCornerCases {
5187 class Foo {
5188 int a GUARDED_BY(getMu());
5190 Mutex* getMu() LOCK_RETURNED("");
5191 Mutex* getUniv() LOCK_RETURNED("*");
5193 void test1() {
5194 a = 0;
5197 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
5198 a = 0;
5201 void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);
5203 void test3() {
5204 foo(nullptr);
5209 class MapTest {
5210 struct MuCell { Mutex* mu; };
5212 MyMap<MyString, Mutex*> map;
5213 MyMap<MyString, MuCell> mapCell;
5215 int a GUARDED_BY(map["foo"]);
5216 int b GUARDED_BY(mapCell["foo"].mu);
5218 void test() {
5219 map["foo"]->Lock();
5220 a = 0;
5221 map["foo"]->Unlock();
5224 void test2() {
5225 mapCell["foo"].mu->Lock();
5226 b = 0;
5227 mapCell["foo"].mu->Unlock();
5232 class PreciseSmartPtr {
5233 SmartPtr<Mutex> mu;
5234 int val GUARDED_BY(mu);
5236 static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {
5237 a.mu->Lock();
5238 bool result = (a.val == b.val); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
5239 // expected-note {{found near match 'a.mu'}}
5240 a.mu->Unlock();
5241 return result;
5246 class SmartRedeclare {
5247 SmartPtr<Mutex> mu;
5248 int val GUARDED_BY(mu);
5250 void test() EXCLUSIVE_LOCKS_REQUIRED(mu);
5251 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
5252 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
5256 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {
5257 val = 0;
5260 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {
5261 val = 0;
5264 void SmartRedeclare::test3() {
5265 val = 0;
5269 namespace CustomMutex {
5272 class LOCKABLE BaseMutex { };
5273 class DerivedMutex : public BaseMutex { };
5275 void customLock(const BaseMutex *m) EXCLUSIVE_LOCK_FUNCTION(m);
5276 void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);
5278 static struct DerivedMutex custMu;
5280 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }
5282 void customTest() {
5283 customLock(reinterpret_cast<BaseMutex*>(&custMu)); // ignore casts
5284 doSomethingRequiringLock();
5285 customUnlock(reinterpret_cast<BaseMutex*>(&custMu));
5288 } // end namespace CustomMutex
5290 } // end AttributeExpressionCornerCases
5293 namespace ScopedLockReturnedInvalid {
5295 class Opaque;
5297 Mutex* getMutex(Opaque* o) LOCK_RETURNED("");
5299 void test(Opaque* o) {
5300 MutexLock lock(getMutex(o));
5303 } // end namespace ScopedLockReturnedInvalid
5306 namespace NegativeRequirements {
5308 class Bar {
5309 Mutex mu;
5310 int a GUARDED_BY(mu);
5312 public:
5313 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
5314 mu.Lock();
5315 a = 0;
5316 mu.Unlock();
5321 class Foo {
5322 Mutex mu;
5323 int a GUARDED_BY(mu);
5325 public:
5326 void foo() {
5327 mu.Lock(); // warning? needs !mu?
5328 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
5329 bar();
5330 mu.Unlock();
5333 void bar() {
5334 bar2(); // expected-warning {{calling function 'bar2' requires negative capability '!mu'}}
5337 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
5338 baz();
5341 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
5342 mu.Lock();
5343 a = 0;
5344 mu.Unlock();
5347 void test() {
5348 Bar b;
5349 b.baz(); // no warning -- in different class.
5353 } // end namespace NegativeRequirements
5356 namespace NegativeThreadRoles {
5358 typedef int __attribute__((capability("role"))) ThreadRole;
5360 void acquire(ThreadRole R) EXCLUSIVE_LOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
5361 void release(ThreadRole R) UNLOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
5363 ThreadRole FlightControl, Logger;
5365 extern void enque_log_msg(const char *msg);
5366 void log_msg(const char *msg) {
5367 enque_log_msg(msg);
5370 void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}
5371 void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}
5373 void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {
5374 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while role 'FlightControl' is held}} */
5375 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
5378 void spawn_fake_flight_control_thread(void) {
5379 acquire(FlightControl);
5380 flight_control_entry();
5381 release(FlightControl);
5384 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
5385 void logger_entry(void) __attribute__((requires_capability(Logger)))
5386 __attribute__((requires_capability(!FlightControl))) {
5387 const char *msg;
5389 while ((msg = deque_log_msg())) {
5390 dispatch_log(msg);
5394 void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl))) {
5395 acquire(Logger);
5396 logger_entry();
5397 release(Logger);
5400 int main(void) __attribute__((requires_capability(!FlightControl))) {
5401 spawn_fake_flight_control_thread();
5402 spawn_fake_logger_thread();
5404 for (;;)
5405 ; /* Pretend to dispatch things. */
5407 return 0;
5410 } // end namespace NegativeThreadRoles
5413 namespace AssertSharedExclusive {
5415 void doSomething();
5417 class Foo {
5418 Mutex mu;
5419 int a GUARDED_BY(mu);
5421 void test() SHARED_LOCKS_REQUIRED(mu) {
5422 mu.AssertHeld();
5423 if (a > 0)
5424 doSomething();
5428 } // end namespace AssertSharedExclusive
5431 namespace RangeBasedForAndReferences {
5433 class Foo {
5434 struct MyStruct {
5435 int a;
5438 Mutex mu;
5439 int a GUARDED_BY(mu);
5440 MyContainer<int> cntr GUARDED_BY(mu);
5441 MyStruct s GUARDED_BY(mu);
5442 int arr[10] GUARDED_BY(mu);
5444 void nonref_test() {
5445 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5446 b = 0; // no warning
5449 void auto_test() {
5450 auto b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5451 b = 0; // no warning
5452 auto &c = a; // no warning
5453 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5456 void ref_test() {
5457 int &b = a;
5458 int &c = b;
5459 int &d = c;
5460 b = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5461 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5462 d = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5464 MyStruct &rs = s;
5465 rs.a = 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
5467 int (&rarr)[10] = arr;
5468 rarr[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
5471 void ptr_test() {
5472 int *b = &a;
5473 *b = 0; // no expected warning yet
5476 void for_test() {
5477 int total = 0;
5478 for (int i : cntr) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
5479 total += i;
5485 } // end namespace RangeBasedForAndReferences
5489 namespace PassByRefTest {
5491 class Foo {
5492 public:
5493 Foo() : a(0), b(0) { }
5495 int a;
5496 int b;
5498 void operator+(const Foo& f);
5500 void operator[](const Foo& g);
5502 void operator()();
5505 template<class T>
5506 T&& mymove(T& f);
5509 // test top-level functions
5510 void copy(Foo f);
5511 void write1(Foo& f);
5512 void write2(int a, Foo& f);
5513 void read1(const Foo& f);
5514 void read2(int a, const Foo& f);
5515 void destroy(Foo&& f);
5517 void operator/(const Foo& f, const Foo& g);
5518 void operator*(const Foo& f, const Foo& g);
5520 // Test constructors.
5521 struct FooRead {
5522 FooRead(const Foo &);
5524 struct FooWrite {
5525 FooWrite(Foo &);
5528 // Test variadic functions
5529 template<typename... T>
5530 void copyVariadic(T...) {}
5531 template<typename... T>
5532 void writeVariadic(T&...) {}
5533 template<typename... T>
5534 void readVariadic(const T&...) {}
5536 void copyVariadicC(int, ...);
5538 class Bar {
5539 public:
5540 Mutex mu;
5541 Foo foo GUARDED_BY(mu);
5542 Foo foo2 GUARDED_BY(mu);
5543 Foo* foop PT_GUARDED_BY(mu);
5544 SmartPtr<Foo> foosp PT_GUARDED_BY(mu);
5546 // test methods.
5547 void mwrite1(Foo& f);
5548 void mwrite2(int a, Foo& f);
5549 void mread1(const Foo& f);
5550 void mread2(int a, const Foo& f);
5552 // static methods
5553 static void smwrite1(Foo& f);
5554 static void smwrite2(int a, Foo& f);
5555 static void smread1(const Foo& f);
5556 static void smread2(int a, const Foo& f);
5558 void operator<<(const Foo& f);
5560 void test1() {
5561 copy(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5562 write1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5563 write2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5564 read1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5565 read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5566 destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5568 copyVariadic(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5569 readVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5570 writeVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5571 copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5573 FooRead reader(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5574 FooWrite writer(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5576 mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5577 mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5578 mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5579 mread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5581 smwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5582 smwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5583 smread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5584 smread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5586 foo + foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5587 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5588 foo / foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5589 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5590 foo * foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5591 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5592 foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5593 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5594 foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5595 (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5597 copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
5598 write1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5599 write2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5600 read1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5601 read2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5602 destroy(mymove(*foop)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5604 copy(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5605 write1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5606 write2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5607 read1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5608 read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5609 destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5611 // TODO -- these require better smart pointer handling.
5612 copy(*foosp.get());
5613 write1(*foosp.get());
5614 write2(10, *foosp.get());
5615 read1(*foosp.get());
5616 read2(10, *foosp.get());
5617 destroy(mymove(*foosp.get()));
5621 class Return {
5622 Mutex mu;
5623 Foo foo GUARDED_BY(mu);
5624 Foo* foo_ptr PT_GUARDED_BY(mu);
5626 Foo returns_value_locked() {
5627 MutexLock lock(&mu);
5628 return foo;
5631 Foo returns_value_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {
5632 return foo;
5635 Foo returns_value_releases_lock_after_return() UNLOCK_FUNCTION(mu) {
5636 MutexLock lock(&mu, true);
5637 return foo;
5640 Foo returns_value_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu) {
5641 mu.Lock();
5642 return foo;
5645 Foo returns_value_not_locked() {
5646 return foo; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5649 Foo returns_value_releases_lock_before_return() UNLOCK_FUNCTION(mu) {
5650 mu.Unlock();
5651 return foo; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5654 Foo &returns_ref_not_locked() {
5655 return foo; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}
5658 Foo &returns_ref_locked() {
5659 MutexLock lock(&mu);
5660 return foo; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}
5663 Foo &returns_ref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {
5664 return foo; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5667 Foo &returns_ref_exclusive_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {
5668 return foo;
5671 Foo &returns_ref_releases_lock_after_return() UNLOCK_FUNCTION(mu) {
5672 MutexLock lock(&mu, true);
5673 return foo; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5676 Foo& returns_ref_releases_lock_before_return() UNLOCK_FUNCTION(mu) {
5677 mu.Unlock();
5678 return foo; // // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5681 Foo &returns_ref_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu) {
5682 mu.Lock();
5683 return foo;
5686 const Foo &returns_constref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {
5687 return foo;
5690 Foo *returns_ptr() {
5691 return &foo; // FIXME -- Do we want to warn on this ?
5694 Foo &returns_ref2() {
5695 return *foo_ptr; // expected-warning {{returning the value that 'foo_ptr' points to by reference requires holding mutex 'mu' exclusively}}
5701 } // end namespace PassByRefTest
5704 namespace AcquiredBeforeAfterText {
5706 class Foo {
5707 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5708 Mutex mu2;
5709 Mutex mu3;
5711 void test1() {
5712 mu1.Lock();
5713 mu2.Lock();
5714 mu3.Lock();
5716 mu3.Unlock();
5717 mu2.Unlock();
5718 mu1.Unlock();
5721 void test2() {
5722 mu2.Lock();
5723 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5724 mu1.Unlock();
5725 mu2.Unlock();
5728 void test3() {
5729 mu3.Lock();
5730 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5731 mu1.Unlock();
5732 mu3.Unlock();
5735 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {
5736 mu2.Lock();
5737 mu2.Unlock();
5740 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5741 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5742 mu1.Unlock();
5745 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5746 mu1.AssertHeld();
5749 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }
5751 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }
5755 class Foo2 {
5756 Mutex mu1;
5757 Mutex mu2 ACQUIRED_AFTER(mu1);
5758 Mutex mu3 ACQUIRED_AFTER(mu1);
5760 void test1() {
5761 mu1.Lock();
5762 mu2.Lock();
5763 mu3.Lock();
5765 mu3.Unlock();
5766 mu2.Unlock();
5767 mu1.Unlock();
5770 void test2() {
5771 mu2.Lock();
5772 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5773 mu1.Unlock();
5774 mu2.Unlock();
5777 void test3() {
5778 mu3.Lock();
5779 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5780 mu1.Unlock();
5781 mu3.Unlock();
5786 class Foo3 {
5787 Mutex mu1 ACQUIRED_BEFORE(mu2);
5788 Mutex mu2;
5789 Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);
5790 Mutex mu4;
5792 void test1() {
5793 mu1.Lock();
5794 mu2.Lock();
5795 mu3.Lock();
5796 mu4.Lock();
5798 mu4.Unlock();
5799 mu3.Unlock();
5800 mu2.Unlock();
5801 mu1.Unlock();
5804 void test2() {
5805 mu4.Lock();
5806 mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
5808 mu2.Unlock();
5809 mu4.Unlock();
5812 void test3() {
5813 mu4.Lock();
5814 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
5816 mu1.Unlock();
5817 mu4.Unlock();
5820 void test4() {
5821 mu3.Lock();
5822 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5824 mu1.Unlock();
5825 mu3.Unlock();
5830 // Test transitive DAG traversal with AFTER
5831 class Foo4 {
5832 Mutex mu1;
5833 Mutex mu2 ACQUIRED_AFTER(mu1);
5834 Mutex mu3 ACQUIRED_AFTER(mu1);
5835 Mutex mu4 ACQUIRED_AFTER(mu2, mu3);
5836 Mutex mu5 ACQUIRED_AFTER(mu4);
5837 Mutex mu6 ACQUIRED_AFTER(mu4);
5838 Mutex mu7 ACQUIRED_AFTER(mu5, mu6);
5839 Mutex mu8 ACQUIRED_AFTER(mu7);
5841 void test() {
5842 mu8.Lock();
5843 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5844 mu1.Unlock();
5845 mu8.Unlock();
5850 // Test transitive DAG traversal with BEFORE
5851 class Foo5 {
5852 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5853 Mutex mu2 ACQUIRED_BEFORE(mu4);
5854 Mutex mu3 ACQUIRED_BEFORE(mu4);
5855 Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);
5856 Mutex mu5 ACQUIRED_BEFORE(mu7);
5857 Mutex mu6 ACQUIRED_BEFORE(mu7);
5858 Mutex mu7 ACQUIRED_BEFORE(mu8);
5859 Mutex mu8;
5861 void test() {
5862 mu8.Lock();
5863 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5864 mu1.Unlock();
5865 mu8.Unlock();
5870 class Foo6 {
5871 Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu1'}}
5872 Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu2'}}
5873 Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu3'}}
5875 Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_b'}}
5876 Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_a'}}
5878 void test0() {
5879 mu_a.Lock();
5880 mu_b.Lock();
5881 mu_b.Unlock();
5882 mu_a.Unlock();
5885 void test1a() {
5886 mu1.Lock();
5887 mu1.Unlock();
5890 void test1b() {
5891 mu1.Lock();
5892 mu_a.Lock();
5893 mu_b.Lock();
5894 mu_b.Unlock();
5895 mu_a.Unlock();
5896 mu1.Unlock();
5899 void test() {
5900 mu2.Lock();
5901 mu2.Unlock();
5904 void test3() {
5905 mu3.Lock();
5906 mu3.Unlock();
5910 } // end namespace AcquiredBeforeAfterTest
5913 namespace ScopedAdoptTest {
5915 class Foo {
5916 Mutex mu;
5917 int a GUARDED_BY(mu);
5918 int b;
5920 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {
5921 MutexLock slock(&mu, true);
5922 a = 0;
5925 void test2() SHARED_UNLOCK_FUNCTION(mu) {
5926 ReaderMutexLock slock(&mu, true);
5927 b = a;
5930 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5931 MutexLock slock(&mu, true);
5932 a = 0;
5933 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5935 void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5936 ReaderMutexLock slock(&mu, true);
5937 b = a;
5938 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5942 } // end namespace ScopedAdoptTest
5945 namespace TestReferenceNoThreadSafetyAnalysis {
5947 #define TS_UNCHECKED_READ(x) ts_unchecked_read(x)
5949 // Takes a reference to a guarded data member, and returns an unguarded
5950 // reference.
5951 template <class T>
5952 inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
5953 return v;
5956 template <class T>
5957 inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
5958 return v;
5962 class Foo {
5963 public:
5964 Foo(): a(0) { }
5966 int a;
5970 class Bar {
5971 public:
5972 Bar() : a(0) { }
5974 Mutex mu;
5975 int a GUARDED_BY(mu);
5976 Foo foo GUARDED_BY(mu);
5980 void test() {
5981 Bar bar;
5982 const Bar cbar;
5984 int a = TS_UNCHECKED_READ(bar.a); // nowarn
5985 TS_UNCHECKED_READ(bar.a) = 1; // nowarn
5987 int b = TS_UNCHECKED_READ(bar.foo).a; // nowarn
5988 TS_UNCHECKED_READ(bar.foo).a = 1; // nowarn
5990 int c = TS_UNCHECKED_READ(cbar.a); // nowarn
5993 #undef TS_UNCHECKED_READ
5995 } // end namespace TestReferenceNoThreadSafetyAnalysis
5998 namespace GlobalAcquiredBeforeAfterTest {
6000 Mutex mu1;
6001 Mutex mu2 ACQUIRED_AFTER(mu1);
6003 void test3() {
6004 mu2.Lock();
6005 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
6006 mu1.Unlock();
6007 mu2.Unlock();
6010 } // end namespace GlobalAcquiredBeforeAfterTest
6013 namespace LifetimeExtensionText {
6015 struct Holder {
6016 virtual ~Holder() throw() {}
6017 int i = 0;
6020 void test() {
6021 // Should not crash.
6022 const auto &value = Holder().i;
6025 } // end namespace LifetimeExtensionTest
6028 namespace LockableUnions {
6030 union LOCKABLE MutexUnion {
6031 int a;
6032 char* b;
6034 void Lock() EXCLUSIVE_LOCK_FUNCTION();
6035 void Unlock() UNLOCK_FUNCTION();
6038 MutexUnion muun2;
6039 MutexUnion muun1 ACQUIRED_BEFORE(muun2);
6041 void test() {
6042 muun2.Lock();
6043 muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
6044 muun1.Unlock();
6045 muun2.Unlock();
6048 } // end namespace LockableUnions
6050 // This used to crash.
6051 class acquired_before_empty_str {
6052 void WaitUntilSpaceAvailable() {
6053 lock_.ReaderLock(); // expected-note {{acquired here}}
6054 } // expected-warning {{mutex 'lock_' is still held at the end of function}}
6055 Mutex lock_ ACQUIRED_BEFORE("");
6058 namespace PR34800 {
6059 struct A {
6060 operator int() const;
6062 struct B {
6063 bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
6064 int h;
6066 struct C {
6067 B *operator[](int);
6069 C c;
6070 void f() { c[A()]->g(); }
6071 } // namespace PR34800
6073 #ifdef __cpp_guaranteed_copy_elision
6075 namespace ReturnScopedLockable {
6077 class Object {
6078 public:
6079 MutexLock lock() EXCLUSIVE_LOCK_FUNCTION(mutex) {
6080 return MutexLock(&mutex);
6083 ReaderMutexLock lockShared() SHARED_LOCK_FUNCTION(mutex) {
6084 return ReaderMutexLock(&mutex);
6087 MutexLock adopt() EXCLUSIVE_LOCKS_REQUIRED(mutex) {
6088 return MutexLock(&mutex, true);
6091 ReaderMutexLock adoptShared() SHARED_LOCKS_REQUIRED(mutex) {
6092 return ReaderMutexLock(&mutex, true);
6095 int x GUARDED_BY(mutex);
6096 void needsLock() EXCLUSIVE_LOCKS_REQUIRED(mutex);
6098 void testInside() {
6099 MutexLock scope = lock();
6100 x = 1;
6101 needsLock();
6104 Mutex mutex;
6107 Object obj;
6109 void testLock() {
6110 MutexLock scope = obj.lock();
6111 obj.x = 1;
6112 obj.needsLock();
6115 int testSharedLock() {
6116 ReaderMutexLock scope = obj.lockShared();
6117 obj.x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'obj.mutex' exclusively}}
6118 return obj.x;
6121 void testAdopt() {
6122 obj.mutex.Lock();
6123 MutexLock scope = obj.adopt();
6124 obj.x = 1;
6127 int testAdoptShared() {
6128 obj.mutex.Lock();
6129 ReaderMutexLock scope = obj.adoptShared();
6130 obj.x = 1;
6131 return obj.x;
6134 } // namespace ReturnScopedLockable
6136 #endif
6138 namespace PR38640 {
6139 void f() {
6140 // Self-referencing assignment previously caused an infinite loop when thread
6141 // safety analysis was enabled.
6142 int &i = i; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}}
6146 namespace Derived_Smart_Pointer {
6147 template <class T>
6148 class SmartPtr_Derived : public SmartPtr<T> {};
6150 class Foo {
6151 public:
6152 SmartPtr_Derived<Mutex> mu_;
6153 int a GUARDED_BY(mu_);
6154 int b GUARDED_BY(mu_.get());
6155 int c GUARDED_BY(*mu_);
6157 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
6158 void Unlock() UNLOCK_FUNCTION(mu_);
6160 void test0() {
6161 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
6162 b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
6163 c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
6166 void test1() {
6167 Lock();
6168 a = 1;
6169 b = 1;
6170 c = 1;
6171 Unlock();
6175 class Bar {
6176 SmartPtr_Derived<Foo> foo;
6178 void test0() {
6179 foo->a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
6180 (*foo).b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
6181 foo.get()->c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
6184 void test1() {
6185 foo->Lock();
6186 foo->a = 1;
6187 foo->Unlock();
6189 foo->mu_->Lock();
6190 foo->b = 1;
6191 foo->mu_->Unlock();
6193 MutexLock lock(foo->mu_.get());
6194 foo->c = 1;
6198 class PointerGuard {
6199 Mutex mu1;
6200 Mutex mu2;
6201 SmartPtr_Derived<int> i GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
6203 void test0() {
6204 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6205 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \
6206 // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
6210 void test1() {
6211 mu1.Lock();
6213 i.get();
6214 *i = 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
6216 mu1.Unlock();
6219 void test2() {
6220 mu2.Lock();
6222 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6223 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6225 mu2.Unlock();
6228 void test3() {
6229 mu1.Lock();
6230 mu2.Lock();
6232 i.get();
6233 *i = 2;
6235 mu2.Unlock();
6236 mu1.Unlock();