1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wthread-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-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s 3 4 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s 5 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s 6 7 #include "thread-safety-annotations.h" 8 9 class LOCKABLE Mutex { 10 public: 11 void Lock() EXCLUSIVE_LOCK_FUNCTION(); 12 void ReaderLock() SHARED_LOCK_FUNCTION(); 13 void Unlock() UNLOCK_FUNCTION(); 14 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); 15 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); 16 17 // for negative capabilities operator !() const18 const Mutex& operator!() const { return *this; } 19 20 void AssertHeld() ASSERT_EXCLUSIVE_LOCK(); 21 void AssertReaderHeld() ASSERT_SHARED_LOCK(); 22 }; 23 24 25 namespace SimpleTest { 26 27 class Bar { 28 Mutex mu; 29 int a GUARDED_BY(mu); 30 31 public: baz()32 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 33 mu.Lock(); 34 a = 0; 35 mu.Unlock(); 36 } 37 }; 38 39 40 class Foo { 41 Mutex mu; 42 int a GUARDED_BY(mu); 43 44 public: foo()45 void foo() { 46 mu.Lock(); // expected-warning {{acquiring mutex 'mu' requires negative capability '!mu'}} 47 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}} 48 bar(); 49 mu.Unlock(); 50 } 51 bar()52 void bar() { 53 baz(); // expected-warning {{calling function 'baz' requires holding '!mu'}} 54 } 55 baz()56 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 57 mu.Lock(); 58 a = 0; 59 mu.Unlock(); 60 } 61 test()62 void test() { 63 Bar b; 64 b.baz(); // no warning -- in different class. 65 } 66 test2()67 void test2() { 68 mu.Lock(); // expected-warning {{acquiring mutex 'mu' requires negative capability '!mu'}} 69 a = 0; 70 mu.Unlock(); 71 baz(); // no warning -- !mu in set. 72 } 73 test3()74 void test3() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 75 mu.Lock(); 76 a = 0; 77 mu.Unlock(); 78 baz(); // no warning -- !mu in set. 79 } 80 }; 81 82 } // end namespace SimpleTest 83 84 namespace DoubleAttribute { 85 86 struct Foo { 87 Mutex &mutex(); 88 }; 89 90 template <typename A> 91 class TemplateClass { 92 template <typename B> Function(Foo * F)93 static void Function(Foo *F) 94 EXCLUSIVE_LOCKS_REQUIRED(F->mutex()) UNLOCK_FUNCTION(F->mutex()) {} 95 }; 96 test()97void test() { TemplateClass<int> TC; } 98 99 } // end namespace DoubleAttribute 100