1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wthread-safety-verbose -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 -Wthread-safety-verbose -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s |
3 | |
4 | #include "thread-safety-annotations.h" |
5 | |
6 | class LOCKABLE Mutex { |
7 | public: |
8 | void Lock() EXCLUSIVE_LOCK_FUNCTION(); |
9 | void ReaderLock() SHARED_LOCK_FUNCTION(); |
10 | void Unlock() UNLOCK_FUNCTION(); |
11 | bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); |
12 | bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); |
13 | |
14 | // for negative capabilities |
15 | const Mutex& operator!() const { return *this; } |
16 | |
17 | void AssertHeld() ASSERT_EXCLUSIVE_LOCK(); |
18 | void AssertReaderHeld() ASSERT_SHARED_LOCK(); |
19 | }; |
20 | |
21 | |
22 | class Test { |
23 | Mutex mu; |
24 | int a GUARDED_BY(mu); // expected-note3 {{Guarded_by declared here.}} |
25 | |
26 | void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu); |
27 | void foo2() SHARED_LOCKS_REQUIRED(mu); |
28 | void foo3() LOCKS_EXCLUDED(mu); |
29 | |
30 | void test1() { // expected-note {{Thread warning in function 'test1'}} |
31 | a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} |
32 | } |
33 | |
34 | void test2() { // expected-note {{Thread warning in function 'test2'}} |
35 | int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}} |
36 | } |
37 | |
38 | void test3() { // expected-note {{Thread warning in function 'test3'}} |
39 | foo1(); // expected-warning {{calling function 'foo1' requires holding mutex 'mu' exclusively}} |
40 | } |
41 | |
42 | void test4() { // expected-note {{Thread warning in function 'test4'}} |
43 | foo2(); // expected-warning {{calling function 'foo2' requires holding mutex 'mu'}} |
44 | } |
45 | |
46 | void test5() { // expected-note {{Thread warning in function 'test5'}} |
47 | mu.ReaderLock(); |
48 | foo1(); // expected-warning {{calling function 'foo1' requires holding mutex 'mu' exclusively}} |
49 | mu.Unlock(); |
50 | } |
51 | |
52 | void test6() { // expected-note {{Thread warning in function 'test6'}} |
53 | mu.ReaderLock(); |
54 | a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} |
55 | mu.Unlock(); |
56 | } |
57 | |
58 | void test7() { // expected-note {{Thread warning in function 'test7'}} |
59 | mu.Lock(); |
60 | foo3(); // expected-warning {{cannot call function 'foo3' while mutex 'mu' is held}} |
61 | mu.Unlock(); |
62 | } |
63 | }; |
64 | |
65 | |