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
);
154 int x
= sls_guard_var
;
172 int x
= sls_guardby_var
;
205 void sls_fun_good_6() {
219 void sls_fun_good_7() {
234 void sls_fun_good_8() {
239 void sls_fun_bad_1() {
240 sls_mu
.Unlock(); // \
241 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
244 void sls_fun_bad_2() {
245 sls_mu
.Lock(); // expected-note{{mutex acquired here}}
247 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
251 void sls_fun_bad_3() {
252 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
253 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
255 void sls_fun_bad_4() {
257 sls_mu
.Lock(); // expected-note{{mutex acquired here}}
259 sls_mu2
.Lock(); // expected-note{{mutex acquired here}}
260 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
261 // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
263 void sls_fun_bad_5() {
264 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
267 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
269 void sls_fun_bad_6() {
271 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
279 sls_mu
.Unlock(); // \
280 expected
-warning
{{mutex
'sls_mu' is
not held on every path through here
}}\
281 expected
-warning
{{releasing mutex
'sls_mu' that was
not held
}}
284 void sls_fun_bad_7() {
286 while (getBool()) { // \
287 expected
-warning
{{expecting mutex
'sls_mu' to be held at start of each loop
}}
294 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
299 void sls_fun_bad_8() {
300 sls_mu
.Lock(); // expected-note{{mutex acquired here}}
303 sls_mu
.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
307 void sls_fun_bad_9() {
310 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
311 // expected-note{{mutex acquired here}}
316 void sls_fun_bad_10() {
317 sls_mu
.Lock(); // expected-note 2{{mutex acquired here}}
318 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
321 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
323 void sls_fun_bad_11() {
324 while (getBool()) { // \
325 expected
-warning
{{expecting mutex
'sls_mu' to be held at start of each loop
}}
326 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
328 sls_mu
.Unlock(); // \
329 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
332 void sls_fun_bad_12() {
333 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
343 sls_mu
.Unlock(); // \
344 expected
-warning
{{mutex
'sls_mu' is
not held on every path through here
}} \
345 expected
-warning
{{releasing mutex
'sls_mu' that was
not held
}}
348 //-----------------------------------------//
349 // Handling lock expressions in attribute args
350 // -------------------------------------------//
356 void globalLock() EXCLUSIVE_LOCK_FUNCTION(aa_mu
);
357 void globalUnlock() UNLOCK_FUNCTION(aa_mu
);
364 glock
.globalUnlock();
367 void aa_fun_bad_1() {
368 glock
.globalUnlock(); // \
369 // expected-warning{{releasing mutex 'aa_mu' that was not held}}
372 void aa_fun_bad_2() {
373 glock
.globalLock(); // expected-note{{mutex acquired here}}
374 glock
.globalLock(); // \
375 // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
376 glock
.globalUnlock();
379 void aa_fun_bad_3() {
380 glock
.globalLock(); // expected-note{{mutex acquired here}}
381 } // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
383 //--------------------------------------------------//
384 // Regression tests for unusual method names
385 //--------------------------------------------------//
389 // Test diagnostics for other method names.
391 // FIXME: can't currently check inside constructors and destructors.
393 wmu
.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
394 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
396 wmu
.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
397 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
399 wmu
.Lock(); // expected-note {{mutex acquired here}}
400 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
402 wmu
.Lock(); // expected-note {{mutex acquired here}}
404 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
407 //-----------------------------------------------//
408 // Errors for guarded by or guarded var variables
409 // ----------------------------------------------//
411 int *pgb_gvar
__attribute__((pt_guarded_var
));
412 int *pgb_var
__attribute__((pt_guarded_by(sls_mu
)));
417 int *pgb_field
__attribute__((guarded_by(sls_mu2
)))
418 __attribute__((pt_guarded_by(sls_mu
)));
421 // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
422 *pgb_field
= x
; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
423 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
424 x
= *pgb_field
; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
425 // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
426 (*pgb_field
)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
427 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
433 int gb_field
__attribute__((guarded_by(sls_mu
)));
437 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
440 void testNoAnal() NO_THREAD_SAFETY_ANALYSIS
{
445 GBFoo GlobalGBFoo
__attribute__((guarded_by(sls_mu
)));
469 sls_guard_var
= 1; // \
470 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
474 int x
= sls_guard_var
; // \
475 // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
479 sls_guardby_var
= 1; // \
480 // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
484 int x
= sls_guardby_var
; // \
485 // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
490 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
494 int x
= *pgb_gvar
; // \
495 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
500 // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
504 int x
= *pgb_var
; // \
505 // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
511 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
515 sls_guard_var
++; // \
516 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
517 sls_guard_var
--; // \
518 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
519 ++sls_guard_var
; // \
520 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
522 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
525 //-----------------------------------------------//
526 // Warnings on variables with late parsed attributes
527 // ----------------------------------------------//
531 int a
__attribute__((guarded_by(mu
)));
534 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu
) { }
538 // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
540 // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
542 // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
545 int c
__attribute__((guarded_by(mu
)));
552 int a_
__attribute__((guarded_by(mu1_
)));
554 int *q
__attribute__((pt_guarded_by(mu
)));
574 BarA
.FooPointer
->mu
.Lock();
575 BarA
.FooPointer
->a
= 2;
576 BarA
.FooPointer
->mu
.Unlock();
584 // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
585 // expected-note{{found near match 'fooA.mu'}}
593 int res
= b1
.a_
+ b3
->b_
;
595 // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
603 BarA
.FooPointer
->mu
.Lock();
605 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
606 // expected-note{{found near match 'BarA.FooPointer->mu'}}
607 BarA
.FooPointer
->mu
.Unlock();
613 BarA
.FooPointer
->a
= 2; // \
614 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
615 // expected-note{{found near match 'BarA.Foo.mu'}}
616 BarA
.Foo
.mu
.Unlock();
622 BarA
.Foo2
.a
= 2; // \
623 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
624 // expected-note{{found near match 'BarA.Foo.mu'}}
625 BarA
.Foo
.mu
.Unlock();
628 //-----------------------------------------------//
629 // Extra warnings for shared vs. exclusive locks
630 // ----------------------------------------------//
632 void shared_fun_0() {
641 void shared_fun_1() {
642 sls_mu
.ReaderLock(); // \
643 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
647 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
652 void shared_fun_3() {
661 void shared_fun_4() {
666 int x
= sls_guardby_var
;
670 void shared_fun_8() {
673 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
675 sls_mu
.ReaderLock(); // \
676 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
680 void shared_fun_9() {
682 sls_mu
.ExclusiveUnlock();
685 sls_mu
.ReaderUnlock();
688 void shared_fun_10() {
690 sls_mu
.DemoteExclusive();
691 sls_mu
.ReaderUnlock();
694 void shared_fun_11() {
696 sls_mu
.PromoteShared();
700 void shared_bad_0() {
702 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
705 sls_mu
.ReaderLock(); // \
706 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
711 void shared_bad_1() {
714 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
716 sls_mu
.ReaderLock(); // \
717 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
722 void shared_bad_2() {
724 sls_mu
.ReaderLock(); // \
725 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
728 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
733 void shared_bad_3() {
734 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
735 sls_mu
.ReaderUnlock(); // \
736 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
739 void shared_bad_4() {
740 sls_mu
.ReaderLock(); // expected-note {{mutex acquired here}}
741 sls_mu
.ExclusiveUnlock(); // \
742 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
745 void shared_bad_5() {
746 sls_mu
.Lock(); // expected-note {{mutex acquired here}}
747 sls_mu
.PromoteShared(); // \
748 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
749 sls_mu
.ExclusiveUnlock();
752 void shared_bad_6() {
753 sls_mu
.ReaderLock(); // expected-note {{mutex acquired here}}
754 sls_mu
.DemoteExclusive(); // \
755 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
756 sls_mu
.ReaderUnlock();
759 // FIXME: Add support for functions (not only methods)
762 void aa_elr_fun() EXCLUSIVE_LOCKS_REQUIRED(aa_mu
);
763 void aa_elr_fun_s() SHARED_LOCKS_REQUIRED(aa_mu
);
764 void le_fun() __attribute__((locks_excluded(sls_mu
)));
769 void test() EXCLUSIVE_LOCKS_REQUIRED(sls_mu
);
770 void testShared() SHARED_LOCKS_REQUIRED(sls_mu2
);
773 void elr_fun() EXCLUSIVE_LOCKS_REQUIRED(sls_mu
);
805 MyLRFoo
.testShared();
810 sls_mu2
.ReaderLock();
811 MyLRFoo
.testShared();
825 void es_fun_8() NO_THREAD_SAFETY_ANALYSIS
;
831 void es_fun_9() SHARED_LOCKS_REQUIRED(aa_mu
);
836 void es_fun_10() EXCLUSIVE_LOCKS_REQUIRED(aa_mu
);
842 Bar
.aa_elr_fun(); // \
843 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
848 Bar
.aa_elr_fun(); // \
849 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
854 Bar
.aa_elr_fun_s(); // \
855 // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
860 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
864 MyLRFoo
.testShared(); // \
865 // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
871 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
878 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
885 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
890 //-----------------------------------------------//
891 // Unparseable lock expressions
892 // ----------------------------------------------//
894 // FIXME -- derive new tests for unhandled expressions
897 //----------------------------------------------------------------------------//
898 // The following test cases are ported from the gcc thread safety implementation
899 // They are each wrapped inside a namespace with the test number of the gcc test
901 // FIXME: add all the gcc tests, once this analysis passes them.
902 //----------------------------------------------------------------------------//
904 //-----------------------------------------//
905 // Good testcases (no errors)
906 //-----------------------------------------//
908 namespace thread_annot_lock_20
{
911 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_
);
912 static int b_
GUARDED_BY(mu1_
);
914 static int a_
GUARDED_BY(mu1_
);
927 } // end namespace thread_annot_lock_20
929 namespace thread_annot_lock_22
{
930 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
931 // uses in class definitions.
936 int a_
GUARDED_BY(mu1_
);
938 int *q
PT_GUARDED_BY(mu
);
939 Mutex mu1_
ACQUIRED_AFTER(mu
);
943 int *p
GUARDED_BY(mu
) PT_GUARDED_BY(mu
);
944 int res
GUARDED_BY(mu
) = 5;
951 res
= b1
.a_
+ b3
->b_
;
953 b1
.a_
= res
+ b3
->b_
;
961 } // end namespace thread_annot_lock_22
963 namespace thread_annot_lock_27_modified
{
964 // test lock annotations applied to function definitions
965 // Modified: applied annotations only to function declarations
967 Mutex mu2
ACQUIRED_AFTER(mu1
);
971 int method1(int i
) SHARED_LOCKS_REQUIRED(mu2
) EXCLUSIVE_LOCKS_REQUIRED(mu1
);
974 int Foo::method1(int i
) {
979 int foo(int i
) EXCLUSIVE_LOCKS_REQUIRED(mu2
) SHARED_LOCKS_REQUIRED(mu1
);
984 static int bar(int i
) EXCLUSIVE_LOCKS_REQUIRED(mu1
);
985 static int bar(int i
) {
1000 } // end namespace thread_annot_lock_27_modified
1003 namespace thread_annot_lock_38
{
1004 // Test the case where a template member function is annotated with lock
1005 // attributes in a non-template class.
1008 void func1(int y
) LOCKS_EXCLUDED(mu_
);
1009 template <typename T
> void func2(T x
) LOCKS_EXCLUDED(mu_
);
1021 } // end namespace thread_annot_lock_38
1023 namespace thread_annot_lock_43
{
1024 // Tests lock canonicalization
1033 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_
->mu_
) { return a_
; }
1034 int a_
GUARDED_BY(foo_
->mu_
);
1042 fb
->foo_
->mu_
->Lock();
1044 fb
->foo_
->mu_
->Unlock();
1046 } // end namespace thread_annot_lock_43
1048 namespace thread_annot_lock_49
{
1049 // Test the support for use of lock expression in the annotations
1058 Mutex bar_mu_
ACQUIRED_AFTER(foo
->foo_mu_
);
1062 foo
->foo_mu_
.Lock();
1065 foo
->foo_mu_
.Unlock();
1073 } // end namespace thread_annot_lock_49
1075 namespace thread_annot_lock_61_modified
{
1076 // Modified to fix the compiler errors
1077 // Test the fix for a bug introduced by the support of pass-by-reference
1079 struct Foo
{ Foo
&operator<< (bool) {return *this;} };
1081 struct Bar
{ Foo
&func () {return getFoo();} };
1082 struct Bas
{ void operator& (Foo
&) {} };
1085 Bas() & Bar().func() << "" << "";
1086 Bas() & Bar().func() << "";
1088 } // end namespace thread_annot_lock_61_modified
1091 namespace thread_annot_lock_65
{
1092 // Test the fix for a bug in the support of allowing reader locks for
1093 // non-const, non-modifying overload functions. (We didn't handle the builtin
1109 operator|(MyFlags a
, MyFlags b
)
1111 return MyFlags(static_cast<int>(a
) | static_cast<int>(b
));
1115 operator|=(MyFlags
& a
, MyFlags b
)
1119 } // end namespace thread_annot_lock_65
1121 namespace thread_annot_lock_66_modified
{
1122 // Modified: Moved annotation to function defn
1123 // Test annotations on out-of-line definitions of member functions where the
1124 // annotations refer to locks that are also data members in the class.
1129 int method1(int i
) SHARED_LOCKS_REQUIRED(mu1
, mu
, mu2
);
1130 int data
GUARDED_BY(mu1
);
1135 int Foo::method1(int i
)
1152 } // end namespace thread_annot_lock_66_modified
1154 namespace thread_annot_lock_68_modified
{
1155 // Test a fix to a bug in the delayed name binding with nested template
1156 // instantiation. We use a stack to make sure a name is not resolved to an
1158 template <typename T
>
1163 template <typename T
>
1173 T count_
GUARDED_BY(mu_
);
1183 } // end namespace thread_annot_lock_68_modified
1185 namespace thread_annot_lock_30_modified
{
1186 // Test delay parsing of lock attribute arguments with nested classes.
1187 // Modified: trylocks replaced with exclusive_lock_fun
1194 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu
);
1221 } // end namespace thread_annot_lock_30_modified
1223 namespace thread_annot_lock_47
{
1224 // Test the support for annotations on virtual functions.
1225 // This is a good test case. (i.e. There should be no warning emitted by the
1229 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1230 virtual void func2() LOCKS_EXCLUDED(mu_
);
1234 class Child
: public Base
{
1236 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1237 virtual void func2() LOCKS_EXCLUDED(mu_
);
1254 } // end namespace thread_annot_lock_47
1256 //-----------------------------------------//
1257 // Tests which produce errors
1258 //-----------------------------------------//
1260 namespace thread_annot_lock_13
{
1264 int g
GUARDED_BY(mu1
);
1265 int w
GUARDED_BY(mu2
);
1269 void bar() LOCKS_EXCLUDED(mu_
, mu1
);
1270 int foo() SHARED_LOCKS_REQUIRED(mu_
) EXCLUSIVE_LOCKS_REQUIRED(mu2
);
1273 int a_
GUARDED_BY(mu_
);
1275 Mutex mu_
ACQUIRED_AFTER(mu1
);
1290 x
= foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1304 f1
.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1310 f2
->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1316 } // end namespace thread_annot_lock_13
1318 namespace thread_annot_lock_18_modified
{
1319 // Modified: Trylocks removed
1320 // Test the ability to distnguish between the same lock field of
1321 // different objects of a class.
1324 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_
);
1325 void MyUnlock() UNLOCK_FUNCTION(mu1_
);
1326 int a_
GUARDED_BY(mu1_
);
1339 // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
1340 // expected-note {{found near match 'b1->mu1_'}}
1345 } // end namespace thread_annot_lock_18_modified
1347 namespace thread_annot_lock_21
{
1348 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1349 // uses in class definitions.
1354 int a_
GUARDED_BY(mu1_
);
1356 int *q
PT_GUARDED_BY(mu
);
1357 Mutex mu1_
ACQUIRED_AFTER(mu
);
1361 int *p
GUARDED_BY(mu
) PT_GUARDED_BY(mu
);
1363 int res
GUARDED_BY(mu
) = 5;
1369 res
= b1
.a_
+ b3
->b_
; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1370 // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
1371 // expected-note {{found near match 'b3->mu1_'}}
1372 *p
= i
; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1373 // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1374 b1
.a_
= res
+ b3
->b_
; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1375 // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
1376 // expected-note {{found near match 'b3->mu1_'}}
1377 b3
->b_
= *b1
.q
; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1379 b1
.b_
= res
; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1380 x
= res
; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1383 } // end namespace thread_annot_lock_21
1385 namespace thread_annot_lock_35_modified
{
1386 // Test the analyzer's ability to distinguish the lock field of different
1391 int a_
GUARDED_BY(lock_
);
1394 void Func(Foo
* child
) LOCKS_EXCLUDED(lock_
) {
1395 Foo
*new_foo
= new Foo
;
1399 child
->Func(new_foo
); // There shouldn't be any warning here as the
1400 // acquired lock is not in child.
1402 // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
1403 // expected-note {{found near match 'lock_'}}
1405 // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
1406 // expected-note {{found near match 'lock_'}}
1410 void bar(int y
) EXCLUSIVE_LOCKS_REQUIRED(lock_
) {
1418 Foo
*child
= new Foo
;
1421 } // end namespace thread_annot_lock_35_modified
1423 namespace thread_annot_lock_36_modified
{
1424 // Modified to move the annotations to function defns.
1425 // Test the analyzer's ability to distinguish the lock field of different
1430 int a_
GUARDED_BY(lock_
);
1433 void Func(Foo
* child
) LOCKS_EXCLUDED(lock_
);
1434 void bar(int y
) EXCLUSIVE_LOCKS_REQUIRED(lock_
);
1437 void Foo::Func(Foo
* child
) {
1438 Foo
*new_foo
= new Foo
;
1442 child
->lock_
.Lock();
1443 child
->Func(new_foo
); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1446 child
->lock_
.Unlock();
1451 void Foo::bar(int y
) {
1459 Foo
*child
= new Foo
;
1462 } // end namespace thread_annot_lock_36_modified
1465 namespace thread_annot_lock_42
{
1466 // Test support of multiple lock attributes of the same kind on a decl.
1469 Mutex mu1
, mu2
, mu3
;
1470 int x
GUARDED_BY(mu1
) GUARDED_BY(mu2
);
1471 int y
GUARDED_BY(mu2
);
1473 void f2() LOCKS_EXCLUDED(mu1
) LOCKS_EXCLUDED(mu2
) LOCKS_EXCLUDED(mu3
) {
1480 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2
) EXCLUSIVE_LOCKS_REQUIRED(mu1
) {
1482 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1483 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1491 foo
->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1492 // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1494 } // end namespace thread_annot_lock_42
1496 namespace thread_annot_lock_46
{
1497 // Test the support for annotations on virtual functions.
1500 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1501 virtual void func2() LOCKS_EXCLUDED(mu_
);
1505 class Child
: public Base
{
1507 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
1508 virtual void func2() LOCKS_EXCLUDED(mu_
);
1515 b
->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1517 b
->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1520 c
->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1522 c
->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1525 } // end namespace thread_annot_lock_46
1527 namespace thread_annot_lock_67_modified
{
1528 // Modified: attributes on definitions moved to declarations
1529 // Test annotations on out-of-line definitions of member functions where the
1530 // annotations refer to locks that are also data members in the class.
1536 int method1(int i
) SHARED_LOCKS_REQUIRED(mu1
, mu
, mu2
, mu3
);
1537 int data
GUARDED_BY(mu1
);
1542 int Foo::method1(int i
) {
1549 a
.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1550 // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1551 // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1552 // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1554 } // end namespace thread_annot_lock_67_modified
1557 namespace substitution_test
{
1562 void lockData() EXCLUSIVE_LOCK_FUNCTION(mu
);
1563 void unlockData() UNLOCK_FUNCTION(mu
);
1565 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu
) { }
1571 void lockData (MyData
*d
) EXCLUSIVE_LOCK_FUNCTION(d
->mu
);
1572 void unlockData(MyData
*d
) UNLOCK_FUNCTION(d
->mu
);
1578 void foo(MyData
* d
) EXCLUSIVE_LOCKS_REQUIRED(d
->mu
) { }
1580 void bar1(MyData
* d
) {
1586 void bar2(MyData
* d
) {
1593 void bar3(MyData
* d1
, MyData
* d2
) {
1595 dlr
.lockData(d1
); // expected-note {{mutex acquired here}}
1596 dlr
.unlockData(d2
); // \
1597 // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1598 } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
1600 void bar4(MyData
* d1
, MyData
* d2
) {
1604 // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
1605 // expected-note {{found near match 'd1->mu'}}
1610 // Automatic object destructor calls don't appear as expressions in the CFG,
1611 // so we have to handle them separately whenever substitutions are required.
1612 struct DestructorRequires
{
1614 ~DestructorRequires() EXCLUSIVE_LOCKS_REQUIRED(mu
);
1617 void destructorRequires() {
1618 DestructorRequires rd
;
1622 struct DestructorExcludes
{
1624 ~DestructorExcludes() LOCKS_EXCLUDED(mu
);
1627 void destructorExcludes() {
1628 DestructorExcludes ed
;
1629 ed
.mu
.Lock(); // expected-note {{mutex acquired here}}
1630 } // expected-warning {{cannot call function '~DestructorExcludes' while mutex 'ed.mu' is held}}
1631 // expected-warning@-1 {{mutex 'ed.mu' is still held at the end of function}}
1633 } // end namespace substituation_test
1637 namespace constructor_destructor_tests
{
1639 int myVar
GUARDED_BY(fooMu
);
1643 Foo() EXCLUSIVE_LOCK_FUNCTION(fooMu
) { }
1644 ~Foo() UNLOCK_FUNCTION(fooMu
) { }
1654 namespace template_member_test
{
1656 struct S
{ int n
; };
1659 S
*s
GUARDED_BY(this->m
);
1668 template<typename U
>
1669 struct IndirectLock
{
1670 int DoNaughtyThings(T
*t
) {
1671 u
->n
= 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1672 return t
->s
->n
; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
1676 template struct IndirectLock
<int>; // expected-note {{here}}
1683 V
*p
GUARDED_BY(this->m
);
1685 template<typename U
> struct W
{
1688 v
.p
->f(u
); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1691 template struct W
<int>; // expected-note {{here}}
1695 namespace test_scoped_lockable
{
1697 struct TestScopedLockable
{
1700 int a
__attribute__((guarded_by(mu1
)));
1701 int b
__attribute__((guarded_by(mu2
)));
1706 MutexLock
mulock(&mu1
);
1710 #ifdef __cpp_guaranteed_copy_elision
1712 const MutexLock mulock
= MutexLock(&mu1
);
1718 MutexLock
{&mu1
}, a
= 5;
1721 void lifetime_extension() {
1722 const MutexLock
&mulock
= MutexLock(&mu1
);
1727 ReaderMutexLock
mulock1(&mu1
);
1729 MutexLock
mulock2a(&mu2
);
1733 MutexLock
mulock2b(&mu2
);
1739 MutexLock
mulock_a(&mu1
); // expected-note{{mutex acquired here}}
1740 MutexLock
mulock_b(&mu1
); // \
1741 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1744 void temporary_double_lock() {
1745 MutexLock
mulock_a(&mu1
); // expected-note{{mutex acquired here}}
1746 MutexLock
{&mu1
}; // \
1747 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1751 MutexLock
mulock1(&mu1
), mulock2(&mu2
);
1757 DoubleMutexLock
mulock(&mu1
, &mu2
);
1763 } // end namespace test_scoped_lockable
1766 namespace FunctionAttrTest
{
1771 int a
GUARDED_BY(mu_
);
1776 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj
.mu_
);
1779 foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1782 fooObj
.mu_
.Unlock();
1785 }; // end namespace FunctionAttrTest
1788 namespace TryLockTest
{
1790 struct TestTryLock
{
1792 int a
GUARDED_BY(mu
);
1803 if (!mu
.TryLock()) return;
1808 void foo2_builtin_expect() {
1809 if (__builtin_expect(!mu
.TryLock(), false))
1816 bool b
= mu
.TryLock();
1823 void foo3_builtin_expect() {
1824 bool b
= mu
.TryLock();
1825 if (__builtin_expect(b
, true)) {
1832 bool b
= mu
.TryLock();
1839 while (mu
.TryLock()) {
1846 bool b
= mu
.TryLock();
1854 bool b1
= mu
.TryLock();
1863 // Test use-def chains: join points
1865 bool b
= mu
.TryLock();
1869 if (b
) { // b should be unknown at this point, because of the join point
1870 a
= 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1872 if (b2
) { // b2 should be known at this point.
1878 // Test use-def-chains: back edges
1880 bool b
= mu
.TryLock();
1882 for (int i
= 0; i
< 10; ++i
);
1884 if (b
) { // b is still known, because the loop doesn't alter it
1890 // Test use-def chains: back edges
1892 bool b
= mu
.TryLock();
1895 if (b
) { // b should be unknown at this point b/c of the loop
1896 a
= 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1902 // Test merge of exclusive trylock
1915 // Test merge of shared trylock
1918 if (!mu
.ReaderTryLock())
1928 // Test with conditional operator
1930 if (mu
.TryLock() ? 1 : 0)
1935 if (mu
.TryLock() ? 0 : 1)
1941 if (mu
.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}}
1942 mu
.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}}
1943 } // expected-warning{{mutex 'mu' is not held on every path through here}}
1944 }; // end TestTrylock
1946 } // end namespace TrylockTest
1949 namespace TestTemplateAttributeInstantiation
{
1954 int a
GUARDED_BY(mu_
);
1959 int a
GUARDED_BY(mu_
);
1966 // Test non-dependent expressions in attributes on template functions
1968 void barND(Foo1
*foo
, T
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(foo
->mu_
) {
1972 // Test dependent expressions in attributes on template functions
1974 void barD(Foo1
*foo
, T
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(fooT
->mu_
) {
1986 // Test non-dependent expression in ordinary method on template class
1987 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase
.mu_
) {
1991 // Test dependent expressions in ordinary methods on template class
1992 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT
.mu_
) {
1996 // Test dependent expressions in template method in template class
1998 void barTD(T2
*fooT
) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT
.mu_
, fooT
->mu_
) {
2008 // Test dependent guarded_by
2009 T data
GUARDED_BY(mu_
);
2011 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2030 bt
.fooBase
.mu_
.Lock();
2031 bt
.fooBaseT
.mu_
.Lock();
2041 // expected-warning {{calling function 'barTD<TestTemplateAttributeInstantiation::Foo1>' requires holding mutex 'f1.mu_' exclusively}} \
2042 // expected-note {{found near match 'bt.fooBase.mu_'}}
2044 bt
.fooBase
.mu_
.Unlock();
2045 bt
.fooBaseT
.mu_
.Unlock();
2050 // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
2061 // Test dependent guarded_by
2062 T data
GUARDED_BY(mu_
);
2063 static T static_data
GUARDED_BY(static_mu_
);
2065 void fooEx(CellDelayed
<T
> *other
) EXCLUSIVE_LOCKS_REQUIRED(mu_
, other
->mu_
) {
2066 this->data
= other
->data
;
2070 void fooExT(CellDelayed
<T2
> *otherT
) EXCLUSIVE_LOCKS_REQUIRED(mu_
, otherT
->mu_
) {
2071 this->data
= otherT
->data
;
2081 static Mutex static_mu_
;
2084 void testDelayed() {
2085 CellDelayed
<int> celld
;
2086 CellDelayed
<int> celld2
;
2091 celld
.fooEx(&celld2
);
2092 celld
.fooExT(&celld2
);
2094 celld2
.mu_
.Unlock();
2098 }; // end namespace TestTemplateAttributeInstantiation
2101 namespace FunctionDeclDefTest
{
2106 int a
GUARDED_BY(mu_
);
2108 virtual void foo1(Foo
*f_declared
) EXCLUSIVE_LOCKS_REQUIRED(f_declared
->mu_
);
2111 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
2112 void Foo::foo1(Foo
*f_defined
) {
2118 myfoo
.foo1(&myfoo
); // \
2119 // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2127 namespace GoingNative
{
2129 struct LOCKABLE mutex
{
2130 void lock() EXCLUSIVE_LOCK_FUNCTION();
2131 void unlock() UNLOCK_FUNCTION();
2139 while (foo()) { // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
2149 m
.lock(); // expected-note {{mutex acquired here}}
2158 namespace FunctionDefinitionTest
{
2164 void foo3(Foo
*other
);
2167 void fooT1(const T
& dummy1
);
2170 void fooT2(const T
& dummy2
) EXCLUSIVE_LOCKS_REQUIRED(mu_
);
2173 int a
GUARDED_BY(mu_
);
2182 T a
GUARDED_BY(mu_
);
2186 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS
{
2190 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2194 void Foo::foo3(Foo
*other
) EXCLUSIVE_LOCKS_REQUIRED(other
->mu_
) {
2199 void Foo::fooT1(const T
& dummy1
) EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2203 /* TODO -- uncomment with template instantiation of attributes.
2205 void Foo::fooT2(const T& dummy2) {
2210 void fooF1(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
) {
2215 void fooF2(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
) {
2219 void fooF3(Foo
*f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
);
2220 void fooF3(Foo
*f
) {
2225 void FooT
<T
>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
2234 // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2235 myFoo
.foo3(&myFoo
); // \
2236 // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2237 myFoo
.fooT1(dummy
); // \
2238 // expected-warning {{calling function 'fooT1<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2240 myFoo
.fooT2(dummy
); // \
2241 // expected-warning {{calling function 'fooT2<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2244 // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2246 // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2248 // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2264 // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2267 } // end namespace FunctionDefinitionTest
2270 namespace SelfLockingTest
{
2272 class LOCKABLE MyLock
{
2274 int foo
GUARDED_BY(this);
2276 void lock() EXCLUSIVE_LOCK_FUNCTION();
2277 void unlock() UNLOCK_FUNCTION();
2279 void doSomething() {
2280 this->lock(); // allow 'this' as a lock expression
2286 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2292 // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
2297 class LOCKABLE MyLock2
{
2300 int foo
GUARDED_BY(this);
2302 // don't check inside lock and unlock functions
2303 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_
.Lock(); }
2304 void unlock() UNLOCK_FUNCTION() { mu_
.Unlock(); }
2306 // don't check inside constructors and destructors
2307 MyLock2() { foo
= 1; }
2308 ~MyLock2() { foo
= 0; }
2312 } // end namespace SelfLockingTest
2315 namespace InvalidNonstatic
{
2317 // Forward decl here causes bogus "invalid use of non-static data member"
2318 // on reference to mutex_ in guarded_by attribute.
2324 int foo
__attribute__((guarded_by(mutex_
)));
2327 } // end namespace InvalidNonStatic
2330 namespace NoReturnTest
{
2333 void fatal() __attribute__((noreturn
));
2338 MutexLock
lock(&mu_
);
2345 } // end namespace NoReturnTest
2348 namespace TestMultiDecl
{
2352 int GUARDED_BY(mu_
) a
;
2353 int GUARDED_BY(mu_
) b
, c
;
2357 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2359 // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2361 // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2368 } // end namespace TestMultiDecl
2371 namespace WarnNoDecl
{
2374 void foo(int a
); __attribute__(( // \
2375 // expected-warning {{declaration does not declare anything}}
2376 exclusive_locks_required(a
))); // \
2377 // expected-warning {{attribute exclusive_locks_required ignored}}
2380 } // end namespace WarnNoDecl
2384 namespace MoreLockExpressions
{
2389 int a
GUARDED_BY(mu_
);
2397 Foo
& getFoo() { return *f
; }
2398 Foo
& getFoo2(int c
) { return *f
; }
2399 Foo
& getFoo3(int c
, int d
) { return *f
; }
2401 Foo
& getFooey() { return *f
; }
2404 Foo
& getBarFoo(Bar
&bar
, int c
) { return bar
.getFoo2(c
); }
2409 Foo
&(*fooFuncPtr
)();
2415 bar
.getFoo().mu_
.Lock();
2417 bar
.getFoo().mu_
.Unlock();
2419 (bar
.getFoo().mu_
).Lock(); // test parenthesis
2421 (bar
.getFoo().mu_
).Unlock();
2423 bar
.getFoo2(a
).mu_
.Lock();
2424 bar
.getFoo2(a
).a
= 0;
2425 bar
.getFoo2(a
).mu_
.Unlock();
2427 bar
.getFoo3(a
, b
).mu_
.Lock();
2428 bar
.getFoo3(a
, b
).a
= 0;
2429 bar
.getFoo3(a
, b
).mu_
.Unlock();
2431 getBarFoo(bar
, a
).mu_
.Lock();
2432 getBarFoo(bar
, a
).a
= 0;
2433 getBarFoo(bar
, a
).mu_
.Unlock();
2435 bar
.getFoo2(10).mu_
.Lock();
2436 bar
.getFoo2(10).a
= 0;
2437 bar
.getFoo2(10).mu_
.Unlock();
2439 bar
.getFoo2(a
+ 1).mu_
.Lock();
2440 bar
.getFoo2(a
+ 1).a
= 0;
2441 bar
.getFoo2(a
+ 1).mu_
.Unlock();
2443 (a
> 0 ? fooArray
[1] : fooArray
[b
]).mu_
.Lock();
2444 (a
> 0 ? fooArray
[1] : fooArray
[b
]).a
= 0;
2445 (a
> 0 ? fooArray
[1] : fooArray
[b
]).mu_
.Unlock();
2447 fooFuncPtr().mu_
.Lock();
2449 fooFuncPtr().mu_
.Unlock();
2460 bar
.getFoo().mu_
.Lock();
2461 bar
.getFooey().a
= 0; // \
2462 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
2463 // expected-note {{found near match 'bar.getFoo().mu_'}}
2464 bar
.getFoo().mu_
.Unlock();
2466 bar
.getFoo2(a
).mu_
.Lock();
2467 bar
.getFoo2(b
).a
= 0; // \
2468 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
2469 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2470 bar
.getFoo2(a
).mu_
.Unlock();
2472 bar
.getFoo3(a
, b
).mu_
.Lock();
2473 bar
.getFoo3(a
, c
).a
= 0; // \
2474 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \
2475 // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}
2476 bar
.getFoo3(a
, b
).mu_
.Unlock();
2478 getBarFoo(bar
, a
).mu_
.Lock();
2479 getBarFoo(bar
, b
).a
= 0; // \
2480 // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \
2481 // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}
2482 getBarFoo(bar
, a
).mu_
.Unlock();
2484 (a
> 0 ? fooArray
[1] : fooArray
[b
]).mu_
.Lock();
2485 (a
> 0 ? fooArray
[b
] : fooArray
[c
]).a
= 0; // \
2486 // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \
2487 // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}
2488 (a
> 0 ? fooArray
[1] : fooArray
[b
]).mu_
.Unlock();
2492 } // end namespace MoreLockExpressions
2495 namespace TrylockJoinPoint
{
2512 } // end namespace TrylockJoinPoint
2515 namespace LockReturned
{
2519 int a
GUARDED_BY(mu_
);
2520 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
2521 void foo2(Foo
* f
) EXCLUSIVE_LOCKS_REQUIRED(mu_
, f
->mu_
);
2523 static void sfoo(Foo
* f
) EXCLUSIVE_LOCKS_REQUIRED(f
->mu_
);
2525 Mutex
* getMu() LOCK_RETURNED(mu_
);
2529 static Mutex
* getMu(Foo
* f
) LOCK_RETURNED(f
->mu_
);
2533 // Calls getMu() directly to lock and unlock
2534 void test1(Foo
* f1
, Foo
* f2
) {
2535 f1
->a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2536 f1
->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2538 f1
->foo2(f2
); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2539 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2540 Foo::sfoo(f1
); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2542 f1
->getMu()->Lock();
2547 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
2548 // expected-note {{found near match 'f1->mu_'}}
2550 Foo::getMu(f2
)->Lock();
2552 Foo::getMu(f2
)->Unlock();
2556 f1
->getMu()->Unlock();
2560 Mutex
* getFooMu(Foo
* f
) LOCK_RETURNED(Foo::getMu(f
));
2562 class Bar
: public Foo
{
2564 int b
GUARDED_BY(getMu());
2565 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2566 void bar2(Bar
* g
) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g
->getMu());
2568 static void sbar(Bar
* g
) EXCLUSIVE_LOCKS_REQUIRED(g
->getMu());
2569 static void sbar2(Bar
* g
) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g
));
2574 // Use getMu() within other attributes.
2575 // This requires at lest levels of substitution, more in the case of
2576 void test2(Bar
* b1
, Bar
* b2
) {
2577 b1
->b
= 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2578 b1
->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2579 b1
->bar2(b2
); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2580 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2581 Bar::sbar(b1
); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2582 Bar::sbar2(b1
); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2584 b1
->getMu()->Lock();
2589 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
2590 // // expected-note {{found near match 'b1->mu_'}}
2592 b2
->getMu()->Lock();
2595 b2
->getMu()->Unlock();
2600 b1
->getMu()->Unlock();
2604 // Lock the mutex directly, but use attributes that call getMu()
2605 // Also lock the mutex using getFooMu, which calls a lock_returned function.
2606 void test3(Bar
* b1
, Bar
* b2
) {
2611 getFooMu(b2
)->Lock();
2613 getFooMu(b2
)->Unlock();
2621 } // end namespace LockReturned
2624 namespace ReleasableScopedLock
{
2629 int a
GUARDED_BY(mu_
);
2641 ReleasableMutexLock
rlock(&mu_
);
2646 ReleasableMutexLock
rlock(&mu_
);
2647 if (c
) { // test join point -- held/not held during release
2650 // No warning on join point because the lock will be released by the scope object anyway.
2654 ReleasableMutexLock
rlock(&mu_
);
2657 a
= 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2661 ReleasableMutexLock
rlock(&mu_
);
2662 rlock
.Release(); // expected-note{{mutex released here}}
2663 rlock
.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2667 ReleasableMutexLock
rlock(&mu_
);
2671 // No warning on join point because the lock will be released by the scope object anyway.
2672 rlock
.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2676 ReleasableMutexLock
rlock(&mu_
);
2683 // No warning on join point because the lock will be released by the scope object anyway
2684 a
= 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2688 } // end namespace ReleasableScopedLock
2691 namespace RelockableScopedLock
{
2693 class DeferTraits
{};
2695 class SCOPED_LOCKABLE RelockableExclusiveMutexLock
{
2697 RelockableExclusiveMutexLock(Mutex
*mu
) EXCLUSIVE_LOCK_FUNCTION(mu
);
2698 RelockableExclusiveMutexLock(Mutex
*mu
, DeferTraits
) LOCKS_EXCLUDED(mu
);
2699 ~RelockableExclusiveMutexLock() EXCLUSIVE_UNLOCK_FUNCTION();
2701 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2702 void Unlock() UNLOCK_FUNCTION();
2705 struct SharedTraits
{};
2706 struct ExclusiveTraits
{};
2708 class SCOPED_LOCKABLE RelockableMutexLock
{
2710 RelockableMutexLock(Mutex
*mu
, DeferTraits
) LOCKS_EXCLUDED(mu
);
2711 RelockableMutexLock(Mutex
*mu
, SharedTraits
) SHARED_LOCK_FUNCTION(mu
);
2712 RelockableMutexLock(Mutex
*mu
, ExclusiveTraits
) EXCLUSIVE_LOCK_FUNCTION(mu
);
2713 ~RelockableMutexLock() UNLOCK_FUNCTION();
2715 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2716 void Unlock() UNLOCK_FUNCTION();
2718 void ReaderLock() SHARED_LOCK_FUNCTION();
2719 void ReaderUnlock() UNLOCK_FUNCTION();
2721 void PromoteShared() UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();
2722 void DemoteExclusive() UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();
2726 int x
GUARDED_BY(mu
);
2732 RelockableExclusiveMutexLock
scope(&mu
);
2736 x
= 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2743 RelockableExclusiveMutexLock
scope(&mu
, DeferTraits
{});
2744 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2749 void relockExclusive() {
2750 RelockableMutexLock
scope(&mu
, SharedTraits
{});
2752 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2753 scope
.ReaderUnlock();
2755 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2761 scope
.DemoteExclusive();
2763 x
= 5; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2766 void relockShared() {
2767 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{});
2772 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2776 x
= 4; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2778 scope
.PromoteShared();
2783 void deferLockShared() {
2784 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2785 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2788 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2791 void doubleUnlock() {
2792 RelockableExclusiveMutexLock
scope(&mu
);
2793 scope
.Unlock(); // expected-note{{mutex released here}}
2794 scope
.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
2797 void doubleLock1() {
2798 RelockableExclusiveMutexLock
scope(&mu
); // expected-note{{mutex acquired here}}
2799 scope
.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2802 void doubleLock2() {
2803 RelockableExclusiveMutexLock
scope(&mu
);
2805 scope
.Lock(); // expected-note{{mutex acquired here}}
2806 scope
.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2810 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2813 // No warning on join point because the lock will be released by the scope object anyway.
2814 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2818 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2822 // No warning on join point because the lock will be released by the scope object anyway.
2823 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2826 void loopAcquire() {
2827 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2828 for (unsigned i
= 1; i
< 10; ++i
)
2829 scope
.Lock(); // We could catch this double lock with negative capabilities.
2832 void loopRelease() {
2833 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{}); // expected-note {{mutex acquired here}}
2834 // We have to warn on this join point despite the lock being managed ...
2835 for (unsigned i
= 1; i
< 10; ++i
) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}
2836 x
= 1; // ... because we might miss that this doesn't always happen under lock.
2842 void loopPromote() {
2843 RelockableMutexLock
scope(&mu
, SharedTraits
{});
2844 for (unsigned i
= 1; i
< 10; ++i
) {
2845 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2847 scope
.PromoteShared();
2852 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{}); // expected-note {{the other acquisition of mutex 'mu' is here}}
2853 // We have to warn on this join point despite the lock being managed ...
2854 for (unsigned i
= 1; i
< 10; ++i
) {
2855 x
= 1; // ... because we might miss that this doesn't always happen under exclusive lock.
2857 scope
.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}
2861 void loopAcquireContinue() {
2862 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2863 for (unsigned i
= 1; i
< 10; ++i
) {
2864 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2872 void loopReleaseContinue() {
2873 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{}); // expected-note {{mutex acquired here}}
2874 // We have to warn on this join point despite the lock being managed ...
2875 for (unsigned i
= 1; i
< 10; ++i
) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}
2876 x
= 1; // ... because we might miss that this doesn't always happen under lock.
2884 void loopPromoteContinue() {
2885 RelockableMutexLock
scope(&mu
, SharedTraits
{});
2886 for (unsigned i
= 1; i
< 10; ++i
) {
2887 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2889 scope
.PromoteShared();
2895 void loopDemoteContinue() {
2896 RelockableMutexLock
scope(&mu
, ExclusiveTraits
{}); // expected-note {{the other acquisition of mutex 'mu' is here}}
2897 // We have to warn on this join point despite the lock being managed ...
2898 for (unsigned i
= 1; i
< 10; ++i
) {
2899 x
= 1; // ... because we might miss that this doesn't always happen under exclusive lock.
2901 scope
.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}
2907 void exclusiveSharedJoin() {
2908 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2913 // No warning on join point because the lock will be released by the scope object anyway.
2915 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2918 void sharedExclusiveJoin() {
2919 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2924 // No warning on join point because the lock will be released by the scope object anyway.
2926 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2930 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2938 void assertSharedJoin() {
2939 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2943 mu
.AssertReaderHeld();
2945 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2948 void assertStrongerJoin() {
2949 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2955 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2958 void assertWeakerJoin() {
2959 RelockableMutexLock
scope(&mu
, DeferTraits
{});
2963 mu
.AssertReaderHeld();
2965 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2968 void directUnlock() {
2969 RelockableExclusiveMutexLock
scope(&mu
);
2971 // Debatable that there is no warning. Currently we don't track in the scoped
2972 // object whether it is active, but just check if the contained locks can be
2973 // reacquired. Here they can, because mu has been unlocked manually.
2977 void directRelock() {
2978 RelockableExclusiveMutexLock
scope(&mu
);
2981 // Similarly debatable that there is no warning.
2985 // Doesn't make a lot of sense, just making sure there is no crash.
2986 void destructLock() {
2987 RelockableExclusiveMutexLock
scope(&mu
);
2988 scope
.~RelockableExclusiveMutexLock();
2989 scope
.Lock(); // Should be UB, so we don't really care.
2992 class SCOPED_LOCKABLE MemberLock
{
2994 MemberLock() EXCLUSIVE_LOCK_FUNCTION(mutex
);
2995 ~MemberLock() UNLOCK_FUNCTION(mutex
);
2996 void Lock() EXCLUSIVE_LOCK_FUNCTION(mutex
);
3000 void relockShared2() {
3001 MemberLock lock
; // expected-note{{mutex acquired here}}
3002 lock
.Lock(); // expected-warning {{acquiring mutex 'lock.mutex' that is already held}}
3005 class SCOPED_LOCKABLE WeirdScope
{
3010 WeirdScope(Mutex
*mutex
) EXCLUSIVE_LOCK_FUNCTION(mutex
);
3011 void unlock() EXCLUSIVE_UNLOCK_FUNCTION() EXCLUSIVE_UNLOCK_FUNCTION(other
);
3012 void lock() EXCLUSIVE_LOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION(other
);
3013 ~WeirdScope() EXCLUSIVE_UNLOCK_FUNCTION();
3015 void requireOther() EXCLUSIVE_LOCKS_REQUIRED(other
);
3018 void relockWeird() {
3019 WeirdScope
scope(&mu
);
3021 scope
.unlock(); // expected-warning {{releasing mutex 'scope.other' that was not held}}
3023 // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3024 scope
.requireOther(); // \
3025 // expected-warning {{calling function 'requireOther' requires holding mutex 'scope.other' exclusively}}
3026 scope
.lock(); // expected-note {{mutex acquired here}}
3028 scope
.requireOther();
3029 } // expected-warning {{mutex 'scope.other' is still held at the end of function}}
3031 } // end namespace RelockableScopedLock
3034 namespace ScopedUnlock
{
3036 class SCOPED_LOCKABLE MutexUnlock
{
3038 MutexUnlock(Mutex
*mu
) EXCLUSIVE_UNLOCK_FUNCTION(mu
);
3039 ~MutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3041 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
3042 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
3045 class SCOPED_LOCKABLE ReaderMutexUnlock
{
3047 ReaderMutexUnlock(Mutex
*mu
) SHARED_UNLOCK_FUNCTION(mu
);
3048 ~ReaderMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3050 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
3051 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
3055 int x
GUARDED_BY(mu
);
3059 void simple() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3061 MutexUnlock
scope(&mu
);
3062 x
= 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3065 void simpleShared() SHARED_LOCKS_REQUIRED(mu
) {
3067 ReaderMutexUnlock
scope(&mu
);
3068 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3071 void innerUnlock() {
3072 MutexLock
outer(&mu
);
3074 MutexUnlock
inner(&mu
);
3075 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3080 void innerUnlockShared() {
3081 ReaderMutexLock
outer(&mu
);
3083 ReaderMutexUnlock
inner(&mu
);
3084 print(x
); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
3089 void manual() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3090 MutexUnlock
scope(&mu
);
3094 x
= 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3097 void join() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3098 MutexUnlock
scope(&mu
);
3101 // No warning on join point because the lock will be released by the scope object anyway.
3105 void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3106 MutexUnlock
scope(&mu
);
3107 scope
.Lock(); // expected-note{{mutex acquired here}}
3108 scope
.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
3111 void doubleUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3112 MutexUnlock
scope(&mu
); // expected-note{{mutex released here}}
3113 scope
.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
3116 class SCOPED_LOCKABLE MutexLockUnlock
{
3118 MutexLockUnlock(Mutex
*mu1
, Mutex
*mu2
) EXCLUSIVE_UNLOCK_FUNCTION(mu1
) EXCLUSIVE_LOCK_FUNCTION(mu2
);
3119 ~MutexLockUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
3121 void Release() EXCLUSIVE_UNLOCK_FUNCTION();
3122 void Acquire() EXCLUSIVE_LOCK_FUNCTION();
3126 void fn() EXCLUSIVE_LOCKS_REQUIRED(other
);
3128 void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
3129 MutexLockUnlock
scope(&mu
, &other
);
3131 x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
3134 } // end namespace ScopedUnlock
3137 namespace TrylockFunctionTest
{
3145 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_
, mu2_
);
3148 bool Foo::lockBoth() {
3149 if (!mu1_
.TryLock())
3163 } // end namespace TrylockFunctionTest
3167 namespace DoubleLockBug
{
3172 int a
GUARDED_BY(mu_
);
3174 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
3175 int foo2() SHARED_LOCKS_REQUIRED(mu_
);
3179 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
3183 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_
) {
3191 namespace UnlockBug
{
3197 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_
) { // expected-note {{mutex acquired here}}
3199 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
3202 void foo2() SHARED_LOCKS_REQUIRED(mutex_
) { // expected-note {{mutex acquired here}}
3204 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
3207 } // end namespace UnlockBug
3211 namespace FoolishScopedLockableBug
{
3213 class SCOPED_LOCKABLE WTF_ScopedLockable
{
3215 WTF_ScopedLockable(Mutex
* mu
) EXCLUSIVE_LOCK_FUNCTION(mu
);
3217 // have to call release() manually;
3218 ~WTF_ScopedLockable();
3220 void release() UNLOCK_FUNCTION();
3226 int a
GUARDED_BY(mu_
);
3232 WTF_ScopedLockable
wtf(&mu_
);
3237 WTF_ScopedLockable
wtf(&mu_
); // expected-note {{mutex acquired here}}
3238 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
3242 WTF_ScopedLockable
wtf(&mu_
);
3252 WTF_ScopedLockable
wtf(&mu_
);
3259 WTF_ScopedLockable
wtf(&mu_
); // expected-note {{mutex acquired here}}
3261 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3268 WTF_ScopedLockable
wtf(&mu_
); // expected-note {{mutex acquired here}}
3270 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3274 } // end namespace FoolishScopedLockableBug
3278 namespace TemporaryCleanupExpr
{
3281 int a
GUARDED_BY(getMutexPtr().get());
3283 SmartPtr
<Mutex
> getMutexPtr();
3291 ReaderMutexLock
lock(getMutexPtr().get());
3294 int b
= a
; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
3297 #ifdef __cpp_guaranteed_copy_elision
3299 void guaranteed_copy_elision() {
3300 MutexLock lock
= MutexLock
{&sls_mu
};
3304 void guaranteed_copy_elision_const() {
3305 const MutexLock lock
= MutexLock
{&sls_mu
};
3311 } // end namespace TemporaryCleanupExpr
3315 namespace SmartPointerTests
{
3319 SmartPtr
<Mutex
> mu_
;
3320 int a
GUARDED_BY(mu_
);
3321 int b
GUARDED_BY(mu_
.get());
3322 int c
GUARDED_BY(*mu_
);
3324 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_
);
3325 void Unlock() UNLOCK_FUNCTION(mu_
);
3339 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3340 b
= 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
3341 c
= 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
3366 mu_
.get()->Unlock();
3371 MutexLock
lock(mu_
.get());
3379 MutexLock
lock(&(*mu_
));
3410 mu_
.get()->Unlock();
3424 mu_
->Lock(); // expected-note 2 {{mutex acquired here}}
3425 mu_
.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3426 (*mu_
).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3427 mu_
.get()->Unlock(); // expected-note {{mutex released here}}
3428 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
3443 foo
->a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
3444 (*foo
).b
= 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
3445 foo
.get()->c
= 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
3463 foo
.get()->mu_
->Unlock();
3468 MutexLock
lock(foo
->mu_
.get());
3474 } // end namespace SmartPointerTests
3478 namespace DuplicateAttributeTest
{
3480 class LOCKABLE Foo
{
3485 int a
GUARDED_BY(mu1_
);
3486 int b
GUARDED_BY(mu2_
);
3487 int c
GUARDED_BY(mu3_
);
3489 void lock() EXCLUSIVE_LOCK_FUNCTION();
3490 void unlock() UNLOCK_FUNCTION();
3492 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_
);
3493 void slock1() SHARED_LOCK_FUNCTION(mu1_
);
3494 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
, mu3_
);
3496 EXCLUSIVE_LOCK_FUNCTION(mu1_
)
3497 EXCLUSIVE_LOCK_FUNCTION(mu2_
)
3498 EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
, mu3_
);
3500 void unlock1() UNLOCK_FUNCTION(mu1_
);
3501 void unlock3() UNLOCK_FUNCTION(mu1_
, mu2_
, mu3_
);
3503 UNLOCK_FUNCTION(mu1_
)
3504 UNLOCK_FUNCTION(mu2_
)
3505 UNLOCK_FUNCTION(mu1_
, mu2_
, mu3_
);
3509 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
3510 void Foo::unlock() UNLOCK_FUNCTION() { }
3512 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_
) {
3516 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_
) {
3520 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
, mu3_
) {
3526 void Foo::locklots()
3527 EXCLUSIVE_LOCK_FUNCTION(mu1_
, mu2_
)
3528 EXCLUSIVE_LOCK_FUNCTION(mu2_
, mu3_
) {
3534 void Foo::unlock1() UNLOCK_FUNCTION(mu1_
) {
3538 void Foo::unlock3() UNLOCK_FUNCTION(mu1_
, mu2_
, mu3_
) {
3544 void Foo::unlocklots()
3545 UNLOCK_FUNCTION(mu1_
, mu2_
)
3546 UNLOCK_FUNCTION(mu2_
, mu3_
) {
3558 foo
.lock(); // expected-note{{mutex acquired here}}
3559 foo
.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
3560 foo
.unlock(); // expected-note{{mutex released here}}
3561 foo
.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
3571 foo
.lock1(); // expected-note{{mutex acquired here}}
3572 foo
.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3574 foo
.unlock1(); // expected-note{{mutex released here}}
3575 foo
.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3585 foo
.slock1(); // expected-note{{mutex acquired here}}
3586 foo
.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3588 foo
.unlock1(); // expected-note{{mutex released here}}
3589 foo
.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3602 foo
.lock3(); // expected-note 3 {{mutex acquired here}}
3604 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3605 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3606 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3610 foo
.unlock3(); // expected-note 3 {{mutex released here}}
3612 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3613 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3614 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3626 foo
.locklots(); // expected-note 3 {{mutex acquired here}}
3627 foo
.locklots(); // \
3628 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3629 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3630 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3634 foo
.unlocklots(); // expected-note 3 {{mutex released here}}
3635 foo
.unlocklots(); // \
3636 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3637 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3638 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3641 } // end namespace DuplicateAttributeTest
3645 namespace TryLockEqTest
{
3649 int a
GUARDED_BY(mu_
);
3652 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_
);
3653 Mutex
* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_
);
3654 void unlock() UNLOCK_FUNCTION(mu_
);
3662 if (tryLockMutexP() == 0) {
3663 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3669 if (tryLockMutexP() != 0) {
3674 if (0 != tryLockMutexP()) {
3679 if (!(tryLockMutexP() == 0)) {
3684 if (tryLockMutexI() == 0) {
3685 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3691 if (0 == tryLockMutexI()) {
3692 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3698 if (tryLockMutexI() == 1) {
3703 if (mu_
.TryLock() == false) {
3704 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3710 if (mu_
.TryLock() == true) {
3715 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3718 #if __has_feature(cxx_nullptr)
3719 if (tryLockMutexP() == nullptr) {
3720 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3728 } // end namespace TryLockEqTest
3731 namespace ExistentialPatternMatching
{
3738 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_
);
3739 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_
);
3743 int a
GUARDED_BY(&Graph::mu_
);
3745 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_
) {
3748 void foo2() LOCKS_EXCLUDED(&Graph::mu_
);
3756 n1
.a
= 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3757 n1
.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3763 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3769 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3775 n1
.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3784 LockAllGraphs(); // expected-note{{mutex acquired here}}
3785 g1
.mu_
.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3789 } // end namespace ExistentialPatternMatching
3792 namespace StringIgnoreTest
{
3797 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3798 void unlock() UNLOCK_FUNCTION("");
3799 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3800 void roober() SHARED_LOCKS_REQUIRED("");
3804 class Bar
: public Foo
{
3814 } // end namespace StringIgnoreTest
3817 namespace LockReturnedScopeFix
{
3824 const Mutex
& getLock(const Inner
* i
);
3826 void lockInner (Inner
* i
) EXCLUSIVE_LOCK_FUNCTION(getLock(i
));
3827 void unlockInner(Inner
* i
) UNLOCK_FUNCTION(getLock(i
));
3828 void foo(Inner
* i
) EXCLUSIVE_LOCKS_REQUIRED(getLock(i
));
3834 struct Base::Inner
{
3836 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_
);
3840 const Mutex
& Base::getLock(const Inner
* i
) LOCK_RETURNED(i
->lock_
) {
3845 void Base::foo(Inner
* i
) {
3849 void Base::bar(Inner
* i
) {
3860 } // end namespace LockReturnedScopeFix
3863 namespace TrylockWithCleanups
{
3867 int a
GUARDED_BY(mu_
);
3870 Foo
* GetAndLockFoo(const MyString
& s
)
3871 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_
);
3873 static void test() {
3874 Foo
* lt
= GetAndLockFoo("foo");
3880 } // end namespace TrylockWithCleanups
3883 namespace UniversalLock
{
3889 int a
GUARDED_BY(mu_
);
3890 void r_foo() SHARED_LOCKS_REQUIRED(mu_
);
3891 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
3896 beginNoWarnOnReads();
3901 beginNoWarnOnWrites();
3904 endNoWarnOnWrites();
3907 // don't warn on joins with universal lock
3910 beginNoWarnOnWrites();
3913 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3914 endNoWarnOnWrites(); // \
3915 // expected-warning {{releasing wildcard '*' that was not held}}
3919 // make sure the universal lock joins properly
3923 beginNoWarnOnWrites();
3926 beginNoWarnOnWrites();
3930 endNoWarnOnWrites();
3935 // combine universal lock with other locks
3937 beginNoWarnOnWrites();
3940 endNoWarnOnWrites();
3943 beginNoWarnOnWrites();
3944 endNoWarnOnWrites();
3948 beginNoWarnOnWrites();
3950 endNoWarnOnWrites();
3954 } // end namespace UniversalLock
3957 namespace TemplateLockReturned
{
3962 virtual void baseMethod() = 0;
3963 Mutex
* get_mutex() LOCK_RETURNED(mutex_
) { return &mutex_
; }
3966 int a
GUARDED_BY(mutex_
);
3970 class Derived
: public BaseT
<int> {
3972 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
3977 } // end namespace TemplateLockReturned
3980 namespace ExprMatchingBugFix
{
3992 Bar(Foo
* f
) : foo(f
) { }
3996 Nested(Foo
* f
) : foo(f
) { }
3998 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_
);
4008 Nested
*n
= new Nested(foo
);
4016 }; // end namespace ExprMatchingBugfix
4019 namespace ComplexNameTest
{
4025 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) { }
4026 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
) { }
4028 int operator[](int i
) EXCLUSIVE_LOCKS_REQUIRED(mu_
) { return 0; }
4035 Bar() LOCKS_EXCLUDED(mu_
) { }
4036 ~Bar() LOCKS_EXCLUDED(mu_
) { }
4038 int operator[](int i
) LOCKS_EXCLUDED(mu_
) { return 0; }
4043 Foo f
; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
4044 int a
= f
[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
4045 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
4051 Bar b
; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
4052 int a
= b
[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
4053 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
4057 }; // end namespace ComplexNameTest
4060 namespace UnreachableExitTest
{
4065 ~FemmeFatale() __attribute__((noreturn
));
4068 void exitNow() __attribute__((noreturn
));
4069 void exitDestruct(const MyString
& ms
) __attribute__((noreturn
));
4073 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4077 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4083 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4092 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_
) {
4093 exitDestruct("foo");
4096 } // end namespace UnreachableExitTest
4099 namespace VirtualMethodCanonicalizationTest
{
4103 virtual Mutex
* getMutex() = 0;
4106 class Base2
: public Base
{
4111 class Base3
: public Base2
{
4116 class Derived
: public Base3
{
4118 Mutex
* getMutex(); // overrides Base::getMutex()
4121 void baseFun(Base
*b
) EXCLUSIVE_LOCKS_REQUIRED(b
->getMutex()) { }
4123 void derivedFun(Derived
*d
) EXCLUSIVE_LOCKS_REQUIRED(d
->getMutex()) {
4127 } // end namespace VirtualMethodCanonicalizationTest
4130 namespace TemplateFunctionParamRemapTest
{
4141 void elr(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4147 void Foo::elr(Cell
<T
>* c1
) { }
4152 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}
4157 void globalELR(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4160 void globalELR(Cell
<T
>* c1
) { }
4164 globalELR(&cell
); // \
4165 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}
4170 void globalELR2(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4172 // second declaration
4174 void globalELR2(Cell
<T
>* c2
);
4177 void globalELR2(Cell
<T
>* c3
) { }
4179 // re-declaration after definition
4181 void globalELR2(Cell
<T
>* c4
);
4183 void globalTest2() {
4185 globalELR2(&cell
); // \
4186 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}
4193 void elr(Cell
<T
>* c
) EXCLUSIVE_LOCKS_REQUIRED(c
->mu_
);
4197 void FooT
<T
>::elr(Cell
<T
>* c1
) { }
4202 foo
.elr(&cell
); // \
4203 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
4206 } // end namespace TemplateFunctionParamRemapTest
4209 namespace SelfConstructorTest
{
4213 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_
);
4214 ~SelfLock() UNLOCK_FUNCTION(mu_
);
4216 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
4221 class LOCKABLE SelfLock2
{
4223 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
4224 ~SelfLock2() UNLOCK_FUNCTION();
4226 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
4229 class SelfLockDeferred
{
4231 SelfLockDeferred() LOCKS_EXCLUDED(mu_
);
4232 ~SelfLockDeferred() UNLOCK_FUNCTION(mu_
);
4237 class LOCKABLE SelfLockDeferred2
{
4239 SelfLockDeferred2() LOCKS_EXCLUDED(this);
4240 ~SelfLockDeferred2() UNLOCK_FUNCTION();
4254 void testDeferredTemporary() {
4255 SelfLockDeferred(); // expected-warning {{releasing mutex '<temporary>.mu_' that was not held}}
4258 void testDeferredTemporary2() {
4259 SelfLockDeferred2(); // expected-warning {{releasing mutex '<temporary>' that was not held}}
4262 } // end namespace SelfConstructorTest
4265 namespace MultipleAttributeTest
{
4270 int a
GUARDED_BY(mu1_
);
4271 int b
GUARDED_BY(mu2_
);
4272 int c
GUARDED_BY(mu1_
) GUARDED_BY(mu2_
);
4273 int* d
PT_GUARDED_BY(mu1_
) PT_GUARDED_BY(mu2_
);
4275 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_
)
4276 EXCLUSIVE_LOCKS_REQUIRED(mu2_
);
4277 void foo2() SHARED_LOCKS_REQUIRED(mu1_
)
4278 SHARED_LOCKS_REQUIRED(mu2_
);
4279 void foo3() LOCKS_EXCLUDED(mu1_
)
4280 LOCKS_EXCLUDED(mu2_
);
4281 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_
)
4282 EXCLUSIVE_LOCK_FUNCTION(mu2_
);
4283 void readerlock() SHARED_LOCK_FUNCTION(mu1_
)
4284 SHARED_LOCK_FUNCTION(mu2_
);
4285 void unlock() UNLOCK_FUNCTION(mu1_
)
4286 UNLOCK_FUNCTION(mu2_
);
4287 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_
)
4288 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_
);
4289 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_
)
4290 SHARED_TRYLOCK_FUNCTION(true, mu2_
);
4291 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_
)
4292 ASSERT_EXCLUSIVE_LOCK(mu2_
);
4294 void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_
, mu2_
);
4296 void assertShared() ASSERT_SHARED_LOCK(mu1_
)
4297 ASSERT_SHARED_LOCK(mu2_
);
4299 void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_
, mu2_
);
4303 void testAssertShared();
4316 void Foo::foo3() { }
4317 void Foo::lock() { mu1_
.Lock(); mu2_
.Lock(); }
4318 void Foo::readerlock() { mu1_
.ReaderLock(); mu2_
.ReaderLock(); }
4319 void Foo::unlock() { mu1_
.Unlock(); mu2_
.Unlock(); }
4320 bool Foo::trylock() { return true; }
4321 bool Foo::readertrylock() { return true; }
4326 foo1(); // expected-warning {{}}
4327 c
= 0; // expected-warning {{}}
4328 *d
= 0; // expected-warning {{}}
4332 foo2(); // expected-warning {{}}
4333 int x
= c
; // expected-warning {{}}
4334 int y
= *d
; // expected-warning {{}}
4338 foo3(); // expected-warning {{}}
4356 if (readertrylock()) {
4362 // Force duplication of attributes
4363 void Foo::assertBoth() { }
4364 void Foo::alsoAssertBoth() { }
4365 void Foo::assertShared() { }
4366 void Foo::alsoAssertShared() { }
4368 void Foo::testAssert() {
4381 void Foo::testAssertShared() {
4394 } // end namespace MultipleAttributeTest
4397 namespace GuardedNonPrimitiveTypeTest
{
4402 Data(int i
) : dat(i
) { }
4404 int getValue() const { return dat
; }
4405 void setValue(int i
) { dat
= i
; }
4407 int operator[](int i
) const { return dat
; }
4408 int& operator[](int i
) { return dat
; }
4410 void operator()() { }
4412 Data
& operator+=(int);
4413 Data
& operator-=(int);
4414 Data
& operator*=(int);
4415 Data
& operator/=(int);
4416 Data
& operator%=(int);
4417 Data
& operator^=(int);
4418 Data
& operator&=(int);
4419 Data
& operator|=(int);
4420 Data
& operator<<=(int);
4421 Data
& operator>>=(int);
4423 Data
& operator++(int);
4425 Data
& operator--(int);
4434 DataCell(const Data
& d
) : dat(d
) { }
4441 void showDataCell(const DataCell
& dc
);
4446 // method call tests
4448 data_
.setValue(0); // FIXME -- should be writing \
4449 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4450 int a
= data_
.getValue(); // \
4451 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4453 datap1_
->setValue(0); // FIXME -- should be writing \
4454 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4455 a
= datap1_
->getValue(); // \
4456 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4458 datap2_
->setValue(0); // FIXME -- should be writing \
4459 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4460 a
= datap2_
->getValue(); // \
4461 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4463 (*datap2_
).setValue(0); // FIXME -- should be writing \
4464 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4465 a
= (*datap2_
).getValue(); // \
4466 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4470 datap1_
->setValue(1);
4471 datap2_
->setValue(1);
4475 a
= data_
.getValue();
4476 datap1_
->setValue(0); // reads datap1_, writes *datap1_
4477 a
= datap1_
->getValue();
4478 a
= datap2_
->getValue();
4484 data_
= Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4485 *datap1_
= data_
; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
4486 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4487 *datap2_
= data_
; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
4488 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4489 data_
= *datap1_
; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4490 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4491 data_
= *datap2_
; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4492 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4493 data_
+= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4494 data_
-= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4495 data_
*= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4496 data_
/= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4497 data_
%= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4498 data_
^= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4499 data_
&= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4500 data_
|= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4501 data_
<<= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4502 data_
>>= 1; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4503 ++data_
; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4504 data_
++; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4505 --data_
; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4506 data_
--; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4508 data_
[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4509 (*datap2_
)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4511 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4514 // const operator tests
4515 void test3() const {
4516 Data
mydat(data_
); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4519 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4520 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4522 int a
= data_
[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4527 Data data_
GUARDED_BY(mu_
);
4528 Data
* datap1_
GUARDED_BY(mu_
);
4529 Data
* datap2_
PT_GUARDED_BY(mu_
);
4532 } // end namespace GuardedNonPrimitiveTypeTest
4535 namespace GuardedNonPrimitive_MemberAccess
{
4550 Cell c
GUARDED_BY(cell_mu_
);
4551 Cell
* cp
PT_GUARDED_BY(cell_mu_
);
4562 Foo foo
GUARDED_BY(mu_
);
4563 Foo
* foop
PT_GUARDED_BY(mu_
);
4566 foo
.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4568 int fa
= foo
.a
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4569 foo
.a
= fa
; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
4571 fa
= foop
->a
; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4572 foop
->a
= fa
; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4574 fa
= (*foop
).a
; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4575 (*foop
).a
= fa
; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4577 foo
.c
= Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
4578 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
4579 foo
.c
.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
4580 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
4582 foop
->c
= Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4583 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4584 foop
->c
.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4585 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4587 (*foop
).c
= Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4588 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4589 (*foop
).c
.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4590 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4594 } // namespace GuardedNonPrimitive_MemberAccess
4597 namespace TestThrowExpr
{
4613 } // end namespace TestThrowExpr
4616 namespace UnevaluatedContextTest
{
4618 // parse attribute expressions in an unevaluated context.
4620 static inline Mutex
* getMutex1();
4621 static inline Mutex
* getMutex2();
4623 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
4625 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
4627 } // end namespace UnevaluatedContextTest
4630 namespace LockUnlockFunctionTest
{
4632 // Check built-in lock functions
4633 class LOCKABLE MyLockable
{
4635 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_
.Lock(); }
4636 void readerLock() SHARED_LOCK_FUNCTION() { mu_
.ReaderLock(); }
4637 void unlock() UNLOCK_FUNCTION() { mu_
.Unlock(); }
4646 // Correct lock/unlock functions
4647 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_
) {
4651 void readerLock() SHARED_LOCK_FUNCTION(mu_
) {
4655 void unlock() UNLOCK_FUNCTION(mu_
) {
4659 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_
) {
4663 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_
) {
4667 // Check failure to lock.
4668 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4671 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4673 void readerLockBad() SHARED_LOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4676 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4678 void unlockBad() UNLOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4681 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4683 // Check locking the wrong thing.
4684 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4685 mu2_
.Lock(); // expected-note {{mutex acquired here}}
4686 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4687 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4690 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4691 mu2_
.ReaderLock(); // expected-note {{mutex acquired here}}
4692 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4693 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4696 void unlockBad2() UNLOCK_FUNCTION(mu_
) { // expected-note {{mutex acquired here}}
4697 mu2_
.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
4698 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4705 } // end namespace LockUnlockFunctionTest
4708 namespace AssertHeldTest
{
4713 int a
GUARDED_BY(mu_
);
4723 mu_
.AssertReaderHeld();
4725 a
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4739 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
4745 void test5() UNLOCK_FUNCTION(mu_
) {
4752 mu_
.Unlock(); // should this be a warning?
4774 // FIXME: should warn, because it's unclear whether we need to release or not.
4777 mu_
.Unlock(); // should this be a warning?
4785 mu_
.Lock(); // expected-note {{mutex acquired here}}
4787 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4791 mu_
.Lock(); // expected-note {{mutex acquired here}}
4796 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4798 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_
);
4808 mu_
.ReaderLock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
4810 mu_
.AssertHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}
4811 // FIXME: should instead warn because it's unclear whether we need to release or not.
4819 mu_
.Lock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}
4821 mu_
.AssertReaderHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}
4822 // FIXME: should instead warn because it's unclear whether we need to release or not.
4829 } // end namespace AssertHeldTest
4832 namespace LogicalConditionalTryLock
{
4837 int a
GUARDED_BY(mu
);
4843 if (c
&& mu
.TryLock()) {
4850 bool b
= mu
.TryLock();
4858 if (c
|| !mu
.TryLock())
4865 while (c
&& mu
.TryLock()) {
4874 if (newc() || !mu
.TryLock())
4886 } while (newc() && mu
.TryLock());
4890 for (bool b
= mu
.TryLock(); c
&& b
;) {
4897 if (c
&& newc() && mu
.TryLock()) {
4904 if (!(c
&& newc() && mu
.TryLock()))
4911 if (!(c
|| !mu
.TryLock())) {
4918 } // end namespace LogicalConditionalTryLock
4922 namespace PtGuardedByTest
{
4932 // This mainly duplicates earlier tests, but just to make sure...
4933 class PtGuardedByCorrectnessTest
{
4936 int* a
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
4937 Cell
* c
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
4938 int sa
[10] GUARDED_BY(mu1
);
4939 Cell sc
[10] GUARDED_BY(mu1
);
4941 static constexpr int Cell::*pa
= &Cell::a
;
4945 if (a
== 0) doSomething(); // OK, we don't dereference.
4948 if (sa
[0] == 42) doSomething();
4950 if (sc
[0].a
== 42) doSomething();
4957 if (*a
== 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4958 *a
= 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4960 if (c
->a
== 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4961 c
->a
= 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4962 c
->*pa
= 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4964 if ((*c
).a
== 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4965 (*c
).a
= 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4966 (*c
).*pa
= 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4968 if (a
[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4969 a
[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4970 if (c
[0].a
== 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4971 c
[0].a
= 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4977 if (*a
== 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4978 *a
= 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4980 if (c
->a
== 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4981 c
->a
= 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4983 if ((*c
).a
== 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4984 (*c
).a
= 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4986 if (a
[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4987 a
[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4988 if (c
[0].a
== 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4989 c
[0].a
= 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4993 void test4() { // Literal arrays
4994 if (sa
[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4995 sa
[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4996 if (sc
[0].a
== 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4997 sc
[0].a
= 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4998 sc
[0].*pa
= 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5000 if (*sa
== 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
5001 *sa
= 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
5002 if ((*sc
).a
== 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
5003 (*sc
).a
= 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5004 if (sc
->a
== 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
5005 sc
->a
= 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
5009 mu1
.ReaderLock(); // OK -- correct use.
5011 if (*a
== 0) doSomething();
5014 if (c
->a
== 0) doSomething();
5017 if ((*c
).a
== 0) doSomething();
5025 class SmartPtr_PtGuardedBy_Test
{
5028 SmartPtr
<int> sp
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
5029 SmartPtr
<Cell
> sq
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
5031 static constexpr int Cell::*pa
= &Cell::a
;
5038 if (*sp
== 0) doSomething();
5043 if (sp
[0] == 0) doSomething();
5053 sp
.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5054 if (*sp
== 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5055 *sp
= 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5056 sq
->a
= 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5057 sq
->*pa
= 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5059 if (sp
[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5060 sp
[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
5061 if (sq
[0].a
== 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5062 sq
[0].a
= 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
5071 if (*sp
== 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5072 *sp
= 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5073 sq
->a
= 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5074 sq
->*pa
= 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5076 if (sp
[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5077 sp
[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
5078 if (sq
[0].a
== 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5079 sq
[0].a
= 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
5085 } // end namespace PtGuardedByTest
5088 namespace NonMemberCalleeICETest
{
5092 (RunHelper
)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
5095 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M
);
5099 } // end namespace NonMemberCalleeICETest
5102 namespace pt_guard_attribute_type
{
5103 int i
PT_GUARDED_BY(sls_mu
); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
5104 int j PT_GUARDED_VAR
; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
5107 int i
PT_GUARDED_BY(sls_mu
); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
5108 int j PT_GUARDED_VAR
; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
5110 typedef int PT_GUARDED_BY(sls_mu
) bad1
; // expected-warning {{'pt_guarded_by' attribute only applies to}}
5111 typedef int PT_GUARDED_VAR bad2
; // expected-warning {{'pt_guarded_var' attribute only applies to}}
5113 } // end namespace pt_guard_attribute_type
5116 namespace ThreadAttributesOnLambdas
{
5121 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_
);
5124 auto func1
= [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_
) {
5128 auto func2
= [this]() NO_THREAD_SAFETY_ANALYSIS
{
5132 auto func3
= [this]() EXCLUSIVE_LOCK_FUNCTION(mu_
) {
5136 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
5143 } // end namespace ThreadAttributesOnLambdas
5147 namespace AttributeExpressionCornerCases
{
5150 int a
GUARDED_BY(getMu());
5152 Mutex
* getMu() LOCK_RETURNED("");
5153 Mutex
* getUniv() LOCK_RETURNED("*");
5159 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
5163 void foo(Mutex
* mu
) EXCLUSIVE_LOCKS_REQUIRED(mu
);
5172 struct MuCell
{ Mutex
* mu
; };
5174 MyMap
<MyString
, Mutex
*> map
;
5175 MyMap
<MyString
, MuCell
> mapCell
;
5177 int a
GUARDED_BY(map
["foo"]);
5178 int b
GUARDED_BY(mapCell
["foo"].mu
);
5183 map
["foo"]->Unlock();
5187 mapCell
["foo"].mu
->Lock();
5189 mapCell
["foo"].mu
->Unlock();
5194 class PreciseSmartPtr
{
5196 int val
GUARDED_BY(mu
);
5198 static bool compare(PreciseSmartPtr
& a
, PreciseSmartPtr
&b
) {
5200 bool result
= (a
.val
== b
.val
); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
5201 // expected-note {{found near match 'a.mu'}}
5208 class SmartRedeclare
{
5210 int val
GUARDED_BY(mu
);
5212 void test() EXCLUSIVE_LOCKS_REQUIRED(mu
);
5213 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu
.get());
5214 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu
.get());
5218 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu
.get()) {
5222 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
5226 void SmartRedeclare::test3() {
5231 namespace CustomMutex
{
5234 class LOCKABLE BaseMutex
{ };
5235 class DerivedMutex
: public BaseMutex
{ };
5237 void customLock(const BaseMutex
*m
) EXCLUSIVE_LOCK_FUNCTION(m
);
5238 void customUnlock(const BaseMutex
*m
) UNLOCK_FUNCTION(m
);
5240 static struct DerivedMutex custMu
;
5242 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu
) { }
5245 customLock(reinterpret_cast<BaseMutex
*>(&custMu
)); // ignore casts
5246 doSomethingRequiringLock();
5247 customUnlock(reinterpret_cast<BaseMutex
*>(&custMu
));
5250 } // end namespace CustomMutex
5252 } // end AttributeExpressionCornerCases
5255 namespace ScopedLockReturnedInvalid
{
5259 Mutex
* getMutex(Opaque
* o
) LOCK_RETURNED("");
5261 void test(Opaque
* o
) {
5262 MutexLock
lock(getMutex(o
));
5265 } // end namespace ScopedLockReturnedInvalid
5268 namespace NegativeRequirements
{
5272 int a
GUARDED_BY(mu
);
5275 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
5285 int a
GUARDED_BY(mu
);
5289 mu
.Lock(); // warning? needs !mu?
5290 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
5296 bar2(); // expected-warning {{calling function 'bar2' requires negative capability '!mu'}}
5299 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
5303 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu
) {
5311 b
.baz(); // no warning -- in different class.
5315 } // end namespace NegativeRequirements
5318 namespace NegativeThreadRoles
{
5320 typedef int __attribute__((capability("role"))) ThreadRole
;
5322 void acquire(ThreadRole R
) EXCLUSIVE_LOCK_FUNCTION(R
) NO_THREAD_SAFETY_ANALYSIS
{}
5323 void release(ThreadRole R
) UNLOCK_FUNCTION(R
) NO_THREAD_SAFETY_ANALYSIS
{}
5325 ThreadRole FlightControl
, Logger
;
5327 extern void enque_log_msg(const char *msg
);
5328 void log_msg(const char *msg
) {
5332 void dispatch_log(const char *msg
) __attribute__((requires_capability(!FlightControl
))) {}
5333 void dispatch_log2(const char *msg
) __attribute__((requires_capability(Logger
))) {}
5335 void flight_control_entry(void) __attribute__((requires_capability(FlightControl
))) {
5336 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */
5337 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
5340 void spawn_fake_flight_control_thread(void) {
5341 acquire(FlightControl
);
5342 flight_control_entry();
5343 release(FlightControl
);
5346 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger
)));
5347 void logger_entry(void) __attribute__((requires_capability(Logger
)))
5348 __attribute__((requires_capability(!FlightControl
))) {
5351 while ((msg
= deque_log_msg())) {
5356 void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl
))) {
5362 int main(void) __attribute__((requires_capability(!FlightControl
))) {
5363 spawn_fake_flight_control_thread();
5364 spawn_fake_logger_thread();
5367 ; /* Pretend to dispatch things. */
5372 } // end namespace NegativeThreadRoles
5375 namespace AssertSharedExclusive
{
5381 int a
GUARDED_BY(mu
);
5383 void test() SHARED_LOCKS_REQUIRED(mu
) {
5390 } // end namespace AssertSharedExclusive
5393 namespace RangeBasedForAndReferences
{
5401 int a
GUARDED_BY(mu
);
5402 MyContainer
<int> cntr
GUARDED_BY(mu
);
5403 MyStruct s
GUARDED_BY(mu
);
5404 int arr
[10] GUARDED_BY(mu
);
5406 void nonref_test() {
5407 int b
= a
; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5408 b
= 0; // no warning
5412 auto b
= a
; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5413 b
= 0; // no warning
5414 auto &c
= a
; // no warning
5415 c
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5422 b
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5423 c
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5424 d
= 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5427 rs
.a
= 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
5429 int (&rarr
)[10] = arr
;
5430 rarr
[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
5435 *b
= 0; // no expected warning yet
5440 for (int i
: cntr
) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
5447 } // end namespace RangeBasedForAndReferences
5451 namespace PassByRefTest
{
5455 Foo() : a(0), b(0) { }
5460 void operator+(const Foo
& f
);
5462 void operator[](const Foo
& g
);
5471 // test top-level functions
5473 void write1(Foo
& f
);
5474 void write2(int a
, Foo
& f
);
5475 void read1(const Foo
& f
);
5476 void read2(int a
, const Foo
& f
);
5477 void destroy(Foo
&& f
);
5479 void operator/(const Foo
& f
, const Foo
& g
);
5480 void operator*(const Foo
& f
, const Foo
& g
);
5482 // Test constructors.
5484 FooRead(const Foo
&);
5490 // Test variadic functions
5491 template<typename
... T
>
5492 void copyVariadic(T
...) {}
5493 template<typename
... T
>
5494 void writeVariadic(T
&...) {}
5495 template<typename
... T
>
5496 void readVariadic(const T
&...) {}
5498 void copyVariadicC(int, ...);
5503 Foo foo
GUARDED_BY(mu
);
5504 Foo foo2
GUARDED_BY(mu
);
5505 Foo
* foop
PT_GUARDED_BY(mu
);
5506 SmartPtr
<Foo
> foosp
PT_GUARDED_BY(mu
);
5509 void mwrite1(Foo
& f
);
5510 void mwrite2(int a
, Foo
& f
);
5511 void mread1(const Foo
& f
);
5512 void mread2(int a
, const Foo
& f
);
5515 static void smwrite1(Foo
& f
);
5516 static void smwrite2(int a
, Foo
& f
);
5517 static void smread1(const Foo
& f
);
5518 static void smread2(int a
, const Foo
& f
);
5520 void operator<<(const Foo
& f
);
5523 copy(foo
); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5524 write1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5525 write2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5526 read1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5527 read2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5528 destroy(mymove(foo
)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5530 copyVariadic(foo
); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5531 readVariadic(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5532 writeVariadic(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5533 copyVariadicC(1, foo
); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5535 FooRead
reader(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5536 FooWrite
writer(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5538 mwrite1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5539 mwrite2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5540 mread1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5541 mread2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5543 smwrite1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5544 smwrite2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5545 smread1(foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5546 smread2(10, foo
); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5548 foo
+ foo2
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5549 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5550 foo
/ foo2
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5551 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5552 foo
* foo2
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5553 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5554 foo
[foo2
]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5555 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5556 foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5557 (*this) << foo
; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5559 copy(*foop
); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
5560 write1(*foop
); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5561 write2(10, *foop
); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5562 read1(*foop
); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5563 read2(10, *foop
); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5564 destroy(mymove(*foop
)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5566 copy(*foosp
); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5567 write1(*foosp
); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5568 write2(10, *foosp
); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5569 read1(*foosp
); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5570 read2(10, *foosp
); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5571 destroy(mymove(*foosp
)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5573 // TODO -- these require better smart pointer handling.
5575 write1(*foosp
.get());
5576 write2(10, *foosp
.get());
5577 read1(*foosp
.get());
5578 read2(10, *foosp
.get());
5579 destroy(mymove(*foosp
.get()));
5585 Foo foo
GUARDED_BY(mu
);
5586 Foo
* foo_ptr
PT_GUARDED_BY(mu
);
5588 Foo
returns_value_locked() {
5589 MutexLock
lock(&mu
);
5593 Foo
returns_value_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
5597 Foo
returns_value_releases_lock_after_return() UNLOCK_FUNCTION(mu
) {
5598 MutexLock
lock(&mu
, true);
5602 Foo
returns_value_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu
) {
5607 Foo
returns_value_not_locked() {
5608 return foo
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5611 Foo
returns_value_releases_lock_before_return() UNLOCK_FUNCTION(mu
) {
5613 return foo
; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5616 Foo
&returns_ref_not_locked() {
5617 return foo
; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}
5620 Foo
&returns_ref_locked() {
5621 MutexLock
lock(&mu
);
5622 return foo
; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}
5625 Foo
&returns_ref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu
) {
5626 return foo
; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5629 Foo
&returns_ref_exclusive_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu
) {
5633 Foo
&returns_ref_releases_lock_after_return() UNLOCK_FUNCTION(mu
) {
5634 MutexLock
lock(&mu
, true);
5635 return foo
; // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5638 Foo
& returns_ref_releases_lock_before_return() UNLOCK_FUNCTION(mu
) {
5640 return foo
; // // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}
5643 Foo
&returns_ref_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu
) {
5648 const Foo
&returns_constref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu
) {
5652 Foo
*returns_ptr() {
5653 return &foo
; // FIXME -- Do we want to warn on this ?
5656 Foo
&returns_ref2() {
5657 return *foo_ptr
; // expected-warning {{returning the value that 'foo_ptr' points to by reference requires holding mutex 'mu' exclusively}}
5663 } // end namespace PassByRefTest
5666 namespace AcquiredBeforeAfterText
{
5669 Mutex mu1
ACQUIRED_BEFORE(mu2
, mu3
);
5685 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5692 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5697 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1
) {
5702 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2
) {
5703 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5707 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2
) {
5711 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1
, mu2
, mu3
) { }
5713 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3
, mu2
, mu1
) { }
5719 Mutex mu2
ACQUIRED_AFTER(mu1
);
5720 Mutex mu3
ACQUIRED_AFTER(mu1
);
5734 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5741 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5749 Mutex mu1
ACQUIRED_BEFORE(mu2
);
5751 Mutex mu3
ACQUIRED_AFTER(mu2
) ACQUIRED_BEFORE(mu4
);
5768 mu2
.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
5776 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
5784 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5792 // Test transitive DAG traversal with AFTER
5795 Mutex mu2
ACQUIRED_AFTER(mu1
);
5796 Mutex mu3
ACQUIRED_AFTER(mu1
);
5797 Mutex mu4
ACQUIRED_AFTER(mu2
, mu3
);
5798 Mutex mu5
ACQUIRED_AFTER(mu4
);
5799 Mutex mu6
ACQUIRED_AFTER(mu4
);
5800 Mutex mu7
ACQUIRED_AFTER(mu5
, mu6
);
5801 Mutex mu8
ACQUIRED_AFTER(mu7
);
5805 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5812 // Test transitive DAG traversal with BEFORE
5814 Mutex mu1
ACQUIRED_BEFORE(mu2
, mu3
);
5815 Mutex mu2
ACQUIRED_BEFORE(mu4
);
5816 Mutex mu3
ACQUIRED_BEFORE(mu4
);
5817 Mutex mu4
ACQUIRED_BEFORE(mu5
, mu6
);
5818 Mutex mu5
ACQUIRED_BEFORE(mu7
);
5819 Mutex mu6
ACQUIRED_BEFORE(mu7
);
5820 Mutex mu7
ACQUIRED_BEFORE(mu8
);
5825 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5833 Mutex mu1
ACQUIRED_AFTER(mu3
); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}}
5834 Mutex mu2
ACQUIRED_AFTER(mu1
); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}}
5835 Mutex mu3
ACQUIRED_AFTER(mu2
); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}}
5837 Mutex mu_b
ACQUIRED_BEFORE(mu_b
); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}}
5838 Mutex mu_a
ACQUIRED_AFTER(mu_a
); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}}
5872 } // end namespace AcquiredBeforeAfterTest
5875 namespace ScopedAdoptTest
{
5879 int a
GUARDED_BY(mu
);
5882 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu
) {
5883 MutexLock
slock(&mu
, true);
5887 void test2() SHARED_UNLOCK_FUNCTION(mu
) {
5888 ReaderMutexLock
slock(&mu
, true);
5892 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu
) { // expected-note {{mutex acquired here}}
5893 MutexLock
slock(&mu
, true);
5895 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5897 void test4() SHARED_LOCKS_REQUIRED(mu
) { // expected-note {{mutex acquired here}}
5898 ReaderMutexLock
slock(&mu
, true);
5900 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5904 } // end namespace ScopedAdoptTest
5907 namespace TestReferenceNoThreadSafetyAnalysis
{
5909 #define TS_UNCHECKED_READ(x) ts_unchecked_read(x)
5911 // Takes a reference to a guarded data member, and returns an unguarded
5914 inline const T
& ts_unchecked_read(const T
& v
) NO_THREAD_SAFETY_ANALYSIS
{
5919 inline T
& ts_unchecked_read(T
& v
) NO_THREAD_SAFETY_ANALYSIS
{
5937 int a
GUARDED_BY(mu
);
5938 Foo foo
GUARDED_BY(mu
);
5946 int a
= TS_UNCHECKED_READ(bar
.a
); // nowarn
5947 TS_UNCHECKED_READ(bar
.a
) = 1; // nowarn
5949 int b
= TS_UNCHECKED_READ(bar
.foo
).a
; // nowarn
5950 TS_UNCHECKED_READ(bar
.foo
).a
= 1; // nowarn
5952 int c
= TS_UNCHECKED_READ(cbar
.a
); // nowarn
5955 #undef TS_UNCHECKED_READ
5957 } // end namespace TestReferenceNoThreadSafetyAnalysis
5960 namespace GlobalAcquiredBeforeAfterTest
{
5963 Mutex mu2
ACQUIRED_AFTER(mu1
);
5967 mu1
.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5972 } // end namespace GlobalAcquiredBeforeAfterTest
5975 namespace LifetimeExtensionText
{
5978 virtual ~Holder() throw() {}
5983 // Should not crash.
5984 const auto &value
= Holder().i
;
5987 } // end namespace LifetimeExtensionTest
5990 namespace LockableUnions
{
5992 union LOCKABLE MutexUnion
{
5996 void Lock() EXCLUSIVE_LOCK_FUNCTION();
5997 void Unlock() UNLOCK_FUNCTION();
6001 MutexUnion muun1
ACQUIRED_BEFORE(muun2
);
6005 muun1
.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
6010 } // end namespace LockableUnions
6012 // This used to crash.
6013 class acquired_before_empty_str
{
6014 void WaitUntilSpaceAvailable() {
6015 lock_
.ReaderLock(); // expected-note {{acquired here}}
6016 } // expected-warning {{mutex 'lock_' is still held at the end of function}}
6017 Mutex lock_
ACQUIRED_BEFORE("");
6022 operator int() const;
6025 bool g() __attribute__((locks_excluded(h
))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
6032 void f() { c
[A()]->g(); }
6033 } // namespace PR34800
6035 #ifdef __cpp_guaranteed_copy_elision
6037 namespace ReturnScopedLockable
{
6041 MutexLock
lock() EXCLUSIVE_LOCK_FUNCTION(mutex
) {
6042 // TODO: False positive because scoped lock isn't destructed.
6043 return MutexLock(&mutex
); // expected-note {{mutex acquired here}}
6044 } // expected-warning {{mutex 'mutex' is still held at the end of function}}
6046 ReaderMutexLock
lockShared() SHARED_LOCK_FUNCTION(mutex
) {
6047 // TODO: False positive because scoped lock isn't destructed.
6048 return ReaderMutexLock(&mutex
); // expected-note {{mutex acquired here}}
6049 } // expected-warning {{mutex 'mutex' is still held at the end of function}}
6051 MutexLock
adopt() EXCLUSIVE_LOCKS_REQUIRED(mutex
) {
6052 // TODO: False positive because scoped lock isn't destructed.
6053 return MutexLock(&mutex
, true); // expected-note {{mutex acquired here}}
6054 } // expected-warning {{mutex 'mutex' is still held at the end of function}}
6056 ReaderMutexLock
adoptShared() SHARED_LOCKS_REQUIRED(mutex
) {
6057 // TODO: False positive because scoped lock isn't destructed.
6058 return ReaderMutexLock(&mutex
, true); // expected-note {{mutex acquired here}}
6059 } // expected-warning {{mutex 'mutex' is still held at the end of function}}
6061 int x
GUARDED_BY(mutex
);
6062 void needsLock() EXCLUSIVE_LOCKS_REQUIRED(mutex
);
6065 MutexLock scope
= lock();
6076 MutexLock scope
= obj
.lock();
6081 int testSharedLock() {
6082 ReaderMutexLock scope
= obj
.lockShared();
6083 obj
.x
= 1; // expected-warning {{writing variable 'x' requires holding mutex 'obj.mutex' exclusively}}
6089 MutexLock scope
= obj
.adopt();
6093 int testAdoptShared() {
6095 ReaderMutexLock scope
= obj
.adoptShared();
6100 } // namespace ReturnScopedLockable
6106 // Self-referencing assignment previously caused an infinite loop when thread
6107 // safety analysis was enabled.
6108 int &i
= i
; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}}
6112 namespace Derived_Smart_Pointer
{
6114 class SmartPtr_Derived
: public SmartPtr
<T
> {};
6118 SmartPtr_Derived
<Mutex
> mu_
;
6119 int a
GUARDED_BY(mu_
);
6120 int b
GUARDED_BY(mu_
.get());
6121 int c
GUARDED_BY(*mu_
);
6123 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_
);
6124 void Unlock() UNLOCK_FUNCTION(mu_
);
6127 a
= 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
6128 b
= 1; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
6129 c
= 1; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
6142 SmartPtr_Derived
<Foo
> foo
;
6145 foo
->a
= 1; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
6146 (*foo
).b
= 1; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
6147 foo
.get()->c
= 1; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
6159 MutexLock
lock(foo
->mu_
.get());
6164 class PointerGuard
{
6167 SmartPtr_Derived
<int> i
GUARDED_BY(mu1
) PT_GUARDED_BY(mu2
);
6170 i
.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6171 *i
= 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \
6172 // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
6180 *i
= 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
6188 i
.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
6189 *i
= 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}