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
{
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
{
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
{
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
{
48 ReleasableMutexLock(Mutex
*mu
) EXCLUSIVE_LOCK_FUNCTION(mu
);
49 ~ReleasableMutexLock() UNLOCK_FUNCTION();
51 void Release() UNLOCK_FUNCTION();
54 class SCOPED_LOCKABLE DoubleMutexLock
{
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.
72 SmartPtr(T
* p
) : ptr_(p
) { }
73 SmartPtr(const SmartPtr
<T
>& p
) : ptr_(p
.ptr_
) { }
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
]; }
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.
92 MyString(const char* s
);
97 // For testing operator overloading
98 template <class K
, class T
>
101 T
& operator[](const K
& k
);
105 // For testing handling of containers.
112 typedef const T
* const_iterator
;
120 T
& operator[](int i
);
121 const T
& operator[](int i
) const;
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;
140 int x
__attribute__((guarded_by(mu
)));
141 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu
);
144 struct TestingMoreComplexAttributes
{
146 struct { Mutex lock
; } strct
;
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();
184 int x
= sls_guard_var
;
202 int x
= sls_guardby_var
;
235 void sls_fun_good_6() {
249 void sls_fun_good_7() {
264 void sls_fun_good_8() {
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}}
277 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
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() {
287 sls_mu
.Lock(); // expected-note{{mutex acquired here}}
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}}
297 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
299 void sls_fun_bad_6() {
301 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
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() {
316 while (getBool()) { // \
317 expected
-warning
{{expecting mutex
'sls_mu' to be held at start of each loop
}}
324 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
329 void sls_fun_bad_8() {
330 sls_mu
.Lock(); // expected-note{{mutex acquired here}}
333 sls_mu
.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
337 void sls_fun_bad_9() {
340 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
341 // expected-note{{mutex acquired here}}
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}}
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}}
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 // -------------------------------------------//
386 void globalLock() EXCLUSIVE_LOCK_FUNCTION(aa_mu
);
387 void globalUnlock() UNLOCK_FUNCTION(aa_mu
);
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 //--------------------------------------------------//
419 // Test diagnostics for other method names.
421 // FIXME: can't currently check inside constructors and destructors.
423 wmu
.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
424 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
426 wmu
.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
427 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
429 wmu
.Lock(); // expected-note {{mutex acquired here}}
430 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
432 wmu
.Lock(); // expected-note {{mutex acquired here}}
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
)));
447 int *pgb_field
__attribute__((guarded_by(sls_mu2
)))
448 __attribute__((pt_guarded_by(sls_mu
)));
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}}
463 int gb_field
__attribute__((guarded_by(sls_mu
)));
467 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
470 void testNoAnal() NO_THREAD_SAFETY_ANALYSIS
{
475 GBFoo GlobalGBFoo
__attribute__((guarded_by(sls_mu
)));
499 sls_guard_var
= 1; // \
500 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
504 int x
= sls_guard_var
; // \
505 // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
509 sls_guardby_var
= 1; // \
510 // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
514 int x
= sls_guardby_var
; // \
515 // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
520 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
524 int x
= *pgb_gvar
; // \
525 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
530 // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
534 int x
= *pgb_var
; // \
535 // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
541 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
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}}
552 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
555 //-----------------------------------------------//
556 // Warnings on variables with late parsed attributes
557 // ----------------------------------------------//
561 int a
__attribute__((guarded_by(mu
)));
564 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu
) { }
568 // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
570 // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
572 // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
575 int c
__attribute__((guarded_by(mu
)));
582 int a_
__attribute__((guarded_by(mu1_
)));
584 int *q
__attribute__((pt_guarded_by(mu
)));
604 BarA
.FooPointer
->mu
.Lock();
605 BarA
.FooPointer
->a
= 2;
606 BarA
.FooPointer
->mu
.Unlock();
614 // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
615 // expected-note{{found near match 'fooA.mu'}}
623 int res
= b1
.a_
+ b3
->b_
;
625 // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
633 BarA
.FooPointer
->mu
.Lock();
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();
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();
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() {
671 void shared_fun_1() {
672 sls_mu
.ReaderLock(); // \
673 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
677 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
682 void shared_fun_3() {
691 void shared_fun_4() {
696 int x
= sls_guardby_var
;
700 void shared_fun_8() {
703 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
705 sls_mu
.ReaderLock(); // \
706 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
710 void shared_fun_9() {
712 sls_mu
.ExclusiveUnlock();
715 sls_mu
.ReaderUnlock();
718 void shared_fun_10() {
720 sls_mu
.DemoteExclusive();
721 sls_mu
.ReaderUnlock();
724 void shared_fun_11() {
726 sls_mu
.PromoteShared();
730 void shared_bad_0() {
732 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
735 sls_mu
.ReaderLock(); // \
736 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
741 void shared_bad_1() {
744 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
746 sls_mu
.ReaderLock(); // \
747 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
752 void shared_bad_2() {
754 sls_mu
.ReaderLock(); // \
755 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
758 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
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)
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
)));
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
);
835 MyLRFoo
.testShared();
840 sls_mu2
.ReaderLock();
841 MyLRFoo
.testShared();
855 void es_fun_8() NO_THREAD_SAFETY_ANALYSIS
;
861 void es_fun_9() SHARED_LOCKS_REQUIRED(aa_mu
);
866 void es_fun_10() EXCLUSIVE_LOCKS_REQUIRED(aa_mu
);
872 Bar
.aa_elr_fun(); // \
873 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
878 Bar
.aa_elr_fun(); // \
879 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
884 Bar
.aa_elr_fun_s(); // \
885 // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
890 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
894 MyLRFoo
.testShared(); // \
895 // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
901 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
908 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
915 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
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
{
941 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_
);
942 static int b_
GUARDED_BY(mu1_
);
944 static int a_
GUARDED_BY(mu1_
);
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.
966 int a_
GUARDED_BY(mu1_
);
968 int *q
PT_GUARDED_BY(mu
);
969 Mutex mu1_
ACQUIRED_AFTER(mu
);
973 int *p
GUARDED_BY(mu
) PT_GUARDED_BY(mu
);
974 int res
GUARDED_BY(mu
) = 5;
981 res
= b1
.a_
+ b3
->b_
;
983 b1
.a_
= res
+ b3
->b_
;
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
997 Mutex mu2
ACQUIRED_AFTER(mu1
);
1001 int method1(int i
) SHARED_LOCKS_REQUIRED(mu2
) EXCLUSIVE_LOCKS_REQUIRED(mu1
);
1004 int Foo::method1(int i
) {
1009 int foo(int i
) EXCLUSIVE_LOCKS_REQUIRED(mu2
) SHARED_LOCKS_REQUIRED(mu1
);
1014 static int bar(int i
) EXCLUSIVE_LOCKS_REQUIRED(mu1
);
1015 static int bar(int i
) {
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.
1038 void func1(int y
) LOCKS_EXCLUDED(mu_
);
1039 template <typename T
> void func2(T x
) LOCKS_EXCLUDED(mu_
);
1051 } // end namespace thread_annot_lock_38
1053 namespace thread_annot_lock_43
{
1054 // Tests lock canonicalization
1063 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_
->mu_
) { return a_
; }
1064 int a_
GUARDED_BY(foo_
->mu_
);
1072 fb
->foo_
->mu_
->Lock();
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
1088 Mutex bar_mu_
ACQUIRED_AFTER(foo
->foo_mu_
);
1092 foo
->foo_mu_
.Lock();
1095 foo
->foo_mu_
.Unlock();
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
1109 struct Foo
{ Foo
&operator<< (bool) {return *this;} };
1111 struct Bar
{ Foo
&func () {return getFoo();} };
1112 struct Bas
{ void operator& (Foo
&) {} };
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
1139 operator|(MyFlags a
, MyFlags b
)
1141 return MyFlags(static_cast<int>(a
) | static_cast<int>(b
));
1145 operator|=(MyFlags
& a
, MyFlags 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.
1159 int method1(int i
) SHARED_LOCKS_REQUIRED(mu1
, mu
, mu2
);
1160 int data
GUARDED_BY(mu1
);
1165 int Foo::method1(int i
)
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
1188 template <typename T
>
1193 template <typename T
>
1203 T count_
GUARDED_BY(mu_
);
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
1224 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu
);
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
1259 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1260 virtual void func2() LOCKS_EXCLUDED(mu_
);
1264 class Child
: public Base
{
1266 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1267 virtual void func2() LOCKS_EXCLUDED(mu_
);
1284 } // end namespace thread_annot_lock_47
1286 //-----------------------------------------//
1287 // Tests which produce errors
1288 //-----------------------------------------//
1290 namespace thread_annot_lock_13
{
1294 int g
GUARDED_BY(mu1
);
1295 int w
GUARDED_BY(mu2
);
1299 void bar() LOCKS_EXCLUDED(mu_
, mu1
);
1300 int foo() SHARED_LOCKS_REQUIRED(mu_
) EXCLUSIVE_LOCKS_REQUIRED(mu2
);
1303 int a_
GUARDED_BY(mu_
);
1305 Mutex mu_
ACQUIRED_AFTER(mu1
);
1320 x
= foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1334 f1
.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1340 f2
->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
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.
1354 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_
);
1355 void MyUnlock() UNLOCK_FUNCTION(mu1_
);
1356 int a_
GUARDED_BY(mu1_
);
1369 // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
1370 // expected-note {{found near match 'b1->mu1_'}}
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.
1384 int a_
GUARDED_BY(mu1_
);
1386 int *q
PT_GUARDED_BY(mu
);
1387 Mutex mu1_
ACQUIRED_AFTER(mu
);
1391 int *p
GUARDED_BY(mu
) PT_GUARDED_BY(mu
);
1393 int res
GUARDED_BY(mu
) = 5;
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'}}
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'}}
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
1421 int a_
GUARDED_BY(lock_
);
1424 void Func(Foo
* child
) LOCKS_EXCLUDED(lock_
) {
1425 Foo
*new_foo
= new Foo
;
1429 child
->Func(new_foo
); // There shouldn't be any warning here as the
1430 // acquired lock is not in child.
1432 // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
1433 // expected-note {{found near match 'lock_'}}
1435 // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
1436 // expected-note {{found near match 'lock_'}}
1440 void bar(int y
) EXCLUSIVE_LOCKS_REQUIRED(lock_
) {
1448 Foo
*child
= new Foo
;
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
1460 int a_
GUARDED_BY(lock_
);
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
;
1472 child
->lock_
.Lock();
1473 child
->Func(new_foo
); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1476 child
->lock_
.Unlock();
1481 void Foo::bar(int y
) {
1489 Foo
*child
= new Foo
;
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.
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
) {
1510 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2
) EXCLUSIVE_LOCKS_REQUIRED(mu1
) {
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}}
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.
1530 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1531 virtual void func2() LOCKS_EXCLUDED(mu_
);
1535 class Child
: public Base
{
1537 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1538 virtual void func2() LOCKS_EXCLUDED(mu_
);
1545 b
->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1547 b
->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1550 c
->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1552 c
->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
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.
1566 int method1(int i
) SHARED_LOCKS_REQUIRED(mu1
, mu
, mu2
, mu3
);
1567 int data
GUARDED_BY(mu1
);
1572 int Foo::method1(int i
) {
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
{
1592 void lockData() EXCLUSIVE_LOCK_FUNCTION(mu
);
1593 void unlockData() UNLOCK_FUNCTION(mu
);
1595 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu
) { }
1601 void lockData (MyData
*d
) EXCLUSIVE_LOCK_FUNCTION(d
->mu
);
1602 void unlockData(MyData
*d
) UNLOCK_FUNCTION(d
->mu
);
1608 void foo(MyData
* d
) EXCLUSIVE_LOCKS_REQUIRED(d
->mu
) { }
1610 void bar1(MyData
* d
) {
1616 void bar2(MyData
* d
) {
1623 void bar3(MyData
* d1
, MyData
* d2
) {
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
) {
1634 // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
1635 // expected-note {{found near match 'd1->mu'}}
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
{
1644 ~DestructorRequires() EXCLUSIVE_LOCKS_REQUIRED(mu
);
1647 void destructorRequires() {
1648 DestructorRequires rd
;
1652 struct DestructorExcludes
{
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
{
1669 int myVar
GUARDED_BY(fooMu
);
1673 Foo() EXCLUSIVE_LOCK_FUNCTION(fooMu
) { }
1674 ~Foo() UNLOCK_FUNCTION(fooMu
) { }
1684 namespace template_member_test
{
1686 struct S
{ int n
; };
1689 S
*s
GUARDED_BY(this->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}}
1713 V
*p
GUARDED_BY(this->m
);
1715 template<typename U
> struct W
{
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
{
1730 int a
__attribute__((guarded_by(mu1
)));
1731 int b
__attribute__((guarded_by(mu2
)));
1735 bool lock2Bool(MutexLock
);
1738 MutexLock
mulock(&mu1
);
1742 #ifdef __cpp_guaranteed_copy_elision
1744 const MutexLock mulock
= MutexLock(&mu1
);
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
);
1765 ReaderMutexLock
mulock1(&mu1
);
1767 MutexLock
mulock2a(&mu2
);
1771 MutexLock
mulock2b(&mu2
);
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}}
1789 MutexLock
mulock1(&mu1
), mulock2(&mu2
);
1795 DoubleMutexLock
mulock(&mu1
, &mu2
);
1801 } // end namespace test_scoped_lockable
1804 namespace FunctionAttrTest
{
1809 int a
GUARDED_BY(mu_
);
1814 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj
.mu_
);
1817 foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1820 fooObj
.mu_
.Unlock();
1823 }; // end namespace FunctionAttrTest
1826 namespace TryLockTest
{
1828 struct TestTryLock
{
1830 int a
GUARDED_BY(mu
);
1841 if (!mu
.TryLock()) return;
1846 void foo2_builtin_expect() {
1847 if (__builtin_expect(!mu
.TryLock(), false))
1854 bool b
= mu
.TryLock();
1861 void foo3_builtin_expect() {
1862 bool b
= mu
.TryLock();
1863 if (__builtin_expect(b
, true)) {
1870 bool b
= mu
.TryLock();
1877 while (mu
.TryLock()) {
1884 bool b
= mu
.TryLock();
1892 bool b1
= mu
.TryLock();
1901 // Test use-def chains: join points
1903 bool b
= mu
.TryLock();
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.
1916 // Test use-def-chains: back edges
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
1928 // Test use-def chains: back edges
1930 bool b
= mu
.TryLock();
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}}
1940 // Test merge of exclusive trylock
1953 // Test merge of shared trylock
1956 if (!mu
.ReaderTryLock())
1966 // Test with conditional operator
1968 if (mu
.TryLock() ? 1 : 0)
1973 if (mu
.TryLock() ? 0 : 1)
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
{
1992 int a
GUARDED_BY(mu_
);
1997 int a
GUARDED_BY(mu_
);
2004 // Test non-dependent expressions in attributes on template functions
2006 void barND(Foo1
*foo
, T
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(foo
->mu_
) {
2010 // Test dependent expressions in attributes on template functions
2012 void barD(Foo1
*foo
, T
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(fooT
->mu_
) {
2024 // Test non-dependent expression in ordinary method on template class
2025 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase
.mu_
) {
2029 // Test dependent expressions in ordinary methods on template class
2030 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT
.mu_
) {
2034 // Test dependent expressions in template method in template class
2036 void barTD(T2
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT
.mu_
, fooT
->mu_
) {
2046 // Test dependent guarded_by
2047 T data
GUARDED_BY(mu_
);
2049 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2068 bt
.fooBase
.mu_
.Lock();
2069 bt
.fooBaseT
.mu_
.Lock();
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();
2088 // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
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
;
2108 void fooExT(CellDelayed
<T2
> *otherT
) EXCLUSIVE_LOCKS_REQUIRED(mu_
, otherT
->mu_
) {
2109 this->data
= otherT
->data
;
2119 static Mutex static_mu_
;
2122 void testDelayed() {
2123 CellDelayed
<int> celld
;
2124 CellDelayed
<int> celld2
;
2129 celld
.fooEx(&celld2
);
2130 celld
.fooExT(&celld2
);
2132 celld2
.mu_
.Unlock();
2136 }; // end namespace TestTemplateAttributeInstantiation
2139 namespace FunctionDeclDefTest
{
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
) {
2156 myfoo
.foo1(&myfoo
); // \
2157 // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2165 namespace GoingNative
{
2167 struct LOCKABLE mutex
{
2168 void lock() EXCLUSIVE_LOCK_FUNCTION();
2169 void unlock() UNLOCK_FUNCTION();
2177 while (foo()) { // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
2187 m
.lock(); // expected-note {{mutex acquired here}}
2196 namespace FunctionDefinitionTest
{
2202 void foo3(Foo
*other
);
2205 void fooT1(const T
& dummy1
);
2208 void fooT2(const T
& dummy2
) EXCLUSIVE_LOCKS_REQUIRED(mu_
);
2211 int a
GUARDED_BY(mu_
);
2220 T a
GUARDED_BY(mu_
);
2224 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS
{
2228 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2232 void Foo::foo3(Foo
*other
) EXCLUSIVE_LOCKS_REQUIRED(other
->mu_
) {
2237 void Foo::fooT1(const T
& dummy1
) EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2241 /* TODO -- uncomment with template instantiation of attributes.
2243 void Foo::fooT2(const T& dummy2) {
2248 void fooF1(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
) {
2253 void fooF2(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
) {
2257 void fooF3(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
);
2258 void fooF3(Foo
*f
) {
2263 void FooT
<T
>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
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}}
2282 // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2284 // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2286 // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2302 // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2305 } // end namespace FunctionDefinitionTest
2308 namespace SelfLockingTest
{
2310 class LOCKABLE MyLock
{
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
2324 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2330 // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
2335 class LOCKABLE MyLock2
{
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.
2362 int foo
__attribute__((guarded_by(mutex_
)));
2365 } // end namespace InvalidNonStatic
2368 namespace NoReturnTest
{
2371 void fatal() __attribute__((noreturn
));
2376 MutexLock
lock(&mu_
);
2383 } // end namespace NoReturnTest
2386 namespace TestMultiDecl
{
2390 int GUARDED_BY(mu_
) a
;
2391 int GUARDED_BY(mu_
) b
, c
;
2395 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2397 // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2399 // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2406 } // end namespace TestMultiDecl
2409 namespace WarnNoDecl
{
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
{
2427 int a
GUARDED_BY(mu_
);
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
); }
2447 Foo
&(*fooFuncPtr
)();
2453 bar
.getFoo().mu_
.Lock();
2455 bar
.getFoo().mu_
.Unlock();
2457 (bar
.getFoo().mu_
).Lock(); // test parenthesis
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();
2487 fooFuncPtr().mu_
.Unlock();
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
{
2550 } // end namespace TrylockJoinPoint
2553 namespace LockReturned
{
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_
);
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();
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();
2590 Foo::getMu(f2
)->Unlock();
2594 f1
->getMu()->Unlock();
2598 Mutex
* getFooMu(Foo
* f
) LOCK_RETURNED(Foo::getMu(f
));
2600 class Bar
: public Foo
{
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();
2627 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
2628 // // expected-note {{found near match 'b1->mu_'}}
2630 b2
->getMu()->Lock();
2633 b2
->getMu()->Unlock();
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
) {
2649 getFooMu(b2
)->Lock();
2651 getFooMu(b2
)->Unlock();
2659 } // end namespace LockReturned
2662 namespace ReleasableScopedLock
{
2667 int a
GUARDED_BY(mu_
);
2679 ReleasableMutexLock
rlock(&mu_
);
2684 ReleasableMutexLock
rlock(&mu_
);
2685 if (c
) { // test join point -- held/not held during release
2688 // No warning on join point because the lock will be released by the scope object anyway.
2692 ReleasableMutexLock
rlock(&mu_
);
2695 a
= 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2699 ReleasableMutexLock
rlock(&mu_
);
2700 rlock
.Release(); // expected-note{{mutex released here}}
2701 rlock
.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2705 ReleasableMutexLock
rlock(&mu_
);
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}}
2714 ReleasableMutexLock
rlock(&mu_
);
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
{
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
{
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();
2764 int x
GUARDED_BY(mu
);
2770 RelockableExclusiveMutexLock
scope(&mu
);
2774 x
= 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2781 RelockableExclusiveMutexLock
scope(&mu
, DeferTraits
{});
2782 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2787 void relockExclusive() {
2788 RelockableMutexLock
scope(&mu
, SharedTraits
{});
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'}}
2799 scope
.DemoteExclusive();
2801 x
= 5; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2804 void relockShared() {
2805 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{});
2810 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2814 x
= 4; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2816 scope
.PromoteShared();
2821 void deferLockShared() {
2822 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2823 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
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
);
2843 scope
.Lock(); // expected-note{{mutex acquired here}}
2844 scope
.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2848 RelockableMutexLock
scope(&mu
, DeferTraits
{});
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}}
2856 RelockableMutexLock
scope(&mu
, DeferTraits
{});
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.
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}}
2885 scope
.PromoteShared();
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.
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}}
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.
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}}
2927 scope
.PromoteShared();
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.
2939 scope
.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}
2945 void exclusiveSharedJoin() {
2946 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2951 // No warning on join point because the lock will be released by the scope object anyway.
2953 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2956 void sharedExclusiveJoin() {
2957 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2962 // No warning on join point because the lock will be released by the scope object anyway.
2964 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2968 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2976 void assertSharedJoin() {
2977 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2981 mu
.AssertReaderHeld();
2983 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2986 void assertStrongerJoin() {
2987 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2993 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2996 void assertWeakerJoin() {
2997 RelockableMutexLock
scope(&mu
, DeferTraits
{});
3001 mu
.AssertReaderHeld();
3003 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3006 void directUnlock() {
3007 RelockableExclusiveMutexLock
scope(&mu
);
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.
3015 void directRelock() {
3016 RelockableExclusiveMutexLock
scope(&mu
);
3019 // Similarly debatable that there is no warning.
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
{
3032 MemberLock() EXCLUSIVE_LOCK_FUNCTION(mutex
);
3033 ~MemberLock() UNLOCK_FUNCTION(mutex
);
3034 void Lock() EXCLUSIVE_LOCK_FUNCTION(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
{
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
);
3059 scope
.unlock(); // expected-warning {{releasing mutex 'scope.other' that was not held}}
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}}
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
{
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
{
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();
3093 int x
GUARDED_BY(mu
);
3097 void simple() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3099 MutexUnlock
scope(&mu
);
3100 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3103 void simpleShared() SHARED_LOCKS_REQUIRED(mu
) {
3105 ReaderMutexUnlock
scope(&mu
);
3106 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3109 void innerUnlock() {
3110 MutexLock
outer(&mu
);
3112 MutexUnlock
inner(&mu
);
3113 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3118 void innerUnlockShared() {
3119 ReaderMutexLock
outer(&mu
);
3121 ReaderMutexUnlock
inner(&mu
);
3122 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3127 void manual() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3128 MutexUnlock
scope(&mu
);
3132 x
= 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3135 void join() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3136 MutexUnlock
scope(&mu
);
3139 // No warning on join point because the lock will be released by the scope object anyway.
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
{
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();
3164 void fn() EXCLUSIVE_LOCKS_REQUIRED(other
);
3166 void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3167 MutexLockUnlock
scope(&mu
, &other
);
3169 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3172 } // end namespace ScopedUnlock
3175 namespace TrylockFunctionTest
{
3183 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_
, mu2_
);
3186 bool Foo::lockBoth() {
3187 if (!mu1_
.TryLock())
3201 } // end namespace TrylockFunctionTest
3205 namespace DoubleLockBug
{
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_
) {
3221 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_
) {
3229 namespace UnlockBug
{
3235 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_
) { // expected-note {{mutex acquired here}}
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}}
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
{
3253 WTF_ScopedLockable(Mutex
* mu
) EXCLUSIVE_LOCK_FUNCTION(mu
);
3255 // have to call release() manually;
3256 ~WTF_ScopedLockable();
3258 void release() UNLOCK_FUNCTION();
3264 int a
GUARDED_BY(mu_
);
3270 WTF_ScopedLockable
wtf(&mu_
);
3275 WTF_ScopedLockable
wtf(&mu_
); // expected-note {{mutex acquired here}}
3276 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
3280 WTF_ScopedLockable
wtf(&mu_
);
3290 WTF_ScopedLockable
wtf(&mu_
);
3297 WTF_ScopedLockable
wtf(&mu_
); // expected-note {{mutex acquired here}}
3299 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
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
{
3319 int a
GUARDED_BY(getMutexPtr().get());
3321 SmartPtr
<Mutex
> getMutexPtr();
3329 ReaderMutexLock
lock(getMutexPtr().get());
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
};
3342 void guaranteed_copy_elision_const() {
3343 const MutexLock lock
= MutexLock
{&sls_mu
};
3349 } // end namespace TemporaryCleanupExpr
3353 namespace SmartPointerTests
{
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_
);
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}}
3404 mu_
.get()->Unlock();
3409 MutexLock
lock(mu_
.get());
3417 MutexLock
lock(&(*mu_
));
3448 mu_
.get()->Unlock();
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}}
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}}
3501 foo
.get()->mu_
->Unlock();
3506 MutexLock
lock(foo
->mu_
.get());
3512 } // end namespace SmartPointerTests
3516 namespace DuplicateAttributeTest
{
3518 class LOCKABLE Foo
{
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_
);
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_
);
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_
) {
3554 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_
) {
3558 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
, mu3_
) {
3564 void Foo::locklots()
3565 EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
)
3566 EXCLUSIVE_LOCK_FUNCTION(mu2_
, mu3_
) {
3572 void Foo::unlock1() UNLOCK_FUNCTION(mu1_
) {
3576 void Foo::unlock3() UNLOCK_FUNCTION(mu1_
, mu2_
, mu3_
) {
3582 void Foo::unlocklots()
3583 UNLOCK_FUNCTION(mu1_
, mu2_
)
3584 UNLOCK_FUNCTION(mu2_
, mu3_
) {
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}}
3609 foo
.lock1(); // expected-note{{mutex acquired here}}
3610 foo
.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3612 foo
.unlock1(); // expected-note{{mutex released here}}
3613 foo
.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3623 foo
.slock1(); // expected-note{{mutex acquired here}}
3624 foo
.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3626 foo
.unlock1(); // expected-note{{mutex released here}}
3627 foo
.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3640 foo
.lock3(); // expected-note 3 {{mutex acquired here}}
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}}
3648 foo
.unlock3(); // expected-note 3 {{mutex released here}}
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}}
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}}
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
{
3687 int a
GUARDED_BY(mu_
);
3690 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_
);
3691 Mutex
* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_
);
3692 void unlock() UNLOCK_FUNCTION(mu_
);
3700 if (tryLockMutexP() == 0) {
3701 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3707 if (tryLockMutexP() != 0) {
3712 if (0 != tryLockMutexP()) {
3717 if (!(tryLockMutexP() == 0)) {
3722 if (tryLockMutexI() == 0) {
3723 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3729 if (0 == tryLockMutexI()) {
3730 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3736 if (tryLockMutexI() == 1) {
3741 if (mu_
.TryLock() == false) {
3742 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3748 if (mu_
.TryLock() == true) {
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}}
3766 } // end namespace TryLockEqTest
3769 namespace ExistentialPatternMatching
{
3776 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_
);
3777 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_
);
3781 int a
GUARDED_BY(&Graph::mu_
);
3783 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_
) {
3786 void foo2() LOCKS_EXCLUDED(&Graph::mu_
);
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}}
3801 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3807 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3813 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3822 LockAllGraphs(); // expected-note{{mutex acquired here}}
3823 g1
.mu_
.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3827 } // end namespace ExistentialPatternMatching
3830 namespace StringIgnoreTest
{
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
{
3852 } // end namespace StringIgnoreTest
3855 namespace LockReturnedScopeFix
{
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
));
3872 struct Base::Inner
{
3874 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_
);
3878 const Mutex
& Base::getLock(const Inner
* i
) LOCK_RETURNED(i
->lock_
) {
3883 void Base::foo(Inner
* i
) {
3887 void Base::bar(Inner
* i
) {
3898 } // end namespace LockReturnedScopeFix
3901 namespace TrylockWithCleanups
{
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");
3918 } // end namespace TrylockWithCleanups
3921 namespace UniversalLock
{
3927 int a
GUARDED_BY(mu_
);
3928 void r_foo() SHARED_LOCKS_REQUIRED(mu_
);
3929 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
3934 beginNoWarnOnReads();
3939 beginNoWarnOnWrites();
3942 endNoWarnOnWrites();
3945 // don't warn on joins with universal lock
3948 beginNoWarnOnWrites();
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
3961 beginNoWarnOnWrites();
3964 beginNoWarnOnWrites();
3968 endNoWarnOnWrites();
3973 // combine universal lock with other locks
3975 beginNoWarnOnWrites();
3978 endNoWarnOnWrites();
3981 beginNoWarnOnWrites();
3982 endNoWarnOnWrites();
3986 beginNoWarnOnWrites();
3988 endNoWarnOnWrites();
3992 } // end namespace UniversalLock
3995 namespace TemplateLockReturned
{
4000 virtual void baseMethod() = 0;
4001 Mutex
* get_mutex() LOCK_RETURNED(mutex_
) { return &mutex_
; }
4004 int a
GUARDED_BY(mutex_
);
4008 class Derived
: public BaseT
<int> {
4010 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
4015 } // end namespace TemplateLockReturned
4018 namespace ExprMatchingBugFix
{
4030 Bar(Foo
* f
) : foo(f
) { }
4034 Nested(Foo
* f
) : foo(f
) { }
4036 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_
);
4046 Nested
*n
= new Nested(foo
);
4054 }; // end namespace ExprMatchingBugfix
4057 namespace ComplexNameTest
{
4063 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) { }
4064 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) { }
4066 int operator[](int i
) EXCLUSIVE_LOCKS_REQUIRED(mu_
) { return 0; }
4073 Bar() LOCKS_EXCLUDED(mu_
) { }
4074 ~Bar() LOCKS_EXCLUDED(mu_
) { }
4076 int operator[](int i
) LOCKS_EXCLUDED(mu_
) { return 0; }
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}}
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}}
4095 }; // end namespace ComplexNameTest
4098 namespace UnreachableExitTest
{
4103 ~FemmeFatale() __attribute__((noreturn
));
4106 void exitNow() __attribute__((noreturn
));
4107 void exitDestruct(const MyString
& ms
) __attribute__((noreturn
));
4111 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4115 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4121 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4130 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4131 exitDestruct("foo");
4134 } // end namespace UnreachableExitTest
4137 namespace VirtualMethodCanonicalizationTest
{
4141 virtual Mutex
* getMutex() = 0;
4144 class Base2
: public Base
{
4149 class Base3
: public Base2
{
4154 class Derived
: public Base3
{
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()) {
4165 } // end namespace VirtualMethodCanonicalizationTest
4168 namespace TemplateFunctionParamRemapTest
{
4179 void elr(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4185 void Foo::elr(Cell
<T
>* c1
) { }
4190 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}
4195 void globalELR(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4198 void globalELR(Cell
<T
>* c1
) { }
4202 globalELR(&cell
); // \
4203 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}
4208 void globalELR2(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4210 // second declaration
4212 void globalELR2(Cell
<T
>* c2
);
4215 void globalELR2(Cell
<T
>* c3
) { }
4217 // re-declaration after definition
4219 void globalELR2(Cell
<T
>* c4
);
4221 void globalTest2() {
4223 globalELR2(&cell
); // \
4224 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}
4231 void elr(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4235 void FooT
<T
>::elr(Cell
<T
>* c1
) { }
4240 foo
.elr(&cell
); // \
4241 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
4244 } // end namespace TemplateFunctionParamRemapTest
4247 namespace SelfConstructorTest
{
4251 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_
);
4252 ~SelfLock() UNLOCK_FUNCTION(mu_
);
4254 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
4259 class LOCKABLE SelfLock2
{
4261 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
4262 ~SelfLock2() UNLOCK_FUNCTION();
4264 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
4267 class SelfLockDeferred
{
4269 SelfLockDeferred() LOCKS_EXCLUDED(mu_
);
4270 ~SelfLockDeferred() UNLOCK_FUNCTION(mu_
);
4275 class LOCKABLE SelfLockDeferred2
{
4277 SelfLockDeferred2() LOCKS_EXCLUDED(this);
4278 ~SelfLockDeferred2() UNLOCK_FUNCTION();
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
{
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_
);
4341 void testAssertShared();
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; }
4364 foo1(); // expected-warning {{}}
4365 c
= 0; // expected-warning {{}}
4366 *d
= 0; // expected-warning {{}}
4370 foo2(); // expected-warning {{}}
4371 int x
= c
; // expected-warning {{}}
4372 int y
= *d
; // expected-warning {{}}
4376 foo3(); // expected-warning {{}}
4394 if (readertrylock()) {
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() {
4419 void Foo::testAssertShared() {
4432 } // end namespace MultipleAttributeTest
4435 namespace GuardedNonPrimitiveTypeTest
{
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);
4461 Data
& operator++(int);
4463 Data
& operator--(int);
4472 DataCell(const Data
& d
) : dat(d
) { }
4479 void showDataCell(const DataCell
& dc
);
4484 // method call tests
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_'}}
4508 datap1_
->setValue(1);
4509 datap2_
->setValue(1);
4513 a
= data_
.getValue();
4514 datap1_
->setValue(0); // reads datap1_, writes *datap1_
4515 a
= datap1_
->getValue();
4516 a
= datap2_
->getValue();
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_'}}
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_'}}
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
{
4588 Cell c
GUARDED_BY(cell_mu_
);
4589 Cell
* cp
PT_GUARDED_BY(cell_mu_
);
4600 Foo foo
GUARDED_BY(mu_
);
4601 Foo
* foop
PT_GUARDED_BY(mu_
);
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
{
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
{
4673 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_
.Lock(); }
4674 void readerLock() SHARED_LOCK_FUNCTION() { mu_
.ReaderLock(); }
4675 void unlock() UNLOCK_FUNCTION() { mu_
.Unlock(); }
4684 // Correct lock/unlock functions
4685 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_
) {
4689 void readerLock() SHARED_LOCK_FUNCTION(mu_
) {
4693 void unlock() UNLOCK_FUNCTION(mu_
) {
4697 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_
) {
4701 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_
) {
4705 // Check failure to lock.
4706 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
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}}
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}}
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}}
4743 } // end namespace LockUnlockFunctionTest
4746 namespace AssertHeldTest
{
4751 int a
GUARDED_BY(mu_
);
4761 mu_
.AssertReaderHeld();
4763 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4777 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
4783 void test5() UNLOCK_FUNCTION(mu_
) {
4790 mu_
.Unlock(); // should this be a warning?
4812 // FIXME: should warn, because it's unclear whether we need to release or not.
4815 mu_
.Unlock(); // should this be a warning?
4823 mu_
.Lock(); // expected-note {{mutex acquired here}}
4825 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4829 mu_
.Lock(); // expected-note {{mutex acquired here}}
4834 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4836 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_
);
4846 mu_
.ReaderLock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
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.
4857 mu_
.Lock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
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.
4867 } // end namespace AssertHeldTest
4870 namespace LogicalConditionalTryLock
{
4875 int a
GUARDED_BY(mu
);
4881 if (c
&& mu
.TryLock()) {
4888 bool b
= mu
.TryLock();
4896 if (c
|| !mu
.TryLock())
4903 while (c
&& mu
.TryLock()) {
4912 if (newc() || !mu
.TryLock())
4924 } while (newc() && mu
.TryLock());
4928 for (bool b
= mu
.TryLock(); c
&& b
;) {
4935 if (c
&& newc() && mu
.TryLock()) {
4942 if (!(c
&& newc() && mu
.TryLock()))
4949 if (!(c
|| !mu
.TryLock())) {
4956 } // end namespace LogicalConditionalTryLock
4960 namespace PtGuardedByTest
{
4970 // This mainly duplicates earlier tests, but just to make sure...
4971 class PtGuardedByCorrectnessTest
{
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
;
4983 if (a
== 0) doSomething(); // OK, we don't dereference.
4986 if (sa
[0] == 42) doSomething();
4988 if (sc
[0].a
== 42) doSomething();
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}}
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'}}
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}}
5047 mu1
.ReaderLock(); // OK -- correct use.
5049 if (*a
== 0) doSomething();
5052 if (c
->a
== 0) doSomething();
5055 if ((*c
).a
== 0) doSomething();
5063 class SmartPtr_PtGuardedBy_Test
{
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
;
5076 if (*sp
== 0) doSomething();
5081 if (sp
[0] == 0) doSomething();
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'}}
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'}}
5123 } // end namespace PtGuardedByTest
5126 namespace NonMemberCalleeICETest
{
5130 (RunHelper
)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
5133 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(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'}}
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
{
5159 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
5162 auto func1
= [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
5166 auto func2
= [this]() NO_THREAD_SAFETY_ANALYSIS
{
5170 auto func3
= [this]() EXCLUSIVE_LOCK_FUNCTION(mu_
) {
5174 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
5181 } // end namespace ThreadAttributesOnLambdas
5185 namespace AttributeExpressionCornerCases
{
5188 int a
GUARDED_BY(getMu());
5190 Mutex
* getMu() LOCK_RETURNED("");
5191 Mutex
* getUniv() LOCK_RETURNED("*");
5197 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
5201 void foo(Mutex
* mu
) EXCLUSIVE_LOCKS_REQUIRED(mu
);
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
);
5221 map
["foo"]->Unlock();
5225 mapCell
["foo"].mu
->Lock();
5227 mapCell
["foo"].mu
->Unlock();
5232 class PreciseSmartPtr
{
5234 int val
GUARDED_BY(mu
);
5236 static bool compare(PreciseSmartPtr
& a
, PreciseSmartPtr
&b
) {
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'}}
5246 class SmartRedeclare
{
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()) {
5260 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
5264 void SmartRedeclare::test3() {
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
) { }
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
{
5297 Mutex
* getMutex(Opaque
* o
) LOCK_RETURNED("");
5299 void test(Opaque
* o
) {
5300 MutexLock
lock(getMutex(o
));
5303 } // end namespace ScopedLockReturnedInvalid
5306 namespace NegativeRequirements
{
5310 int a
GUARDED_BY(mu
);
5313 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
5323 int a
GUARDED_BY(mu
);
5327 mu
.Lock(); // warning? needs !mu?
5328 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
5334 bar2(); // expected-warning {{calling function 'bar2' requires negative capability '!mu'}}
5337 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
5341 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
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
) {
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
))) {
5389 while ((msg
= deque_log_msg())) {
5394 void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl
))) {
5400 int main(void) __attribute__((requires_capability(!FlightControl
))) {
5401 spawn_fake_flight_control_thread();
5402 spawn_fake_logger_thread();
5405 ; /* Pretend to dispatch things. */
5410 } // end namespace NegativeThreadRoles
5413 namespace AssertSharedExclusive
{
5419 int a
GUARDED_BY(mu
);
5421 void test() SHARED_LOCKS_REQUIRED(mu
) {
5428 } // end namespace AssertSharedExclusive
5431 namespace RangeBasedForAndReferences
{
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
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}}
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}}
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}}
5473 *b
= 0; // no expected warning yet
5478 for (int i
: cntr
) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
5485 } // end namespace RangeBasedForAndReferences
5489 namespace PassByRefTest
{
5493 Foo() : a(0), b(0) { }
5498 void operator+(const Foo
& f
);
5500 void operator[](const Foo
& g
);
5509 // test top-level functions
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.
5522 FooRead(const 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, ...);
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
);
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
);
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
);
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.
5613 write1(*foosp
.get());
5614 write2(10, *foosp
.get());
5615 read1(*foosp
.get());
5616 read2(10, *foosp
.get());
5617 destroy(mymove(*foosp
.get()));
5623 Foo foo
GUARDED_BY(mu
);
5624 Foo
* foo_ptr
PT_GUARDED_BY(mu
);
5626 Foo
returns_value_locked() {
5627 MutexLock
lock(&mu
);
5631 Foo
returns_value_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
5635 Foo
returns_value_releases_lock_after_return() UNLOCK_FUNCTION(mu
) {
5636 MutexLock
lock(&mu
, true);
5640 Foo
returns_value_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu
) {
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
) {
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
) {
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
) {
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
) {
5686 const Foo
&returns_constref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu
) {
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
{
5707 Mutex mu1
ACQUIRED_BEFORE(mu2
, mu3
);
5723 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5730 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5735 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1
) {
5740 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2
) {
5741 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5745 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2
) {
5749 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1
, mu2
, mu3
) { }
5751 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3
, mu2
, mu1
) { }
5757 Mutex mu2
ACQUIRED_AFTER(mu1
);
5758 Mutex mu3
ACQUIRED_AFTER(mu1
);
5772 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5779 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5787 Mutex mu1
ACQUIRED_BEFORE(mu2
);
5789 Mutex mu3
ACQUIRED_AFTER(mu2
) ACQUIRED_BEFORE(mu4
);
5806 mu2
.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
5814 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
5822 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5830 // Test transitive DAG traversal with AFTER
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
);
5843 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5850 // Test transitive DAG traversal with BEFORE
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
);
5863 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
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'}}
5910 } // end namespace AcquiredBeforeAfterTest
5913 namespace ScopedAdoptTest
{
5917 int a
GUARDED_BY(mu
);
5920 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu
) {
5921 MutexLock
slock(&mu
, true);
5925 void test2() SHARED_UNLOCK_FUNCTION(mu
) {
5926 ReaderMutexLock
slock(&mu
, true);
5930 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu
) { // expected-note {{mutex acquired here}}
5931 MutexLock
slock(&mu
, true);
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);
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
5952 inline const T
& ts_unchecked_read(const T
& v
) NO_THREAD_SAFETY_ANALYSIS
{
5957 inline T
& ts_unchecked_read(T
& v
) NO_THREAD_SAFETY_ANALYSIS
{
5975 int a
GUARDED_BY(mu
);
5976 Foo foo
GUARDED_BY(mu
);
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
{
6001 Mutex mu2
ACQUIRED_AFTER(mu1
);
6005 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
6010 } // end namespace GlobalAcquiredBeforeAfterTest
6013 namespace LifetimeExtensionText
{
6016 virtual ~Holder() throw() {}
6021 // Should not crash.
6022 const auto &value
= Holder().i
;
6025 } // end namespace LifetimeExtensionTest
6028 namespace LockableUnions
{
6030 union LOCKABLE MutexUnion
{
6034 void Lock() EXCLUSIVE_LOCK_FUNCTION();
6035 void Unlock() UNLOCK_FUNCTION();
6039 MutexUnion muun1
ACQUIRED_BEFORE(muun2
);
6043 muun1
.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
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("");
6060 operator int() const;
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'}}
6070 void f() { c
[A()]->g(); }
6071 } // namespace PR34800
6073 #ifdef __cpp_guaranteed_copy_elision
6075 namespace ReturnScopedLockable
{
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
);
6099 MutexLock scope
= lock();
6110 MutexLock scope
= obj
.lock();
6115 int testSharedLock() {
6116 ReaderMutexLock scope
= obj
.lockShared();
6117 obj
.x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'obj.mutex' exclusively}}
6123 MutexLock scope
= obj
.adopt();
6127 int testAdoptShared() {
6129 ReaderMutexLock scope
= obj
.adoptShared();
6134 } // namespace ReturnScopedLockable
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
{
6148 class SmartPtr_Derived
: public SmartPtr
<T
> {};
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_
);
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}}
6176 SmartPtr_Derived
<Foo
> foo
;
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}}
6193 MutexLock
lock(foo
->mu_
.get());
6198 class PointerGuard
{
6201 SmartPtr_Derived
<int> i
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
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'}}
6214 *i
= 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
6222 i
.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6223 *i
= 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}