| 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 | |