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 operator !() const15 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 test1()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 test2()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 test3()38 void test3() { // expected-note {{Thread warning in function 'test3'}} 39 foo1(); // expected-warning {{calling function 'foo1' requires holding mutex 'mu' exclusively}} 40 } 41 test4()42 void test4() { // expected-note {{Thread warning in function 'test4'}} 43 foo2(); // expected-warning {{calling function 'foo2' requires holding mutex 'mu'}} 44 } 45 test5()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 test6()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 test7()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