1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions %s
3 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
4 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
6 #define LOCKABLE __attribute__((lockable))
7 #define SCOPED_LOCKABLE __attribute__((scoped_lockable))
8 #define GUARDED_BY(x) __attribute__((guarded_by(x)))
9 #define GUARDED_VAR __attribute__((guarded_var))
10 #define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
11 #define PT_GUARDED_VAR __attribute__((pt_guarded_var))
12 #define ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
13 #define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
14 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__)))
15 #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__)))
16 #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__((assert_exclusive_lock(__VA_ARGS__)))
17 #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__)))
18 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
19 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__)))
20 #define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
21 #define EXCLUSIVE_UNLOCK_FUNCTION(...) __attribute__((release_capability(__VA_ARGS__)))
22 #define SHARED_UNLOCK_FUNCTION(...) __attribute__((release_shared_capability(__VA_ARGS__)))
23 #define LOCK_RETURNED(x) __attribute__((lock_returned(x)))
24 #define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
25 #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__)))
26 #define SHARED_LOCKS_REQUIRED(...) __attribute__((shared_locks_required(__VA_ARGS__)))
27 #define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
30 class LOCKABLE Mutex {
32 void Lock() __attribute__((exclusive_lock_function));
33 void ReaderLock() __attribute__((shared_lock_function));
34 void Unlock() __attribute__((unlock_function));
35 bool TryLock() __attribute__((exclusive_trylock_function(true)));
36 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
37 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
39 // for negative capabilities
40 const Mutex& operator!() const { return *this; }
42 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
43 void AssertReaderHeld() ASSERT_SHARED_LOCK();
46 class SCOPED_LOCKABLE MutexLock {
48 MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
49 MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu);
50 ~MutexLock() UNLOCK_FUNCTION();
53 class SCOPED_LOCKABLE ReaderMutexLock {
55 ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu);
56 ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu);
57 ~ReaderMutexLock() UNLOCK_FUNCTION();
60 class SCOPED_LOCKABLE ReleasableMutexLock {
62 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
63 ~ReleasableMutexLock() UNLOCK_FUNCTION();
65 void Release() UNLOCK_FUNCTION();
68 class __attribute__((scoped_lockable)) DoubleMutexLock {
70 DoubleMutexLock(Mutex *mu1, Mutex *mu2)
71 __attribute__((exclusive_lock_function(mu1, mu2)));
72 ~DoubleMutexLock() __attribute__((unlock_function));
75 // The universal lock, written "*", allows checking to be selectively turned
76 // off for a particular piece of code.
77 void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
78 void endNoWarnOnReads() UNLOCK_FUNCTION("*");
79 void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
80 void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
83 // For testing handling of smart pointers.
87 SmartPtr(T* p) : ptr_(p) { }
88 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
91 T* get() const { return ptr_; }
92 T* operator->() const { return ptr_; }
93 T& operator*() const { return *ptr_; }
94 T& operator[](int i) const { return ptr_[i]; }
101 // For testing destructor calls and cleanup.
104 MyString(const char* s);
109 // For testing operator overloading
110 template <class K, class T>
113 T& operator[](const K& k);
117 // For testing handling of containers.
124 typedef const T* const_iterator;
132 T& operator[](int i);
133 const T& operator[](int i) const;
143 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
144 int sls_guard_var __attribute__((guarded_var)) = 0;
145 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
152 int x __attribute__((guarded_by(mu)));
153 void MyLock() __attribute__((exclusive_lock_function(mu)));
166 int x = sls_guard_var;
184 int x = sls_guardby_var;
217 void sls_fun_good_6() {
231 void sls_fun_good_7() {
246 void sls_fun_good_8() {
251 void sls_fun_bad_1() {
252 sls_mu.Unlock(); // \
253 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
256 void sls_fun_bad_2() {
259 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
263 void sls_fun_bad_3() {
264 sls_mu.Lock(); // expected-note {{mutex acquired here}}
265 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
267 void sls_fun_bad_4() {
269 sls_mu.Lock(); // expected-note{{mutex acquired here}}
271 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
272 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
273 // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
275 void sls_fun_bad_5() {
276 sls_mu.Lock(); // expected-note {{mutex acquired here}}
279 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
281 void sls_fun_bad_6() {
283 sls_mu.Lock(); // expected-note {{mutex acquired here}}
291 sls_mu.Unlock(); // \
292 expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
293 expected-warning{{releasing mutex 'sls_mu' that was not held}}
296 void sls_fun_bad_7() {
303 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
306 sls_mu.Lock(); // expected-note {{mutex acquired here}}
311 void sls_fun_bad_8() {
312 sls_mu.Lock(); // expected-note{{mutex acquired here}}
315 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
319 void sls_fun_bad_9() {
322 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
323 // expected-note{{mutex acquired here}}
328 void sls_fun_bad_10() {
329 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
330 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
333 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
335 void sls_fun_bad_11() {
336 while (getBool()) { // \
337 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
338 sls_mu.Lock(); // expected-note {{mutex acquired here}}
340 sls_mu.Unlock(); // \
341 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
344 void sls_fun_bad_12() {
345 sls_mu.Lock(); // expected-note {{mutex acquired here}}
350 break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
358 //-----------------------------------------//
359 // Handling lock expressions in attribute args
360 // -------------------------------------------//
366 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
367 void globalUnlock() __attribute__((unlock_function(aa_mu)));
374 glock.globalUnlock();
377 void aa_fun_bad_1() {
378 glock.globalUnlock(); // \
379 // expected-warning{{releasing mutex 'aa_mu' that was not held}}
382 void aa_fun_bad_2() {
384 glock.globalLock(); // \
385 // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
386 glock.globalUnlock();
389 void aa_fun_bad_3() {
390 glock.globalLock(); // expected-note{{mutex acquired here}}
391 } // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
393 //--------------------------------------------------//
394 // Regression tests for unusual method names
395 //--------------------------------------------------//
399 // Test diagnostics for other method names.
401 // FIXME: can't currently check inside constructors and destructors.
403 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
404 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
406 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
407 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
409 wmu.Lock(); // expected-note {{mutex acquired here}}
410 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
412 wmu.Lock(); // expected-note {{mutex acquired here}}
414 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
417 //-----------------------------------------------//
418 // Errors for guarded by or guarded var variables
419 // ----------------------------------------------//
421 int *pgb_gvar __attribute__((pt_guarded_var));
422 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
427 int *pgb_field __attribute__((guarded_by(sls_mu2)))
428 __attribute__((pt_guarded_by(sls_mu)));
431 // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
432 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
433 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
434 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
435 // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
436 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
437 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
443 int gb_field __attribute__((guarded_by(sls_mu)));
447 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
450 void testNoAnal() __attribute__((no_thread_safety_analysis)) {
455 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
479 sls_guard_var = 1; // \
480 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
484 int x = sls_guard_var; // \
485 // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
489 sls_guardby_var = 1; // \
490 // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
494 int x = sls_guardby_var; // \
495 // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
500 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
504 int x = *pgb_gvar; // \
505 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
510 // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
514 int x = *pgb_var; // \
515 // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
521 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
525 sls_guard_var++; // \
526 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
527 sls_guard_var--; // \
528 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
529 ++sls_guard_var; // \
530 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
532 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
535 //-----------------------------------------------//
536 // Warnings on variables with late parsed attributes
537 // ----------------------------------------------//
541 int a __attribute__((guarded_by(mu)));
544 void foo() __attribute__((exclusive_locks_required(mu))) { }
548 // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
550 // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
552 // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
555 int c __attribute__((guarded_by(mu)));
562 int a_ __attribute__((guarded_by(mu1_)));
564 int *q __attribute__((pt_guarded_by(mu)));
584 BarA.FooPointer->mu.Lock();
585 BarA.FooPointer->a = 2;
586 BarA.FooPointer->mu.Unlock();
594 // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
595 // expected-note{{found near match 'fooA.mu'}}
603 int res = b1.a_ + b3->b_;
605 // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
613 BarA.FooPointer->mu.Lock();
615 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
616 // expected-note{{found near match 'BarA.FooPointer->mu'}}
617 BarA.FooPointer->mu.Unlock();
623 BarA.FooPointer->a = 2; // \
624 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
625 // expected-note{{found near match 'BarA.Foo.mu'}}
626 BarA.Foo.mu.Unlock();
632 BarA.Foo2.a = 2; // \
633 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
634 // expected-note{{found near match 'BarA.Foo.mu'}}
635 BarA.Foo.mu.Unlock();
638 //-----------------------------------------------//
639 // Extra warnings for shared vs. exclusive locks
640 // ----------------------------------------------//
642 void shared_fun_0() {
651 void shared_fun_1() {
652 sls_mu.ReaderLock(); // \
653 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
657 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
662 void shared_fun_3() {
671 void shared_fun_4() {
676 int x = sls_guardby_var;
680 void shared_fun_8() {
683 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
685 sls_mu.ReaderLock(); // \
686 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
690 void shared_bad_0() {
692 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
695 sls_mu.ReaderLock(); // \
696 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
701 void shared_bad_1() {
704 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
706 sls_mu.ReaderLock(); // \
707 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
712 void shared_bad_2() {
714 sls_mu.ReaderLock(); // \
715 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
718 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
723 // FIXME: Add support for functions (not only methods)
726 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
727 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
728 void le_fun() __attribute__((locks_excluded(sls_mu)));
733 void test() __attribute__((exclusive_locks_required(sls_mu)));
734 void testShared() __attribute__((shared_locks_required(sls_mu2)));
737 void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
769 MyLRFoo.testShared();
774 sls_mu2.ReaderLock();
775 MyLRFoo.testShared();
789 void es_fun_8() __attribute__((no_thread_safety_analysis));
795 void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
800 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
806 Bar.aa_elr_fun(); // \
807 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
812 Bar.aa_elr_fun(); // \
813 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
818 Bar.aa_elr_fun_s(); // \
819 // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
824 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
828 MyLRFoo.testShared(); // \
829 // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
835 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
842 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
849 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
854 //-----------------------------------------------//
855 // Unparseable lock expressions
856 // ----------------------------------------------//
858 // FIXME -- derive new tests for unhandled expressions
861 //----------------------------------------------------------------------------//
862 // The following test cases are ported from the gcc thread safety implementation
863 // They are each wrapped inside a namespace with the test number of the gcc test
865 // FIXME: add all the gcc tests, once this analysis passes them.
866 //----------------------------------------------------------------------------//
868 //-----------------------------------------//
869 // Good testcases (no errors)
870 //-----------------------------------------//
872 namespace thread_annot_lock_20 {
875 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
876 static int b_ GUARDED_BY(mu1_);
878 static int a_ GUARDED_BY(mu1_);
891 } // end namespace thread_annot_lock_20
893 namespace thread_annot_lock_22 {
894 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
895 // uses in class definitions.
900 int a_ GUARDED_BY(mu1_);
902 int *q PT_GUARDED_BY(mu);
903 Mutex mu1_ ACQUIRED_AFTER(mu);
907 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
908 int res GUARDED_BY(mu) = 5;
915 res = b1.a_ + b3->b_;
917 b1.a_ = res + b3->b_;
925 } // end namespace thread_annot_lock_22
927 namespace thread_annot_lock_27_modified {
928 // test lock annotations applied to function definitions
929 // Modified: applied annotations only to function declarations
931 Mutex mu2 ACQUIRED_AFTER(mu1);
935 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
938 int Foo::method1(int i) {
943 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
948 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
949 static int bar(int i) {
964 } // end namespace thread_annot_lock_27_modified
967 namespace thread_annot_lock_38 {
968 // Test the case where a template member function is annotated with lock
969 // attributes in a non-template class.
972 void func1(int y) LOCKS_EXCLUDED(mu_);
973 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
985 } // end namespace thread_annot_lock_38
987 namespace thread_annot_lock_43 {
988 // Tests lock canonicalization
997 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
998 int a_ GUARDED_BY(foo_->mu_);
1006 fb->foo_->mu_->Lock();
1008 fb->foo_->mu_->Unlock();
1010 } // end namespace thread_annot_lock_43
1012 namespace thread_annot_lock_49 {
1013 // Test the support for use of lock expression in the annotations
1022 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
1026 foo->foo_mu_.Lock();
1029 foo->foo_mu_.Unlock();
1037 } // end namespace thread_annot_lock_49
1039 namespace thread_annot_lock_61_modified {
1040 // Modified to fix the compiler errors
1041 // Test the fix for a bug introduced by the support of pass-by-reference
1043 struct Foo { Foo &operator<< (bool) {return *this;} };
1045 struct Bar { Foo &func () {return getFoo();} };
1046 struct Bas { void operator& (Foo &) {} };
1049 Bas() & Bar().func() << "" << "";
1050 Bas() & Bar().func() << "";
1052 } // end namespace thread_annot_lock_61_modified
1055 namespace thread_annot_lock_65 {
1056 // Test the fix for a bug in the support of allowing reader locks for
1057 // non-const, non-modifying overload functions. (We didn't handle the builtin
1073 operator|(MyFlags a, MyFlags b)
1075 return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1079 operator|=(MyFlags& a, MyFlags b)
1083 } // end namespace thread_annot_lock_65
1085 namespace thread_annot_lock_66_modified {
1086 // Modified: Moved annotation to function defn
1087 // Test annotations on out-of-line definitions of member functions where the
1088 // annotations refer to locks that are also data members in the class.
1093 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1094 int data GUARDED_BY(mu1);
1099 int Foo::method1(int i)
1116 } // end namespace thread_annot_lock_66_modified
1118 namespace thread_annot_lock_68_modified {
1119 // Test a fix to a bug in the delayed name binding with nested template
1120 // instantiation. We use a stack to make sure a name is not resolved to an
1122 template <typename T>
1127 template <typename T>
1137 T count_ GUARDED_BY(mu_);
1147 } // end namespace thread_annot_lock_68_modified
1149 namespace thread_annot_lock_30_modified {
1150 // Test delay parsing of lock attribute arguments with nested classes.
1151 // Modified: trylocks replaced with exclusive_lock_fun
1158 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1185 } // end namespace thread_annot_lock_30_modified
1187 namespace thread_annot_lock_47 {
1188 // Test the support for annotations on virtual functions.
1189 // This is a good test case. (i.e. There should be no warning emitted by the
1193 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1194 virtual void func2() LOCKS_EXCLUDED(mu_);
1198 class Child : public Base {
1200 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1201 virtual void func2() LOCKS_EXCLUDED(mu_);
1218 } // end namespace thread_annot_lock_47
1220 //-----------------------------------------//
1221 // Tests which produce errors
1222 //-----------------------------------------//
1224 namespace thread_annot_lock_13 {
1228 int g GUARDED_BY(mu1);
1229 int w GUARDED_BY(mu2);
1233 void bar() LOCKS_EXCLUDED(mu_, mu1);
1234 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1237 int a_ GUARDED_BY(mu_);
1239 Mutex mu_ ACQUIRED_AFTER(mu1);
1254 x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1268 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1274 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1280 } // end namespace thread_annot_lock_13
1282 namespace thread_annot_lock_18_modified {
1283 // Modified: Trylocks removed
1284 // Test the ability to distnguish between the same lock field of
1285 // different objects of a class.
1288 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1289 void MyUnlock() UNLOCK_FUNCTION(mu1_);
1290 int a_ GUARDED_BY(mu1_);
1303 // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
1304 // expected-note {{found near match 'b1->mu1_'}}
1309 } // end namespace thread_annot_lock_18_modified
1311 namespace thread_annot_lock_21 {
1312 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1313 // uses in class definitions.
1318 int a_ GUARDED_BY(mu1_);
1320 int *q PT_GUARDED_BY(mu);
1321 Mutex mu1_ ACQUIRED_AFTER(mu);
1325 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1327 int res GUARDED_BY(mu) = 5;
1333 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1334 // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
1335 // expected-note {{found near match 'b3->mu1_'}}
1336 *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1337 // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1338 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1339 // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
1340 // expected-note {{found near match 'b3->mu1_'}}
1341 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1343 b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1344 x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1347 } // end namespace thread_annot_lock_21
1349 namespace thread_annot_lock_35_modified {
1350 // Test the analyzer's ability to distinguish the lock field of different
1355 int a_ GUARDED_BY(lock_);
1358 void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1359 Foo *new_foo = new Foo;
1363 child->Func(new_foo); // There shouldn't be any warning here as the
1364 // acquired lock is not in child.
1366 // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
1367 // expected-note {{found near match 'lock_'}}
1369 // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
1370 // expected-note {{found near match 'lock_'}}
1374 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1382 Foo *child = new Foo;
1385 } // end namespace thread_annot_lock_35_modified
1387 namespace thread_annot_lock_36_modified {
1388 // Modified to move the annotations to function defns.
1389 // Test the analyzer's ability to distinguish the lock field of different
1394 int a_ GUARDED_BY(lock_);
1397 void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1398 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1401 void Foo::Func(Foo* child) {
1402 Foo *new_foo = new Foo;
1406 child->lock_.Lock();
1407 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1410 child->lock_.Unlock();
1415 void Foo::bar(int y) {
1423 Foo *child = new Foo;
1426 } // end namespace thread_annot_lock_36_modified
1429 namespace thread_annot_lock_42 {
1430 // Test support of multiple lock attributes of the same kind on a decl.
1433 Mutex mu1, mu2, mu3;
1434 int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1435 int y GUARDED_BY(mu2);
1437 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1444 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1446 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1447 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1455 foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1456 // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1458 } // end namespace thread_annot_lock_42
1460 namespace thread_annot_lock_46 {
1461 // Test the support for annotations on virtual functions.
1464 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1465 virtual void func2() LOCKS_EXCLUDED(mu_);
1469 class Child : public Base {
1471 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1472 virtual void func2() LOCKS_EXCLUDED(mu_);
1479 b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1481 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1484 c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1486 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1489 } // end namespace thread_annot_lock_46
1491 namespace thread_annot_lock_67_modified {
1492 // Modified: attributes on definitions moved to declarations
1493 // Test annotations on out-of-line definitions of member functions where the
1494 // annotations refer to locks that are also data members in the class.
1500 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1501 int data GUARDED_BY(mu1);
1506 int Foo::method1(int i) {
1513 a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1514 // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1515 // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1516 // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1518 } // end namespace thread_annot_lock_67_modified
1521 namespace substitution_test {
1526 void lockData() __attribute__((exclusive_lock_function(mu)));
1527 void unlockData() __attribute__((unlock_function(mu)));
1529 void doSomething() __attribute__((exclusive_locks_required(mu))) { }
1535 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
1536 void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
1542 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
1544 void bar1(MyData* d) {
1550 void bar2(MyData* d) {
1557 void bar3(MyData* d1, MyData* d2) {
1559 dlr.lockData(d1); // expected-note {{mutex acquired here}}
1560 dlr.unlockData(d2); // \
1561 // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1562 } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
1564 void bar4(MyData* d1, MyData* d2) {
1568 // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
1569 // expected-note {{found near match 'd1->mu'}}
1573 } // end namespace substituation_test
1577 namespace constructor_destructor_tests {
1579 int myVar GUARDED_BY(fooMu);
1583 Foo() __attribute__((exclusive_lock_function(fooMu))) { }
1584 ~Foo() __attribute__((unlock_function(fooMu))) { }
1594 namespace template_member_test {
1596 struct S { int n; };
1599 S *s GUARDED_BY(this->m);
1608 template<typename U>
1609 struct IndirectLock {
1610 int DoNaughtyThings(T *t) {
1611 u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1612 return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
1616 template struct IndirectLock<int>; // expected-note {{here}}
1623 V *p GUARDED_BY(this->m);
1625 template<typename U> struct W {
1628 v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1631 template struct W<int>; // expected-note {{here}}
1635 namespace test_scoped_lockable {
1637 struct TestScopedLockable {
1640 int a __attribute__((guarded_by(mu1)));
1641 int b __attribute__((guarded_by(mu2)));
1646 MutexLock mulock(&mu1);
1651 ReaderMutexLock mulock1(&mu1);
1653 MutexLock mulock2a(&mu2);
1657 MutexLock mulock2b(&mu2);
1663 MutexLock mulock_a(&mu1);
1664 MutexLock mulock_b(&mu1); // \
1665 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1669 MutexLock mulock1(&mu1), mulock2(&mu2);
1675 DoubleMutexLock mulock(&mu1, &mu2);
1681 } // end namespace test_scoped_lockable
1684 namespace FunctionAttrTest {
1689 int a GUARDED_BY(mu_);
1694 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1697 foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1700 fooObj.mu_.Unlock();
1703 }; // end namespace FunctionAttrTest
1706 namespace TryLockTest {
1708 struct TestTryLock {
1710 int a GUARDED_BY(mu);
1721 if (!mu.TryLock()) return;
1727 bool b = mu.TryLock();
1735 bool b = mu.TryLock();
1742 while (mu.TryLock()) {
1749 bool b = mu.TryLock();
1757 bool b1 = mu.TryLock();
1766 // Test use-def chains: join points
1768 bool b = mu.TryLock();
1772 if (b) { // b should be unknown at this point, because of the join point
1773 a = 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1775 if (b2) { // b2 should be known at this point.
1781 // Test use-def-chains: back edges
1783 bool b = mu.TryLock();
1785 for (int i = 0; i < 10; ++i);
1787 if (b) { // b is still known, because the loop doesn't alter it
1793 // Test use-def chains: back edges
1795 bool b = mu.TryLock();
1798 if (b) { // b should be uknown at this point b/c of the loop
1799 a = 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1805 // Test merge of exclusive trylock
1818 // Test merge of shared trylock
1821 if (!mu.ReaderTryLock())
1830 }; // end TestTrylock
1832 } // end namespace TrylockTest
1835 namespace TestTemplateAttributeInstantiation {
1840 int a GUARDED_BY(mu_);
1845 int a GUARDED_BY(mu_);
1852 // Test non-dependent expressions in attributes on template functions
1854 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
1858 // Test dependent expressions in attributes on template functions
1860 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
1872 // Test non-dependent expression in ordinary method on template class
1873 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
1877 // Test dependent expressions in ordinary methods on template class
1878 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
1882 // Test dependent expressions in template method in template class
1884 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
1894 // Test dependent guarded_by
1895 T data GUARDED_BY(mu_);
1897 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1916 bt.fooBase.mu_.Lock();
1917 bt.fooBaseT.mu_.Lock();
1927 // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
1928 // expected-note {{found near match 'bt.fooBase.mu_'}}
1930 bt.fooBase.mu_.Unlock();
1931 bt.fooBaseT.mu_.Unlock();
1936 // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
1947 // Test dependent guarded_by
1948 T data GUARDED_BY(mu_);
1949 static T static_data GUARDED_BY(static_mu_);
1951 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
1952 this->data = other->data;
1956 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
1957 this->data = otherT->data;
1967 static Mutex static_mu_;
1970 void testDelayed() {
1971 CellDelayed<int> celld;
1972 CellDelayed<int> celld2;
1977 celld.fooEx(&celld2);
1978 celld.fooExT(&celld2);
1980 celld2.mu_.Unlock();
1984 }; // end namespace TestTemplateAttributeInstantiation
1987 namespace FunctionDeclDefTest {
1992 int a GUARDED_BY(mu_);
1994 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1997 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1998 void Foo::foo1(Foo *f_defined) {
2004 myfoo.foo1(&myfoo); // \
2005 // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2013 namespace GoingNative {
2015 struct __attribute__((lockable)) mutex {
2016 void lock() __attribute__((exclusive_lock_function));
2017 void unlock() __attribute__((unlock_function));
2031 continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
2035 m.lock(); // expected-note {{mutex acquired here}}
2044 namespace FunctionDefinitionTest {
2050 void foo3(Foo *other);
2053 void fooT1(const T& dummy1);
2056 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2059 int a GUARDED_BY(mu_);
2068 T a GUARDED_BY(mu_);
2072 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2076 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2080 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2085 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2089 /* TODO -- uncomment with template instantiation of attributes.
2091 void Foo::fooT2(const T& dummy2) {
2096 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2101 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2105 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2106 void fooF3(Foo *f) {
2111 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2120 // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2121 myFoo.foo3(&myFoo); // \
2122 // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2123 myFoo.fooT1(dummy); // \
2124 // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
2126 myFoo.fooT2(dummy); // \
2127 // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
2130 // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2132 // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2134 // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2150 // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2153 } // end namespace FunctionDefinitionTest
2156 namespace SelfLockingTest {
2158 class LOCKABLE MyLock {
2160 int foo GUARDED_BY(this);
2162 void lock() EXCLUSIVE_LOCK_FUNCTION();
2163 void unlock() UNLOCK_FUNCTION();
2165 void doSomething() {
2166 this->lock(); // allow 'this' as a lock expression
2172 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2178 // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
2183 class LOCKABLE MyLock2 {
2186 int foo GUARDED_BY(this);
2188 // don't check inside lock and unlock functions
2189 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
2190 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
2192 // don't check inside constructors and destructors
2193 MyLock2() { foo = 1; }
2194 ~MyLock2() { foo = 0; }
2198 } // end namespace SelfLockingTest
2201 namespace InvalidNonstatic {
2203 // Forward decl here causes bogus "invalid use of non-static data member"
2204 // on reference to mutex_ in guarded_by attribute.
2210 int foo __attribute__((guarded_by(mutex_)));
2213 } // end namespace InvalidNonStatic
2216 namespace NoReturnTest {
2219 void fatal() __attribute__((noreturn));
2224 MutexLock lock(&mu_);
2231 } // end namespace NoReturnTest
2234 namespace TestMultiDecl {
2238 int GUARDED_BY(mu_) a;
2239 int GUARDED_BY(mu_) b, c;
2243 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2245 // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2247 // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2254 } // end namespace TestMultiDecl
2257 namespace WarnNoDecl {
2260 void foo(int a); __attribute__(( // \
2261 // expected-warning {{declaration does not declare anything}}
2262 exclusive_locks_required(a))); // \
2263 // expected-warning {{attribute exclusive_locks_required ignored}}
2266 } // end namespace WarnNoDecl
2270 namespace MoreLockExpressions {
2275 int a GUARDED_BY(mu_);
2283 Foo& getFoo() { return *f; }
2284 Foo& getFoo2(int c) { return *f; }
2285 Foo& getFoo3(int c, int d) { return *f; }
2287 Foo& getFooey() { return *f; }
2290 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
2300 bar.getFoo().mu_.Lock();
2302 bar.getFoo().mu_.Unlock();
2304 (bar.getFoo().mu_).Lock(); // test parenthesis
2306 (bar.getFoo().mu_).Unlock();
2308 bar.getFoo2(a).mu_.Lock();
2309 bar.getFoo2(a).a = 0;
2310 bar.getFoo2(a).mu_.Unlock();
2312 bar.getFoo3(a, b).mu_.Lock();
2313 bar.getFoo3(a, b).a = 0;
2314 bar.getFoo3(a, b).mu_.Unlock();
2316 getBarFoo(bar, a).mu_.Lock();
2317 getBarFoo(bar, a).a = 0;
2318 getBarFoo(bar, a).mu_.Unlock();
2320 bar.getFoo2(10).mu_.Lock();
2321 bar.getFoo2(10).a = 0;
2322 bar.getFoo2(10).mu_.Unlock();
2324 bar.getFoo2(a + 1).mu_.Lock();
2325 bar.getFoo2(a + 1).a = 0;
2326 bar.getFoo2(a + 1).mu_.Unlock();
2328 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2329 (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
2330 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2341 bar.getFoo().mu_.Lock();
2342 bar.getFooey().a = 0; // \
2343 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
2344 // expected-note {{found near match 'bar.getFoo().mu_'}}
2345 bar.getFoo().mu_.Unlock();
2347 bar.getFoo2(a).mu_.Lock();
2348 bar.getFoo2(b).a = 0; // \
2349 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
2350 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2351 bar.getFoo2(a).mu_.Unlock();
2353 bar.getFoo3(a, b).mu_.Lock();
2354 bar.getFoo3(a, c).a = 0; // \
2355 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \
2356 // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}
2357 bar.getFoo3(a, b).mu_.Unlock();
2359 getBarFoo(bar, a).mu_.Lock();
2360 getBarFoo(bar, b).a = 0; // \
2361 // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \
2362 // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}
2363 getBarFoo(bar, a).mu_.Unlock();
2365 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2366 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2367 // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \
2368 // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}
2369 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2373 } // end namespace MoreLockExpressions
2376 namespace TrylockJoinPoint {
2393 } // end namespace TrylockJoinPoint
2396 namespace LockReturned {
2400 int a GUARDED_BY(mu_);
2401 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2402 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2404 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2406 Mutex* getMu() LOCK_RETURNED(mu_);
2410 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2414 // Calls getMu() directly to lock and unlock
2415 void test1(Foo* f1, Foo* f2) {
2416 f1->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2417 f1->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2419 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2420 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2421 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2423 f1->getMu()->Lock();
2428 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
2429 // expected-note {{found near match 'f1->mu_'}}
2431 Foo::getMu(f2)->Lock();
2433 Foo::getMu(f2)->Unlock();
2437 f1->getMu()->Unlock();
2441 Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2443 class Bar : public Foo {
2445 int b GUARDED_BY(getMu());
2446 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2447 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2449 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2450 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2455 // Use getMu() within other attributes.
2456 // This requires at lest levels of substitution, more in the case of
2457 void test2(Bar* b1, Bar* b2) {
2458 b1->b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2459 b1->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2460 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2461 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2462 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2463 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2465 b1->getMu()->Lock();
2470 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
2471 // // expected-note {{found near match 'b1->mu_'}}
2473 b2->getMu()->Lock();
2476 b2->getMu()->Unlock();
2481 b1->getMu()->Unlock();
2485 // Sanity check -- lock the mutex directly, but use attributes that call getMu()
2486 // Also lock the mutex using getFooMu, which calls a lock_returned function.
2487 void test3(Bar* b1, Bar* b2) {
2492 getFooMu(b2)->Lock();
2494 getFooMu(b2)->Unlock();
2502 } // end namespace LockReturned
2505 namespace ReleasableScopedLock {
2510 int a GUARDED_BY(mu_);
2521 ReleasableMutexLock rlock(&mu_);
2526 ReleasableMutexLock rlock(&mu_);
2527 if (c) { // test join point -- held/not held during release
2533 ReleasableMutexLock rlock(&mu_);
2536 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2540 ReleasableMutexLock rlock(&mu_);
2542 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2546 ReleasableMutexLock rlock(&mu_);
2550 // no warning on join point for managed lock.
2551 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2555 } // end namespace ReleasableScopedLock
2558 namespace TrylockFunctionTest {
2566 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
2569 bool Foo::lockBoth() {
2570 if (!mu1_.TryLock())
2584 } // end namespace TrylockFunctionTest
2588 namespace DoubleLockBug {
2593 int a GUARDED_BY(mu_);
2595 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2596 int foo2() SHARED_LOCKS_REQUIRED(mu_);
2600 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2604 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
2612 namespace UnlockBug {
2618 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2620 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2623 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2625 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2628 } // end namespace UnlockBug
2632 namespace FoolishScopedLockableBug {
2634 class SCOPED_LOCKABLE WTF_ScopedLockable {
2636 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2638 // have to call release() manually;
2639 ~WTF_ScopedLockable();
2641 void release() UNLOCK_FUNCTION();
2647 int a GUARDED_BY(mu_);
2653 WTF_ScopedLockable wtf(&mu_);
2658 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2659 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
2663 WTF_ScopedLockable wtf(&mu_);
2673 WTF_ScopedLockable wtf(&mu_);
2680 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2682 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2689 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2691 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2695 } // end namespace FoolishScopedLockableBug
2699 namespace TemporaryCleanupExpr {
2702 int a GUARDED_BY(getMutexPtr().get());
2704 SmartPtr<Mutex> getMutexPtr();
2712 ReaderMutexLock lock(getMutexPtr().get());
2715 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
2718 } // end namespace TemporaryCleanupExpr
2722 namespace SmartPointerTests {
2726 SmartPtr<Mutex> mu_;
2727 int a GUARDED_BY(mu_);
2728 int b GUARDED_BY(mu_.get());
2729 int c GUARDED_BY(*mu_);
2731 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
2732 void Unlock() UNLOCK_FUNCTION(mu_);
2746 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2747 b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2748 c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2773 mu_.get()->Unlock();
2778 MutexLock lock(mu_.get());
2786 MutexLock lock(&(*mu_));
2817 mu_.get()->Unlock();
2832 mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
2833 (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
2834 mu_.get()->Unlock();
2835 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2850 foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
2851 (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
2852 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
2870 foo.get()->mu_->Unlock();
2875 MutexLock lock(foo->mu_.get());
2881 } // end namespace SmartPointerTests
2885 namespace DuplicateAttributeTest {
2887 class LOCKABLE Foo {
2892 int a GUARDED_BY(mu1_);
2893 int b GUARDED_BY(mu2_);
2894 int c GUARDED_BY(mu3_);
2896 void lock() EXCLUSIVE_LOCK_FUNCTION();
2897 void unlock() UNLOCK_FUNCTION();
2899 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
2900 void slock1() SHARED_LOCK_FUNCTION(mu1_);
2901 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2903 EXCLUSIVE_LOCK_FUNCTION(mu1_)
2904 EXCLUSIVE_LOCK_FUNCTION(mu2_)
2905 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2907 void unlock1() UNLOCK_FUNCTION(mu1_);
2908 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2910 UNLOCK_FUNCTION(mu1_)
2911 UNLOCK_FUNCTION(mu2_)
2912 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2916 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
2917 void Foo::unlock() UNLOCK_FUNCTION() { }
2919 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
2923 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
2927 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
2933 void Foo::locklots()
2934 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
2935 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
2941 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
2945 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
2951 void Foo::unlocklots()
2952 UNLOCK_FUNCTION(mu1_, mu2_)
2953 UNLOCK_FUNCTION(mu2_, mu3_) {
2966 foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
2968 foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
2979 foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
2982 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
2993 foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
2996 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3011 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3012 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3013 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3019 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3020 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3021 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3034 foo.locklots(); // \
3035 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3036 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3037 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3042 foo.unlocklots(); // \
3043 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3044 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3045 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3048 } // end namespace DuplicateAttributeTest
3052 namespace TryLockEqTest {
3056 int a GUARDED_BY(mu_);
3059 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3060 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3061 void unlock() UNLOCK_FUNCTION(mu_);
3069 if (tryLockMutexP() == 0) {
3070 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3076 if (tryLockMutexP() != 0) {
3081 if (0 != tryLockMutexP()) {
3086 if (!(tryLockMutexP() == 0)) {
3091 if (tryLockMutexI() == 0) {
3092 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3098 if (0 == tryLockMutexI()) {
3099 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3105 if (tryLockMutexI() == 1) {
3110 if (mu_.TryLock() == false) {
3111 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3117 if (mu_.TryLock() == true) {
3122 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3125 #if __has_feature(cxx_nullptr)
3126 if (tryLockMutexP() == nullptr) {
3127 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3135 } // end namespace TryLockEqTest
3138 namespace ExistentialPatternMatching {
3145 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3146 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3150 int a GUARDED_BY(&Graph::mu_);
3152 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3155 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3163 n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3164 n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3170 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3176 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3182 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3192 g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3196 } // end namespace ExistentialPatternMatching
3199 namespace StringIgnoreTest {
3204 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3205 void unlock() UNLOCK_FUNCTION("");
3206 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3207 void roober() SHARED_LOCKS_REQUIRED("");
3211 class Bar : public Foo {
3221 } // end namespace StringIgnoreTest
3224 namespace LockReturnedScopeFix {
3231 const Mutex& getLock(const Inner* i);
3233 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3234 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3235 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3241 struct Base::Inner {
3243 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3247 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3252 void Base::foo(Inner* i) {
3256 void Base::bar(Inner* i) {
3267 } // end namespace LockReturnedScopeFix
3270 namespace TrylockWithCleanups {
3274 int a GUARDED_BY(mu_);
3277 Foo* GetAndLockFoo(const MyString& s)
3278 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3280 static void test() {
3281 Foo* lt = GetAndLockFoo("foo");
3287 } // end namespace TrylockWithCleanups
3290 namespace UniversalLock {
3296 int a GUARDED_BY(mu_);
3297 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3298 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3303 beginNoWarnOnReads();
3308 beginNoWarnOnWrites();
3311 endNoWarnOnWrites();
3314 // don't warn on joins with universal lock
3317 beginNoWarnOnWrites();
3320 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3321 endNoWarnOnWrites(); // \
3322 // expected-warning {{releasing mutex '*' that was not held}}
3326 // make sure the universal lock joins properly
3330 beginNoWarnOnWrites();
3333 beginNoWarnOnWrites();
3337 endNoWarnOnWrites();
3342 // combine universal lock with other locks
3344 beginNoWarnOnWrites();
3347 endNoWarnOnWrites();
3350 beginNoWarnOnWrites();
3351 endNoWarnOnWrites();
3355 beginNoWarnOnWrites();
3357 endNoWarnOnWrites();
3361 } // end namespace UniversalLock
3364 namespace TemplateLockReturned {
3369 virtual void baseMethod() = 0;
3370 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
3373 int a GUARDED_BY(mutex_);
3377 class Derived : public BaseT<int> {
3379 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
3384 } // end namespace TemplateLockReturned
3387 namespace ExprMatchingBugFix {
3399 Bar(Foo* f) : foo(f) { }
3403 Nested(Foo* f) : foo(f) { }
3405 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3415 Nested *n = new Nested(foo);
3423 }; // end namespace ExprMatchingBugfix
3426 namespace ComplexNameTest {
3432 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
3433 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
3435 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
3442 Bar() LOCKS_EXCLUDED(mu_) { }
3443 ~Bar() LOCKS_EXCLUDED(mu_) { }
3445 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
3450 Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
3451 int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
3452 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
3458 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
3459 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
3460 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
3464 }; // end namespace ComplexNameTest
3467 namespace UnreachableExitTest {
3472 ~FemmeFatale() __attribute__((noreturn));
3475 void exitNow() __attribute__((noreturn));
3476 void exitDestruct(const MyString& ms) __attribute__((noreturn));
3480 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3484 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3490 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3499 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3500 exitDestruct("foo");
3503 } // end namespace UnreachableExitTest
3506 namespace VirtualMethodCanonicalizationTest {
3510 virtual Mutex* getMutex() = 0;
3513 class Base2 : public Base {
3518 class Base3 : public Base2 {
3523 class Derived : public Base3 {
3525 Mutex* getMutex(); // overrides Base::getMutex()
3528 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3530 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3534 } // end namespace VirtualMethodCanonicalizationTest
3537 namespace TemplateFunctionParamRemapTest {
3548 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3554 void Foo::elr(Cell<T>* c1) { }
3559 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3564 void globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3567 void globalELR(Cell<T>* c1) { }
3571 globalELR(&cell); // \
3572 // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
3577 void globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3579 // second declaration
3581 void globalELR2(Cell<T>* c2);
3584 void globalELR2(Cell<T>* c3) { }
3586 // re-declaration after definition
3588 void globalELR2(Cell<T>* c4);
3590 void globalTest2() {
3592 globalELR2(&cell); // \
3593 // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
3600 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3604 void FooT<T>::elr(Cell<T>* c1) { }
3609 foo.elr(&cell); // \
3610 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3613 } // end namespace TemplateFunctionParamRemapTest
3616 namespace SelfConstructorTest {
3620 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3621 ~SelfLock() UNLOCK_FUNCTION(mu_);
3623 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3628 class LOCKABLE SelfLock2 {
3630 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
3631 ~SelfLock2() UNLOCK_FUNCTION();
3633 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3647 } // end namespace SelfConstructorTest
3650 namespace MultipleAttributeTest {
3655 int a GUARDED_BY(mu1_);
3656 int b GUARDED_BY(mu2_);
3657 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_);
3658 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
3660 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_)
3661 EXCLUSIVE_LOCKS_REQUIRED(mu2_);
3662 void foo2() SHARED_LOCKS_REQUIRED(mu1_)
3663 SHARED_LOCKS_REQUIRED(mu2_);
3664 void foo3() LOCKS_EXCLUDED(mu1_)
3665 LOCKS_EXCLUDED(mu2_);
3666 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
3667 EXCLUSIVE_LOCK_FUNCTION(mu2_);
3668 void readerlock() SHARED_LOCK_FUNCTION(mu1_)
3669 SHARED_LOCK_FUNCTION(mu2_);
3670 void unlock() UNLOCK_FUNCTION(mu1_)
3671 UNLOCK_FUNCTION(mu2_);
3672 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
3673 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
3674 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
3675 SHARED_TRYLOCK_FUNCTION(true, mu2_);
3676 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
3677 ASSERT_EXCLUSIVE_LOCK(mu2_);
3678 void assertShared() ASSERT_SHARED_LOCK(mu1_)
3679 ASSERT_SHARED_LOCK(mu2_);
3683 void testAssertShared();
3696 void Foo::foo3() { }
3697 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
3698 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
3699 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
3700 bool Foo::trylock() { return true; }
3701 bool Foo::readertrylock() { return true; }
3706 foo1(); // expected-warning {{}}
3707 c = 0; // expected-warning {{}}
3708 *d = 0; // expected-warning {{}}
3712 foo2(); // expected-warning {{}}
3713 int x = c; // expected-warning {{}}
3714 int y = *d; // expected-warning {{}}
3718 foo3(); // expected-warning {{}}
3736 if (readertrylock()) {
3742 // Force duplication of attributes
3743 void Foo::assertBoth() { }
3744 void Foo::assertShared() { }
3746 void Foo::testAssert() {
3752 void Foo::testAssertShared() {
3758 } // end namespace MultipleAttributeTest
3761 namespace GuardedNonPrimitiveTypeTest {
3766 Data(int i) : dat(i) { }
3768 int getValue() const { return dat; }
3769 void setValue(int i) { dat = i; }
3771 int operator[](int i) const { return dat; }
3772 int& operator[](int i) { return dat; }
3774 void operator()() { }
3783 DataCell(const Data& d) : dat(d) { }
3790 void showDataCell(const DataCell& dc);
3795 // method call tests
3797 data_.setValue(0); // FIXME -- should be writing \
3798 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3799 int a = data_.getValue(); // \
3800 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3802 datap1_->setValue(0); // FIXME -- should be writing \
3803 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
3804 a = datap1_->getValue(); // \
3805 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
3807 datap2_->setValue(0); // FIXME -- should be writing \
3808 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3809 a = datap2_->getValue(); // \
3810 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3812 (*datap2_).setValue(0); // FIXME -- should be writing \
3813 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3814 a = (*datap2_).getValue(); // \
3815 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3819 datap1_->setValue(1);
3820 datap2_->setValue(1);
3824 a = data_.getValue();
3825 datap1_->setValue(0); // reads datap1_, writes *datap1_
3826 a = datap1_->getValue();
3827 a = datap2_->getValue();
3833 data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
3834 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
3835 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3836 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
3837 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3838 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3839 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
3840 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3841 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3843 data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3844 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3846 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3849 // const operator tests
3850 void test3() const {
3851 Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3854 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3855 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3857 int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3862 Data data_ GUARDED_BY(mu_);
3863 Data* datap1_ GUARDED_BY(mu_);
3864 Data* datap2_ PT_GUARDED_BY(mu_);
3867 } // end namespace GuardedNonPrimitiveTypeTest
3870 namespace GuardedNonPrimitive_MemberAccess {
3885 Cell c GUARDED_BY(cell_mu_);
3886 Cell* cp PT_GUARDED_BY(cell_mu_);
3897 Foo foo GUARDED_BY(mu_);
3898 Foo* foop PT_GUARDED_BY(mu_);
3901 foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
3903 int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
3904 foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
3906 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3907 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
3909 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3910 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
3912 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
3913 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
3914 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
3915 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
3917 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3918 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3919 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3920 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
3922 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3923 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3924 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3925 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
3929 } // namespace GuardedNonPrimitive_MemberAccess
3932 namespace TestThrowExpr {
3948 } // end namespace TestThrowExpr
3951 namespace UnevaluatedContextTest {
3953 // parse attribute expressions in an unevaluated context.
3955 static inline Mutex* getMutex1();
3956 static inline Mutex* getMutex2();
3958 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3960 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3962 } // end namespace UnevaluatedContextTest
3965 namespace LockUnlockFunctionTest {
3967 // Check built-in lock functions
3968 class LOCKABLE MyLockable {
3970 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
3971 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
3972 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
3981 // Correct lock/unlock functions
3982 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
3986 void readerLock() SHARED_LOCK_FUNCTION(mu_) {
3990 void unlock() UNLOCK_FUNCTION(mu_) {
3994 // Check failure to lock.
3995 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3998 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4000 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4003 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4005 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4008 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4010 // Check locking the wrong thing.
4011 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4012 mu2_.Lock(); // expected-note {{mutex acquired here}}
4013 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4014 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4017 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4018 mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
4019 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4020 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4023 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4024 mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
4025 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4032 } // end namespace LockUnlockFunctionTest
4035 namespace AssertHeldTest {
4040 int a GUARDED_BY(mu_);
4050 mu_.AssertReaderHeld();
4052 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4066 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4072 void test5() UNLOCK_FUNCTION(mu_) {
4080 } // should this be a warning?
4111 mu_.Lock(); // expected-note {{mutex acquired here}}
4113 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4117 mu_.Lock(); // expected-note {{mutex acquired here}}
4122 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4124 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
4133 } // end namespace AssertHeldTest
4136 namespace LogicalConditionalTryLock {
4141 int a GUARDED_BY(mu);
4147 if (c && mu.TryLock()) {
4154 bool b = mu.TryLock();
4162 if (c || !mu.TryLock())
4169 while (c && mu.TryLock()) {
4178 if (newc() || !mu.TryLock())
4190 } while (newc() && mu.TryLock());
4194 for (bool b = mu.TryLock(); c && b;) {
4201 if (c && newc() && mu.TryLock()) {
4208 if (!(c && newc() && mu.TryLock()))
4215 if (!(c || !mu.TryLock())) {
4222 } // end namespace LogicalConditionalTryLock
4226 namespace PtGuardedByTest {
4236 // This mainly duplicates earlier tests, but just to make sure...
4237 class PtGuardedBySanityTest {
4240 int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4241 Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4242 int sa[10] GUARDED_BY(mu1);
4243 Cell sc[10] GUARDED_BY(mu1);
4247 if (a == 0) doSomething(); // OK, we don't dereference.
4250 if (sa[0] == 42) doSomething();
4252 if (sc[0].a == 42) doSomething();
4259 if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4260 *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4262 if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4263 c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4265 if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4266 (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4268 if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4269 a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4270 if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4271 c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4277 if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4278 *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4280 if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4281 c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4283 if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4284 (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4286 if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4287 a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4288 if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4289 c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4293 void test4() { // Literal arrays
4294 if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4295 sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4296 if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4297 sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4299 if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4300 *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4301 if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4302 (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4303 if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4304 sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4308 mu1.ReaderLock(); // OK -- correct use.
4310 if (*a == 0) doSomething();
4313 if (c->a == 0) doSomething();
4316 if ((*c).a == 0) doSomething();
4324 class SmartPtr_PtGuardedBy_Test {
4327 SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4328 SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4335 if (*sp == 0) doSomething();
4339 if (sp[0] == 0) doSomething();
4349 sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4350 if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4351 *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4352 sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4354 if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4355 sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4356 if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4357 sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4366 if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4367 *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4368 sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4370 if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4371 sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4372 if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4373 sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4379 } // end namespace PtGuardedByTest
4382 namespace NonMemberCalleeICETest {
4386 (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
4389 void RunHelper() __attribute__((exclusive_locks_required(M)));
4393 } // end namespace NonMemberCalleeICETest
4396 namespace pt_guard_attribute_type {
4397 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
4398 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
4401 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4402 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4404 typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4405 typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4407 } // end namespace pt_guard_attribute_type
4410 namespace ThreadAttributesOnLambdas {
4415 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4418 auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4422 auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
4426 auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4430 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
4437 } // end namespace ThreadAttributesOnLambdas
4441 namespace AttributeExpressionCornerCases {
4444 int a GUARDED_BY(getMu());
4446 Mutex* getMu() LOCK_RETURNED("");
4447 Mutex* getUniv() LOCK_RETURNED("*");
4453 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
4457 void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);
4466 struct MuCell { Mutex* mu; };
4468 MyMap<MyString, Mutex*> map;
4469 MyMap<MyString, MuCell> mapCell;
4471 int a GUARDED_BY(map["foo"]);
4472 int b GUARDED_BY(mapCell["foo"].mu);
4477 map["foo"]->Unlock();
4481 mapCell["foo"].mu->Lock();
4483 mapCell["foo"].mu->Unlock();
4488 class PreciseSmartPtr {
4490 int val GUARDED_BY(mu);
4492 static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {
4494 bool result = (a.val == b.val); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
4495 // expected-note {{found near match 'a.mu'}}
4502 class SmartRedeclare {
4504 int val GUARDED_BY(mu);
4506 void test() EXCLUSIVE_LOCKS_REQUIRED(mu);
4507 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4508 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4512 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {
4516 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {
4520 void SmartRedeclare::test3() {
4525 namespace CustomMutex {
4528 class LOCKABLE BaseMutex { };
4529 class DerivedMutex : public BaseMutex { };
4531 void customLock(const BaseMutex *m) EXCLUSIVE_LOCK_FUNCTION(m);
4532 void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);
4534 static struct DerivedMutex custMu;
4536 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }
4539 customLock(reinterpret_cast<BaseMutex*>(&custMu)); // ignore casts
4540 doSomethingRequiringLock();
4541 customUnlock(reinterpret_cast<BaseMutex*>(&custMu));
4544 } // end namespace CustomMutex
4546 } // end AttributeExpressionCornerCases
4549 namespace ScopedLockReturnedInvalid {
4553 Mutex* getMutex(Opaque* o) LOCK_RETURNED("");
4555 void test(Opaque* o) {
4556 MutexLock lock(getMutex(o));
4559 } // end namespace ScopedLockReturnedInvalid
4562 namespace NegativeRequirements {
4566 int a GUARDED_BY(mu);
4569 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4579 int a GUARDED_BY(mu);
4583 mu.Lock(); // warning? needs !mu?
4584 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
4590 bar2(); // expected-warning {{calling function 'bar2' requires holding '!mu'}}
4593 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4597 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4605 b.baz(); // no warning -- in different class.
4609 } // end namespace NegativeRequirements
4612 namespace NegativeThreadRoles {
4614 typedef int __attribute__((capability("role"))) ThreadRole;
4616 void acquire(ThreadRole R) __attribute__((exclusive_lock_function(R))) __attribute__((no_thread_safety_analysis)) {}
4617 void release(ThreadRole R) __attribute__((unlock_function(R))) __attribute__((no_thread_safety_analysis)) {}
4619 ThreadRole FlightControl, Logger;
4621 extern void enque_log_msg(const char *msg);
4622 void log_msg(const char *msg) {
4626 void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}
4627 void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}
4629 void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {
4630 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */
4631 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
4634 void spawn_fake_flight_control_thread(void) {
4635 acquire(FlightControl);
4636 flight_control_entry();
4637 release(FlightControl);
4640 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
4641 void logger_entry(void) __attribute__((requires_capability(Logger))) {
4644 while ((msg = deque_log_msg())) {
4649 void spawn_fake_logger_thread(void) {
4656 spawn_fake_flight_control_thread();
4657 spawn_fake_logger_thread();
4660 ; /* Pretend to dispatch things. */
4665 } // end namespace NegativeThreadRoles
4668 namespace AssertSharedExclusive {
4674 int a GUARDED_BY(mu);
4676 void test() SHARED_LOCKS_REQUIRED(mu) {
4683 } // end namespace AssertSharedExclusive
4686 namespace RangeBasedForAndReferences {
4694 int a GUARDED_BY(mu);
4695 MyContainer<int> cntr GUARDED_BY(mu);
4696 MyStruct s GUARDED_BY(mu);
4697 int arr[10] GUARDED_BY(mu);
4699 void nonref_test() {
4700 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
4701 b = 0; // no warning
4705 auto b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
4706 b = 0; // no warning
4707 auto &c = a; // no warning
4708 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4715 b = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4716 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4717 d = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4720 rs.a = 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
4722 int (&rarr)[10] = arr;
4723 rarr[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
4728 *b = 0; // no expected warning yet
4733 for (int i : cntr) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
4740 } // end namespace RangeBasedForAndReferences
4744 namespace PassByRefTest {
4748 Foo() : a(0), b(0) { }
4753 void operator+(const Foo& f);
4755 void operator[](const Foo& g);
4762 // test top-level functions
4764 void write1(Foo& f);
4765 void write2(int a, Foo& f);
4766 void read1(const Foo& f);
4767 void read2(int a, const Foo& f);
4768 void destroy(Foo&& f);
4770 void operator/(const Foo& f, const Foo& g);
4771 void operator*(const Foo& f, const Foo& g);
4779 Foo foo GUARDED_BY(mu);
4780 Foo foo2 GUARDED_BY(mu);
4781 Foo* foop PT_GUARDED_BY(mu);
4782 SmartPtr<Foo> foosp PT_GUARDED_BY(mu);
4785 void mwrite1(Foo& f);
4786 void mwrite2(int a, Foo& f);
4787 void mread1(const Foo& f);
4788 void mread2(int a, const Foo& f);
4791 static void smwrite1(Foo& f);
4792 static void smwrite2(int a, Foo& f);
4793 static void smread1(const Foo& f);
4794 static void smread2(int a, const Foo& f);
4796 void operator<<(const Foo& f);
4799 copy(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
4800 write1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4801 write2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4802 read1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4803 read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4804 destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4806 mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4807 mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4808 mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4809 mread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4811 smwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4812 smwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4813 smread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4814 smread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4816 foo + foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4817 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4818 foo / foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4819 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4820 foo * foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4821 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4822 foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4823 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4824 (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4826 copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
4827 write1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4828 write2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4829 read1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4830 read2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4831 destroy(mymove(*foop)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4833 copy(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4834 write1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4835 write2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4836 read1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4837 read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4838 destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4840 // TODO -- these require better smart pointer handling.
4842 write1(*foosp.get());
4843 write2(10, *foosp.get());
4844 read1(*foosp.get());
4845 read2(10, *foosp.get());
4846 destroy(mymove(*foosp.get()));
4851 } // end namespace PassByRefTest
4854 namespace AcquiredBeforeAfterText {
4857 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
4873 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
4880 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
4885 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {
4890 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
4891 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
4895 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
4899 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }
4901 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }
4907 Mutex mu2 ACQUIRED_AFTER(mu1);
4908 Mutex mu3 ACQUIRED_AFTER(mu1);
4922 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
4929 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
4937 Mutex mu1 ACQUIRED_BEFORE(mu2);
4939 Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);
4956 mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
4964 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
4972 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
4980 // Test transitive DAG traversal with AFTER
4983 Mutex mu2 ACQUIRED_AFTER(mu1);
4984 Mutex mu3 ACQUIRED_AFTER(mu1);
4985 Mutex mu4 ACQUIRED_AFTER(mu2, mu3);
4986 Mutex mu5 ACQUIRED_AFTER(mu4);
4987 Mutex mu6 ACQUIRED_AFTER(mu4);
4988 Mutex mu7 ACQUIRED_AFTER(mu5, mu6);
4989 Mutex mu8 ACQUIRED_AFTER(mu7);
4993 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5000 // Test transitive DAG traversal with BEFORE
5002 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5003 Mutex mu2 ACQUIRED_BEFORE(mu4);
5004 Mutex mu3 ACQUIRED_BEFORE(mu4);
5005 Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);
5006 Mutex mu5 ACQUIRED_BEFORE(mu7);
5007 Mutex mu6 ACQUIRED_BEFORE(mu7);
5008 Mutex mu7 ACQUIRED_BEFORE(mu8);
5013 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5021 Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}}
5022 Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}}
5023 Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}}
5025 Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}}
5026 Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}}
5060 } // end namespace AcquiredBeforeAfterTest
5063 namespace ScopedAdoptTest {
5067 int a GUARDED_BY(mu);
5070 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {
5071 MutexLock slock(&mu, true);
5075 void test2() SHARED_UNLOCK_FUNCTION(mu) {
5076 ReaderMutexLock slock(&mu, true);
5080 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5081 MutexLock slock(&mu, true);
5083 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5085 void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5086 ReaderMutexLock slock(&mu, true);
5088 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5092 } // end namespace ScopedAdoptTest