1176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions %s
213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
53ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
60e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define LOCKABLE             __attribute__((lockable))
70e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define SCOPED_LOCKABLE      __attribute__((scoped_lockable))
80e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define GUARDED_BY(x)        __attribute__((guarded_by(x)))
90e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define GUARDED_VAR          __attribute__((guarded_var))
100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define PT_GUARDED_BY(x)     __attribute__((pt_guarded_by(x)))
110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define PT_GUARDED_VAR       __attribute__((pt_guarded_var))
120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define ACQUIRED_AFTER(...)  __attribute__((acquired_after(__VA_ARGS__)))
130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define EXCLUSIVE_LOCK_FUNCTION(...)    __attribute__((exclusive_lock_function(__VA_ARGS__)))
150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define SHARED_LOCK_FUNCTION(...)       __attribute__((shared_lock_function(__VA_ARGS__)))
160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define ASSERT_EXCLUSIVE_LOCK(...)      __attribute__((assert_exclusive_lock(__VA_ARGS__)))
170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define ASSERT_SHARED_LOCK(...)         __attribute__((assert_shared_lock(__VA_ARGS__)))
180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define SHARED_TRYLOCK_FUNCTION(...)    __attribute__((shared_trylock_function(__VA_ARGS__)))
200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define UNLOCK_FUNCTION(...)            __attribute__((unlock_function(__VA_ARGS__)))
210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define EXCLUSIVE_UNLOCK_FUNCTION(...)  __attribute__((release_capability(__VA_ARGS__)))
220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define SHARED_UNLOCK_FUNCTION(...)     __attribute__((release_shared_capability(__VA_ARGS__)))
230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define LOCK_RETURNED(x)                __attribute__((lock_returned(x)))
240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define LOCKS_EXCLUDED(...)             __attribute__((locks_excluded(__VA_ARGS__)))
250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define EXCLUSIVE_LOCKS_REQUIRED(...)   __attribute__((exclusive_locks_required(__VA_ARGS__)))
260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define SHARED_LOCKS_REQUIRED(...)      __attribute__((shared_locks_required(__VA_ARGS__)))
270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#define NO_THREAD_SAFETY_ANALYSIS       __attribute__((no_thread_safety_analysis))
280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
300e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass LOCKABLE Mutex {
313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski public:
323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Lock() __attribute__((exclusive_lock_function));
333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void ReaderLock() __attribute__((shared_lock_function));
343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Unlock() __attribute__((unlock_function));
353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool TryLock() __attribute__((exclusive_trylock_function(true)));
363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
385c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // for negative capabilities
40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const Mutex& operator!() const { return *this; }
41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
425c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();
435c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void AssertReaderHeld() ASSERT_SHARED_LOCK();
443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
460e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass SCOPED_LOCKABLE MutexLock {
471fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu);
500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ~MutexLock() UNLOCK_FUNCTION();
511fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
521fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
530e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass SCOPED_LOCKABLE ReaderMutexLock {
541fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu);
560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu);
570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ~ReaderMutexLock() UNLOCK_FUNCTION();
581fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
591fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
60c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass SCOPED_LOCKABLE ReleasableMutexLock {
61c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins public:
62c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
63c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ~ReleasableMutexLock() UNLOCK_FUNCTION();
64c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
65c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void Release() UNLOCK_FUNCTION();
66c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass __attribute__((scoped_lockable)) DoubleMutexLock {
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  DoubleMutexLock(Mutex *mu1, Mutex *mu2)
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      __attribute__((exclusive_lock_function(mu1, mu2)));
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ~DoubleMutexLock() __attribute__((unlock_function));
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
749d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
750b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// The universal lock, written "*", allows checking to be selectively turned
760b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// off for a particular piece of code.
770b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnReads()  SHARED_LOCK_FUNCTION("*");
780b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnReads()    UNLOCK_FUNCTION("*");
790b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
800b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnWrites()   UNLOCK_FUNCTION("*");
810b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
820b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
83d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing handling of smart pointers.
849d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinstemplate<class T>
859d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass SmartPtr {
869d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinspublic:
879d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(T* p) : ptr_(p) { }
889d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
899d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  ~SmartPtr();
909d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
919d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* get()        const { return ptr_; }
929d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* operator->() const { return ptr_; }
9396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  T& operator*()  const { return *ptr_; }
94f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  T& operator[](int i) const { return ptr_[i]; }
959d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
969d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsprivate:
979d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* ptr_;
989d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
999d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
1009d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
101d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing destructor calls and cleanup.
102d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsclass MyString {
103d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinspublic:
104d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  MyString(const char* s);
105d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  ~MyString();
106d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins};
107d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
108d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// For testing operator overloading
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <class K, class T>
111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass MyMap {
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T& operator[](const K& k);
114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// For testing handling of containers.
118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <class T>
119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass MyContainer {
120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MyContainer();
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  typedef T* iterator;
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  typedef const T* const_iterator;
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T* begin();
127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T* end();
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const T* cbegin();
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const T* cend();
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T&       operator[](int i);
133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const T& operator[](int i) const;
134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesprivate:
136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T* ptr_;
137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
140d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
152194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
1537336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins   void MyLock() __attribute__((exclusive_lock_function(mu)));
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
1573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
1593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
1607336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  sls_mw.x = 5;
1613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
1833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
2023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
2103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
2183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
2343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
2383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
2393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
246194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
247194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
248194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
249194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
250194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
2513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
2523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
2543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
2573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
2603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
2642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
2663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
2683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2690da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // expected-note{{mutex acquired here}}
2703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2710da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu2.Lock(); // expected-note{{mutex acquired here}}
272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
2762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2832e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    expected-warning{{releasing mutex 'sls_mu' that was not held}}
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
297aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2984e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
3022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
3053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
3062e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
3083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
3093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
3122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
3132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
3140da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  do {
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
3210da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // \
322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
3232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
3290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
3310da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock();
3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
3362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
3382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
3423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
344aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
3452e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
346aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
347aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
348aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
349aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
351aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
352aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
353aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
354aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
355aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
356aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
357aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
3583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
3593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
3613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
3633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
3653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
3663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
3673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
3683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
3693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
3713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
3733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
3783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'aa_mu' that was not held}}
3803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
3833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
3863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
392b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
393b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
394b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
395b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
396b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
397b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
398b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
399b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
400b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
4012f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
402b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
4032f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
405b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
4062f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
408b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
4092e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
411b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
4122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
413b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
415b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
416b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
44205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
44305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
44605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
44805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
449af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
450af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
451af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
452af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
45305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
45405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45505b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
45605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
45805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
45905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
46005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
46105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
46405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
46505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
46605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
46705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
47005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
47105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
47205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
47505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
47605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
47905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
48105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
48205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
48305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
48405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
48605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
48705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
48805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
48905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
49105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
49205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
49305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
49405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
49605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
49705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
49805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
49905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
50105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
50205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
50305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
50405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
50605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
50705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
50805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
50905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
51105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
51205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
51305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
51405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
51605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
51705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
51805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
51905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
52005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
521651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
52205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
52305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
52405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
52505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
52705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
52905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
531a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
53305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
534b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
535eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
536eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
537eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
538eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
539eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
540eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
541eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
542eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
543eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
544eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
545eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
546eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
547eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
549eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
551eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
553eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
554eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
555eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
556eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
557eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
558eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
559eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
56099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
56199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
56299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
56399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
56499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
56599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
56699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
56799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
56899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
56999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
57099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
57199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57299107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
57399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
57599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
57699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
57799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
57899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
57999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
58099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
58299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
58399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
58499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
58599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
58699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
58799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
58999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
59099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
59199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
59299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
59399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
5953f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'fooA.mu'}}
59699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
59799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
59899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
59999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
60099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
60199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
60299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
60399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
60499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
60699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
60799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
60899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
60999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
61099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
61199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
61299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
61399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
61499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
6163f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.FooPointer->mu'}}
61799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
61899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
61999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
62099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
62199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
62299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
62399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
6253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
62699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
62799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
62899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
62999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
63099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
63199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
63299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
6343f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
63599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
63699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
63799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
638a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
639a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
640a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
641a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
642a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
643a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
644a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
645a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
646a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
647a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
648a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
649a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
650a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
651a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
6524e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
654a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
655a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6564e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
658a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
659a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
660a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
661a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
662a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
663a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
664a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
665a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
666a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
667a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
668a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
669a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
670a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
671a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
672a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
673a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
674a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
675a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
676a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
677a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
678a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
679a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
680a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
681a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
682a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
684a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
685a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
687a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
688a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
689a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
690a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6914e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
693a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
694a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6954e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
697a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
698a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
699a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
700a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
701a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
702a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
703a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
705a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
706a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
708a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
709a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
710a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
711a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
712a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
713a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
714a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
716a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
717a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
719a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
720a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
721a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
734978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
735978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
739978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
740978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
741978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
742978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
743978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
744978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
745978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
746978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
747978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
748978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
749978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
750978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
751978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
752978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
753978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
754978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
755978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
756978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
757978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
758978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
759978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
760978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
761978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
762978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
763978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
764978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
765978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
766978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
767978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
768978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
769978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
770978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
771978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
772978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
773978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
774978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
775978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
776978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
777978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
778978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
779978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
780978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
781978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
782978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
783978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
784978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
785978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
786978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
787978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
788978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
789af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
790af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
791af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
792af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
793af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
794af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
795cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
796cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
797cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
798cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
799cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
800cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
801cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
802cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
803cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
804cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
805978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
806978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
808978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
809978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
810978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
811978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
812978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
814978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
815978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
816978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
817978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
818978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
820978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
821978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
822978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
823978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
825978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
826978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
827978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
828978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
829651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
830978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
831978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
832978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
833978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
834978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
836978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
837978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
838978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
839978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
840978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
841978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
843978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
844978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
845978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
846978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
847978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
848978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
849651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
850978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
851978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
852194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8538121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
854194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
855194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
856194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
857194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
859194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
113223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
113723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1245e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 5;
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1259e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie    g = 2;
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1261988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1262988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
1268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
1274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1277e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 2;
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1291988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1292988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1293988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1295988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1296988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
13023f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b2->a_ = 3; // \
1303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
13043f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b1->mu1_'}}
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
1333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
13353f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
1336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
13403f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
1341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
1343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
13653f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->bar(7); // \
1366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
13673f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
13683f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->a_ = 5; // \
1369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
13703f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1404988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
1407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1436988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1438988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1443988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1444988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1445988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
1446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1448988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1449988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1450988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1451988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1452988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1453988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1454988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1457988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1458988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1459988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1460988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1461988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1462988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1463988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1464988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1465988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1466988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1467988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1468988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1469988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1470988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1471988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1472988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1473988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1474988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1475988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1476988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1477988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1478988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1480988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1482988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1483988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1485988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1487988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1488988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1489988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1490988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1491988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1492988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1493988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1494988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1495988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1496988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1497988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1498988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1499988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1500988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1501988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1502988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1503988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1504988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1505988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1506988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1507988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1508988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1509988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1510988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1511988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1512988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1517988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1518988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1519988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1520988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
15218121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
15228121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
15238121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
15248121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
15258121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15265696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)));
15275696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)));
15288121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15298121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
15308121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15318121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15328121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15338121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
15348121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
15355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
15365696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
15378121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15388121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15398121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15408121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
15418121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
15428121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
15438121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15448121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
15458121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
15468121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15478121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
15488121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15498121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15508121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
15518121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15528121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
15538121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15548121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
15558121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15568121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15578121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
15588121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15592e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
15608121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
1561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
15638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
15658121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15668121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
15678121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
1568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
15693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-note {{found near match 'd1->mu'}}
15708121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
15718121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15728121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
15748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1575e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1576f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1577e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1578e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1579e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1580e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1581e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1582e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1583e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1584e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1585e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1586e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1587e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15886db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1589e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1590e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1591e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1592e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1593f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
159497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1595f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
159697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
159797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
159897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
159997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
160097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1601a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1602a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1603a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1604a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1605a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1606a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
160797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
160897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
160997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
161097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1612651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
161397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
161497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
161597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1616f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
161797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1618601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1619601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1620601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1621601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1622601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1623601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1624601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1625601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1626601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1627601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1629601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1630601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1631601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1632601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
163397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
16341fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16351fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
16361fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16371fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
16381fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
16391fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
16401fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
16411fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
16421fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16431fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
16441fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16451fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
16461fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
16471fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
16481fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16491fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16501fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
16511fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
16521fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
16531fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
16541fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
16551fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16561fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
16571fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
16581fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
16591fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16601fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16611fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16621fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16631fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16641fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
1665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{acquiring mutex 'mu1' that is already held}}
1666c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
16671fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16681fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16691fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16701fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16711fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16721fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
1673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1674176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void foo5() {
1675176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    DoubleMutexLock mulock(&mu1, &mu2);
1676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = b + 1;
1677176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b = a + 1;
1678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
16791fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16801fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16811fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16821fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16831fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1684df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1685df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1686df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1687df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1688df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1689df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1690df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1691df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1692df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1693df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1694df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1695df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1696df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo();  // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1698df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1699df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1700df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1701df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1702df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1703df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1704df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1705df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
170660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchinsnamespace TryLockTest {
170760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1737b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1738b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1739b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1740b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1741b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1742b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1743b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1744b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1745b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1746b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1747b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1748b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1749b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1750b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1751b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1752b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1753b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1754b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1755b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1756b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1757b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1758b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1759b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1760b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1761b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1762b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1763b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1764b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1765b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1766b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1767b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1768b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1769b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1770b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1771b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
177243e3deeabf3ca02da427b63df8604e2daf86e8a3Sylvestre Ledru    if (b) {    // b should be unknown at this point, because of the join point
1773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      a = 8;    // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1774b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1775b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1776b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1777b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1778b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1779b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1780b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1781b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1782b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1783b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1784b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1785b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1786b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1787b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1788b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1789b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1790b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1791b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1792b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1793b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1794b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1795b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1796b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1797b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1798b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1799651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        a = 10;  // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1800b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1801b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1802b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1803b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
180460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
180560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of exclusive trylock
180660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo11() {
180760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
180860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.TryLock())
180960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
181060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
181160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
181260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.Lock();
181360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
181460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   a = 10;
181560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
181660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
181760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
181860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of shared trylock
181960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo12() {
182060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
182160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.ReaderTryLock())
182260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
182360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
182460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
182560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.ReaderLock();
182660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
182760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   int i = a;
182860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
182960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
1830b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1831b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
183260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins} // end namespace TrylockTest
183360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1834b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
18417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
18447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
18467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
18517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
18537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
18557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
18567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
18597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
18617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
18687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
18707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
18717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
18737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
18747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
18757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
18787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
18797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
18847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
18857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
18927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
18957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
18967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
189723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
19007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
19027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
19037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
19047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
19057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
19067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
19077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
19097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
19107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
19117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
19127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
19137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
19157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
19167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
19177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
19187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
19207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
19217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
19227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
19237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
19247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
19267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
1927651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
19283f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bt.fooBase.mu_'}}
19297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
19317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
19327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
19337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
19357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
1936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
19377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
193823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
193923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
194023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
194123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
194223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
194323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
194423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
194523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
194623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
194723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
194823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1949dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
195023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
195123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
195223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
195323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
195423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
195523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
195623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
195723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
195823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
19597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
196023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
196123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
196223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
196323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
196423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
196523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
196623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1967dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
196823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
196923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
197023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
197123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
197223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
197323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
197423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
197523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
197623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
197723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
197823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
197923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
198023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
198123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
19827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
19837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
19857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1987e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1988e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1989e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1990e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1991e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1992e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1993e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1994e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1995e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1996e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1997e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1998e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1999e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
2000e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
2001e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
2002e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
2003e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
2004e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
2005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2006e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
2007e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
2008e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
2009e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
2010e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
2011e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
20122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
20132e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
20142e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
20152e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
20162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
20172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
20182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
20192e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
20202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
20212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
20222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
20232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
20242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
20252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
20262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
20272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
20282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
20292e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
20302e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
2031651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
20322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
20332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
20342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
20352e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
20362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
20372e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
20382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
20392e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
20402e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2052c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
2054c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2055c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2056c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2057c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2058c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2059c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
2060c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2061c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2063c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
2064c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2065c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
2066c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2067c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2068c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
2069c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2070c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2071c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2072c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2073c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
2074c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2075c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2076c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2077c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
2078c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2079c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2080c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2081c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
2082c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2083c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2084c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2085c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2086c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
2087c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2088c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2089c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
2090c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2091c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
2092c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
2093c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2094c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
2095c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2096c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2097c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
2098c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2099c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2100c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2101c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2102c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2103c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2104c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2105c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2106c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2107c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2108c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2109c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2110c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2111c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2112c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2113c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2114c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2115c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2116c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2117c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2118c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2119c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2121c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2123c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
2125c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2126a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);  // \
2127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
2128c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2129c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2131c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2133c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2135c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2136c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2137c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2138c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2139c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2140c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2141a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);
2142c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2143c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2144c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2145c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2146c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2147c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2148c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2149c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2151c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2152c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21534bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
21544bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21554bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21564bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
21574bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21584bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
21594bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
21604bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
21614bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21624bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
21634bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
21644bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21654bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
21664bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
21674bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
21684bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
21694bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
21704bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
21714bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21724bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
21734bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
21744bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
21754bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21764bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
21774bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
2178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
21794bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2180c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2181c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21822f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21832f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
21842f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
21852f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
21862f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
21872f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21882f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
21892f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
21902f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
21912f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21922f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
21932f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
21942f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
21952f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
21962f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21972f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21984bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21994bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
22004bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2201d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2202d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2203d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2204d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2205d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2206d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2207d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2208d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2209d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2210d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2211d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2212d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2213d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2214d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
22152a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
22162a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
22172a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
22182a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
22192a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
22202a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
22212a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
22222a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
22232a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
22242a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
22252a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
22262a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
22272a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
22282a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
22292a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
22302a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
22312287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
22322287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22332287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22342287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
22352287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22362287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
22372287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
22382287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
22392287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
22402287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22412287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
22422287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
2243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
22442287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
2245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
22462287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
2247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
22482287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
22492287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22502287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
22512287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
22522a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
22532287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22542287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
22552287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22567ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22577ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
22587ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22597ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
22607ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
22617ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
22627ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
22637ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
22647ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
22657ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22667ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
22677ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22687ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
22710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
22730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22740d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
22750d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
22760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
22790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22800d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22810d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
22820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
22840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
22850d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
22860d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22870d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
22880d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22890d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22900d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
22910d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22920d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
22930d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
22940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
22950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
22960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
22970d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22980d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
22990d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
23010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
23020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
23030d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23040d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
23050d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
23060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
23070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
23090d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
23100d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
23110d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23120d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
23130d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
23140d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
23150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23160d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
23170d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
23180d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
23190d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23200d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
23210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
23220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
23230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
23250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
23260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
23270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
23290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
23300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2331176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2332176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2333176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2334176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid test2() {
2335176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Foo *fooArray;
2336176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Bar bar;
2337176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a;
2338176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int b;
2339176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int c;
23400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
23420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
2343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
23443f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo().mu_'}}
23450d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
23460d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23470d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
23480d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
2349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
23503f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
23510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
23520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
23540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
2355176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \
2356176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}
23570d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
23580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
23600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
2361176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \
2362176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}
23630d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
23640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
23660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2367176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \
2368176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}
23690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
23700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
23710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23730da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace MoreLockExpressions
23740da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23750da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23760da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsnamespace TrylockJoinPoint {
23770da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23780da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsclass Foo {
23790da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  Mutex mu;
23800da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  bool c;
23810da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23820da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  void foo() {
23830da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    if (c) {
23840da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      if (!mu.TryLock())
23850da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins        return;
23860da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    } else {
23870da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      mu.Lock();
23880da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    }
23890da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    mu.Unlock();
23900da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  }
23910da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins};
23920da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23930da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace TrylockJoinPoint
23940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2396f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsnamespace LockReturned {
2397f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2398f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Foo {
2399f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2400f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int a             GUARDED_BY(mu_);
2401f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);
2402f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2403f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2404f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2405f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2406f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex* getMu() LOCK_RETURNED(mu_);
2407f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2408f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex mu_;
2409f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2410f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2411f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2412f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2413f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2414f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Calls getMu() directly to lock and unlock
2415f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test1(Foo* f1, Foo* f2) {
2416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->a = 0;       // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->foo();       // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2418f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2422f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2423f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Lock();
2424f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2425f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->a = 0;
2426f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo();
24273f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  f1->foo2(f2); // \
2428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
24293f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'f1->mu_'}}
2430f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2431f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Lock();
2432f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo2(f2);
2433f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Unlock();
2434f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2435f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::sfoo(f1);
2436f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2437f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Unlock();
2438f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2439f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2440f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2441f63797c741e646b9482d204c88dee02fb41d7962DeLesley HutchinsMutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2442f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2443f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Bar : public Foo {
2444f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2445f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int  b            GUARDED_BY(getMu());
2446f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());
2447f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2448f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2449f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2450f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2451f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2452f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2453f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2454f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2455f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Use getMu() within other attributes.
2456f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// This requires at lest levels of substitution, more in the case of
2457f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test2(Bar* b1, Bar* b2) {
2458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->bar();       // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2464f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2465f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Lock();
2466f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2467f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2468f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
24693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b1->bar2(b2);  // \
2470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
24713f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // // expected-note {{found near match 'b1->mu_'}}
2472f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2473f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Lock();
2474f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2475f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2476f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Unlock();
2477f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2478f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2479f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2480f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2481f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Unlock();
2482f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2483f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2484f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2485f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Sanity check -- lock the mutex directly, but use attributes that call getMu()
2486f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Also lock the mutex using getFooMu, which calls a lock_returned function.
2487f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test3(Bar* b1, Bar* b2) {
2488f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Lock();
2489f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2490f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
2491f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2492f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Lock();
2493f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2494f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Unlock();
2495f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2496f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2497f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2498f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2499f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Unlock();
2500f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2501f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2502f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins} // end namespace LockReturned
2503f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2504f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2505c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsnamespace ReleasableScopedLock {
2506c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2507c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass Foo {
2508c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  Mutex mu_;
2509c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  bool c;
2510c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  int a GUARDED_BY(mu_);
2511c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2512c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test1();
2513c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test2();
2514c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test3();
25155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test4();
25165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test5();
2517c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
2518c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2519c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2520c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test1() {
2521c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2522c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2523c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2524c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2525c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test2() {
2526c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2527c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  if (c) {            // test join point -- held/not held during release
2528c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins    rlock.Release();
2529c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
2530c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2531c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2532c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test3() {
2533c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2534c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 0;
2535c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 1;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2537c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2538c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
25395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test4() {
25405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
25415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();
2542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
25435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test5() {
25465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
25475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  if (c) {
25485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    rlock.Release();
25495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  }
25505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  // no warning on join point for managed lock.
2551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
25525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2555c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins} // end namespace ReleasableScopedLock
2556c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2557c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
255876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsnamespace TrylockFunctionTest {
255976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
256076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsclass Foo {
256176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinspublic:
256276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu1_;
256376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu2_;
256476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool c;
256576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
256676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
256776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins};
256876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
256976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsbool Foo::lockBoth() {
257076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!mu1_.TryLock())
257176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
257276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
257376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  mu2_.Lock();
257476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!c) {
257576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu1_.Unlock();
257676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu2_.Unlock();
257776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
257876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  }
257976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
258076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  return true;
258176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}
258276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
258376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
258476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}  // end namespace TrylockFunctionTest
2585c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2586c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2587c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2588c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsnamespace DoubleLockBug {
2589c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2590c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsclass Foo {
2591c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinspublic:
2592c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  Mutex mu_;
2593c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  int a GUARDED_BY(mu_);
2594c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
25965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int  foo2() SHARED_LOCKS_REQUIRED(mu_);
2597c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins};
2598c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2599c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
26005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2601c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  a = 0;
2602c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins}
2603c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
26045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
26055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return a;
26065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
26075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
26095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2610c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2611c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2612879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsnamespace UnlockBug {
2613c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2614879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsclass Foo {
2615879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinspublic:
2616879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  Mutex mutex_;
2617879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2618879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
2619879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2621879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2622879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2623879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
2624879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2626879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins};
2627879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2628879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins} // end namespace UnlockBug
2629c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2630c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
26315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2632bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsnamespace FoolishScopedLockableBug {
2633bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2634bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass SCOPED_LOCKABLE WTF_ScopedLockable {
2635bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinspublic:
2636bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2637bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2638bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  // have to call release() manually;
2639bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  ~WTF_ScopedLockable();
2640bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2641bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void release() UNLOCK_FUNCTION();
2642bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2643bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2644bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2645bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass Foo {
2646bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  Mutex mu_;
2647bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  int a GUARDED_BY(mu_);
2648bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  bool c;
2649bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2650bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void doSomething();
2651bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2652bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test1() {
2653bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);
2654bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    wtf.release();
2655bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2656bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2657bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test2() {
2658bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
2660bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2661bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test3() {
2662bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2663bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2664bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2665bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2666bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2667bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2668bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test4() {
2669bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2670bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2671bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2672bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2673bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2674bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2675bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2676bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2677bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2678bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test5() {
2679bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2680bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2681bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2683bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2684bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test6() {
2685bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2686bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2687bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2688bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2689bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2690bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2692bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2693bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2694bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2695bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins} // end namespace FoolishScopedLockableBug
2696bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
26979d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26999d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsnamespace TemporaryCleanupExpr {
27009d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27019d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass Foo {
27029d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  int a GUARDED_BY(getMutexPtr().get());
27039d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27049d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr<Mutex> getMutexPtr();
27059d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27069d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  void test();
27079d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
27089d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27099d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27109d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsvoid Foo::test() {
27119d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  {
27129d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    ReaderMutexLock lock(getMutexPtr().get());
27139d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    int b = a;
271496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
2715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int b = a;  // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
27169d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins}
27179d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27189d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins} // end namespace TemporaryCleanupExpr
27199d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
27209d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
272196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsnamespace SmartPointerTests {
272396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Foo {
272596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinspublic:
272696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Mutex> mu_;
272796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int a GUARDED_BY(mu_);
272896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int b GUARDED_BY(mu_.get());
272996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int c GUARDED_BY(*mu_);
273096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);
273296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Unlock() UNLOCK_FUNCTION(mu_);
273396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
273596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
273696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
273796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
273896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test4();
273996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test5();
274096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test6();
274196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test7();
274296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test8();
274396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
274496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test0() {
2746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b = 0;  // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c = 0;  // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
274996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
275096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
275196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test1() {
275296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
275396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
275496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
275596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
275696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Unlock();
275796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
275896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
275996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test2() {
276096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();
276196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
276296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
276396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
276496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Unlock();
276596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
276696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test3() {
276996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();
277096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
277196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
277296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
277396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
277496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test4() {
277896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(mu_.get());
277996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
278096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
278196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
278296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
278396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test5() {
278696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(&(*mu_));
278796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
278896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
278996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
279096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
279196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test6() {
279496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Lock();
279596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
279696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
279796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
279896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();
279996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
280096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test7() {
280396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
280496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Lock();
280596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
280696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
280796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
280896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
280996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Unlock();
281096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
281196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
281296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
281396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
281496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
281596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
281696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
281796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Unlock();
281896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
281996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
282096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
282196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Unlock();
282296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
282396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
282496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Lock();
282596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
282696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
282796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
282896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
283096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test8() {
283196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
2832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  mu_.get()->Lock();    // expected-warning {{acquiring mutex 'mu_' that is already held}}
2833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (*mu_).Lock();        // expected-warning {{acquiring mutex 'mu_' that is already held}}
283496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
2835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Unlock();             // expected-warning {{releasing mutex 'mu_' that was not held}}
283696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
283796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
283896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
283996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Bar {
284096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Foo> foo;
284196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
284296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
284396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
284496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
284596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
284696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
284796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
284896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
284996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test0() {
2850651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo->a = 0;         // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
2851651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
2852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
285396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
285496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
285596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
285696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test1() {
285796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Lock();
285896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
285996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
286096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
286196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Unlock();
286296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
286396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
286496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
286596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test2() {
286696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).mu_->Lock();
286796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
286896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
286996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
287096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->mu_->Unlock();
287196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
287296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
287396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
287496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test3() {
287596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(foo->mu_.get());
287696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
287796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
287896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
287996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
288096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
288196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}  // end namespace SmartPointerTests
288296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
288396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
288496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
28855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsnamespace DuplicateAttributeTest {
28865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsclass LOCKABLE Foo {
28885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinspublic:
28895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu1_;
28905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu2_;
28915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu3_;
28925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int a GUARDED_BY(mu1_);
28935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int b GUARDED_BY(mu2_);
28945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int c GUARDED_BY(mu3_);
28955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
28975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
28985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);
29005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void slock1() SHARED_LOCK_FUNCTION(mu1_);
29015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
29025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void locklots()
29035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_)
29045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_)
29055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
29065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock1() UNLOCK_FUNCTION(mu1_);
29085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
29095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlocklots()
29105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_)
29115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_)
29125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
29135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins};
29145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }
29175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock() UNLOCK_FUNCTION()         { }
29185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {
29205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
29215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
29245696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  mu1_.ReaderLock();
29255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
29285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
29295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
29305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
29315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::locklots()
29345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
29355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
29365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
29375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
29385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
29395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
29425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
29435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
29465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
29475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
29485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
29495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlocklots()
29525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_)
29535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_, mu3_) {
29545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
29555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
29565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
29575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test0() {
29615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
2966651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.lock();     // expected-warning {{acquiring mutex 'foo' that is already held}}
29675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
2968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock();   // expected-warning {{releasing mutex 'foo' that was not held}}
29695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test1() {
29735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
29755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
2979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.lock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
29805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2982651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock1();  // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
29835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint test2() {
29875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
29895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d1 = foo.a;
29905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
2993651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.slock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
29945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d2 = foo.a;
29955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2996651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock1();   // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
29975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return d1 + d2;
29985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test3() {
30025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
30035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
30045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
30055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
30065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
30075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
30085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
30105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3(); // \
3011651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3012651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3013651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
30145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
30155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
30165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
30175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
30185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3(); // \
3019651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3021651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
30225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
30235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30245381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid testlots() {
30265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
30275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
30285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
30295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
30305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
30315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
30325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
30345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots(); // \
3035651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3036651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3037651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
30385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
30395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
30405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
30415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
30425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots(); // \
3043651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3045651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
30465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
30475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}  // end namespace DuplicateAttributeTest
30495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
30515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
305213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsnamespace TryLockEqTest {
305313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsclass Foo {
305513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex mu_;
305613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int a GUARDED_BY(mu_);
305713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  bool c;
305813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
306013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
306113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_);
306213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test1();
306413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test2();
306513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins};
306613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test1() {
306913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == 0) {
3070651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
307113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
307213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
307313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
307413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
307513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() != 0) {
307713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
307813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
307913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
308013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
308113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 != tryLockMutexP()) {
308213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
308313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
308413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
308513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
308613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(tryLockMutexP() == 0)) {
308713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
308813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
308913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
309013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
309113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 0) {
3092651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
309313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
309413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
309513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
309613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
309713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
309813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 == tryLockMutexI()) {
3099651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
310013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
310113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
310213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
310313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
310413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
310513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 1) {
310613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
310713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
310813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
310913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
311013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == false) {
3111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
311213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
311313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
311413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
311513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
311613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
311713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == true) {
311813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
311913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
312013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
312113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else {
3122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
312313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
312413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
312513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#if __has_feature(cxx_nullptr)
312613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == nullptr) {
3127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
312813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
312913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
313013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
313113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
313213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#endif
313313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
313413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
313513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins} // end namespace TryLockEqTest
31365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
313796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
3138ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsnamespace ExistentialPatternMatching {
3139ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3140ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Graph {
3141ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3142ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Mutex mu_;
3143ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3144ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3145ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3146ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3147ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3148ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Node {
3149ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3150ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  int a GUARDED_BY(&Graph::mu_);
3151ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3152ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3153ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins    a = 0;
3154ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  }
3155ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3156ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3157ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3158ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid test() {
3159ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g1;
3160ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g2;
3161ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Node n1;
3162ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.a = 0;   // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo();   // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3165ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();
3166ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3167ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();
3168ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3169ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3171ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3172ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3173ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Lock();
3174ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3175ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3177ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3178ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3179ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3180ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3181ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3183ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  UnlockAllGraphs();
3184ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3185ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3186ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3187ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3188ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3189ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3190ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3191ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  g1.mu_.Lock();  // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3193ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3194ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins}
3195ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3196ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins} // end namespace ExistentialPatternMatching
3197ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
31984e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31994e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsnamespace StringIgnoreTest {
32004e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32014e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Foo {
32024e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
32034e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  Mutex mu_;
32044e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION("");
32054e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION("");
32064e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void goober() EXCLUSIVE_LOCKS_REQUIRED("");
32074e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void roober() SHARED_LOCKS_REQUIRED("");
32084e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
32094e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32104e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32114e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Bar : public Foo {
32124e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
32134e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void bar(Foo* f) {
32144e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->unlock();
32154e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->goober();
32164e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->roober();
32174e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->lock();
32184e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  };
32194e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
32204e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32214e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins} // end namespace StringIgnoreTest
32224e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32234e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
32245408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsnamespace LockReturnedScopeFix {
32255408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32265408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsclass Base {
32275408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsprotected:
32285408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  struct Inner;
32295408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  bool c;
32305408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32315408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  const Mutex& getLock(const Inner* i);
32325408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32335408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
32345408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
32355408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
32365408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32375408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void bar(Inner* i);
32385408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
32395408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32405408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32415408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsstruct Base::Inner {
32425408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  Mutex lock_;
32435408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
32445408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
32455408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32465408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32475408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsconst Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
32485408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  return i->lock_;
32495408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32505408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32515408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32525408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::foo(Inner* i) {
32535408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  i->doSomething();
32545408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32555408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32565408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::bar(Inner* i) {
32575408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  if (c) {
32585408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Lock();
32595408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    unlockInner(i);
32605408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32615408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  else {
32625408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    lockInner(i);
32635408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Unlock();
32645408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32655408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32665408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32675408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins} // end namespace LockReturnedScopeFix
32685408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
3269fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3270fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsnamespace TrylockWithCleanups {
3271fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3272fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstruct Foo {
3273fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Mutex mu_;
3274fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a GUARDED_BY(mu_);
3275fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3276fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3277fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley HutchinsFoo* GetAndLockFoo(const MyString& s)
3278fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3279fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3280fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstatic void test() {
3281fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Foo* lt = GetAndLockFoo("foo");
3282fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  if (!lt) return;
3283fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a = lt->a;
3284fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  lt->mu_.Unlock();
3285fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3286fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
328724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TrylockWithCleanups
3288fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3289fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
32900b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsnamespace UniversalLock {
32910b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32920b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsclass Foo {
32930b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  Mutex mu_;
32940b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  bool c;
32950b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32960b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  int a        GUARDED_BY(mu_);
32970b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void r_foo() SHARED_LOCKS_REQUIRED(mu_);
32980b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
32990b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33000b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test1() {
33010b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    int b;
33020b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33030b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnReads();
33040b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    b = a;
33050b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    r_foo();
33060b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnReads();
33070b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33080b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33090b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
33100b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    w_foo();
33110b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33120b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33130b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33140b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // don't warn on joins with universal lock
33150b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test2() {
33160b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
33170b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
33180b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
33190b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0; // \
3320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
33210b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();  // \
3322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{releasing mutex '*' that was not held}}
33230b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33240b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33250b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33260b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // make sure the universal lock joins properly
33270b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test3() {
33280b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
33290b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
33300b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
33310b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
33320b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    else {
33330b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
33340b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
33350b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
33360b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
33370b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33380b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33390b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33400b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33410b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33420b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // combine universal lock with other locks
33430b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test4() {
33440b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33450b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33460b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33470b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33480b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33490b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33500b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33510b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33520b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33530b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33540b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33550b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33560b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33570b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33580b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33590b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins};
33600b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
336124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace UniversalLock
336224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
336324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
336424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsnamespace TemplateLockReturned {
336524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
336624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinstemplate<class T>
336724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass BaseT {
336824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
336924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  virtual void baseMethod() = 0;
337024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
337124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
337224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex mutex_;
337324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  int a GUARDED_BY(mutex_);
337424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
337524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
337624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
337724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass Derived : public BaseT<int> {
337824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
337924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
338024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins    a = 0;
338124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  }
338224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
338324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
338424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TemplateLockReturned
338524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
338624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
3387f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsnamespace ExprMatchingBugFix {
3388f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3389f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Foo {
3390f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3391f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Mutex mu_;
3392f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3393f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3394f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3395f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Bar {
3396f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3397f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  bool c;
3398f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Foo* foo;
3399f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Bar(Foo* f) : foo(f) { }
3400f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3401f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  struct Nested {
3402f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Foo* foo;
3403f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested(Foo* f) : foo(f) { }
3404f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3405f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3406f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  };
3407f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3408f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  void test();
3409f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3410f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3411f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3412f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsvoid Bar::test() {
3413f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  foo->mu_.Lock();
3414f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  if (c) {
3415f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested *n = new Nested(foo);
3416f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    n->unlockFoo();
3417f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3418f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  else {
3419f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    foo->mu_.Unlock();
3420f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3421f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}
3422f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3423f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}; // end namespace ExprMatchingBugfix
3424f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3425f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
34265b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsnamespace ComplexNameTest {
3427f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
34285b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Foo {
34295b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
34305b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
34315b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34325b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_)  { }
34335b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
34345b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34355b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
34365b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
34375b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34385b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Bar {
34395b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
34405b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
34415b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34425b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar()  LOCKS_EXCLUDED(mu_) { }
34435b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Bar() LOCKS_EXCLUDED(mu_) { }
34445b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34455b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
34465b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
34475b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34485b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34495b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test1() {
3450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Foo f;           // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
3451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int a = f[0];    // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
3452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}                  // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
34535b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34545b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34555b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test2() {
34565b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Lock();
34575b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  {
3458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
3459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
3460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
34615b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Unlock();
34625b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}
34635b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34645b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};  // end namespace ComplexNameTest
34652a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34662a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34672a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsnamespace UnreachableExitTest {
34682a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34692a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsclass FemmeFatale {
34702a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinspublic:
34712a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale();
34722a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  ~FemmeFatale() __attribute__((noreturn));
34732a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins};
34742a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34752a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid exitNow() __attribute__((noreturn));
3476d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid exitDestruct(const MyString& ms) __attribute__((noreturn));
34772a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34782a237e03c407ff55bd8639b18658a8751955f1dbDeLesley HutchinsMutex fatalmu_;
34792a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34802a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34812a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  exitNow();
34822a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34832a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34842a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34852a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale femme;
34862a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34872a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34882a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsbool c;
34892a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34902a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34912a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  if (c) {
34922a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    exitNow();
34932a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34942a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  else {
34952a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    FemmeFatale femme;
34962a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34972a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34982a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
3499d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3500d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  exitDestruct("foo");
3501d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins}
3502d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
35032a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}   // end namespace UnreachableExitTest
3504186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3505186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3506186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsnamespace VirtualMethodCanonicalizationTest {
3507186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3508186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base {
3509186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3510186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  virtual Mutex* getMutex() = 0;
3511186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3512186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3513186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base2 : public Base {
3514186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3515186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3516186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3517186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3518186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base3 : public Base2 {
3519186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3520186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3521186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3522186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3523186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Derived : public Base3 {
3524186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3525186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();  // overrides Base::getMutex()
3526186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3527186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3528186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3529186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3530186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3531186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  baseFun(d);
3532186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}
3533186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3534186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}  // end namespace VirtualMethodCanonicalizationTest
3535186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3536d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3537d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsnamespace TemplateFunctionParamRemapTest {
3538d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3539d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate <class T>
3540d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsstruct Cell {
3541d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  T dummy_;
3542d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Mutex* mu_;
3543d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3544d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3545d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass Foo {
3546d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3547d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  template <class T>
3548d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3549d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3550d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void test();
3551d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3552d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3553d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3554d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::elr(Cell<T>* c1) { }
3555d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3556d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::test() {
3557d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3558d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  elr(&cell); // \
3559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3560d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3561d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3562d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3563d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3564d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3565d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3566d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3567d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c1) { }
3568d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3569d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest() {
3570d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3571d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR(&cell); // \
3572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
3573d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3574d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3575d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3576d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3577d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3578d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3579d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// second declaration
3580d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3581d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c2);
3582d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3583d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3584d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c3) { }
3585d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3586d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// re-declaration after definition
3587d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3588d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c4);
3589d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3590d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest2() {
3591d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3592d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR2(&cell); // \
3593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
3594d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3595d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3596d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3597d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3598d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass FooT {
3599d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3600d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3601d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3602d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3603d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3604d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid FooT<T>::elr(Cell<T>* c1) { }
3605d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3606d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid testFooT() {
3607d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3608d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  FooT<int> foo;
3609d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  foo.elr(&cell); // \
3610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3611d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3612d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3613d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}  // end namespace TemplateFunctionParamRemapTest
3614d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3615ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3616ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsnamespace SelfConstructorTest {
3617ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3618ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass SelfLock {
3619ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3620ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock()  EXCLUSIVE_LOCK_FUNCTION(mu_);
3621ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock() UNLOCK_FUNCTION(mu_);
3622ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3623ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3624ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3625ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  Mutex mu_;
3626ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3627ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3628ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass LOCKABLE SelfLock2 {
3629ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3630ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2()  EXCLUSIVE_LOCK_FUNCTION();
3631ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock2() UNLOCK_FUNCTION();
3632ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3633ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3634ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3635ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3636ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3637ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test() {
3638ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock s;
3639ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s.foo();
3640ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3641ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3642ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test2() {
3643ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2 s2;
3644ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s2.foo();
3645ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3646ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3647ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}  // end namespace SelfConstructorTest
3648ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
36493ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36503ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsnamespace MultipleAttributeTest {
36513ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36523ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsclass Foo {
36533ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu1_;
36543ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu2_;
36553ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  a GUARDED_BY(mu1_);
36563ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  b GUARDED_BY(mu2_);
36573ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  c GUARDED_BY(mu1_)    GUARDED_BY(mu2_);
36583ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
36593ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36603ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo1()          EXCLUSIVE_LOCKS_REQUIRED(mu1_)
36613ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCKS_REQUIRED(mu2_);
36623ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo2()          SHARED_LOCKS_REQUIRED(mu1_)
36633ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_LOCKS_REQUIRED(mu2_);
36643ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo3()          LOCKS_EXCLUDED(mu1_)
36653ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       LOCKS_EXCLUDED(mu2_);
36663ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void lock()          EXCLUSIVE_LOCK_FUNCTION(mu1_)
36673ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCK_FUNCTION(mu2_);
36685696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerlock()    SHARED_LOCK_FUNCTION(mu1_)
36695696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins                       SHARED_LOCK_FUNCTION(mu2_);
36703ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void unlock()        UNLOCK_FUNCTION(mu1_)
36713ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       UNLOCK_FUNCTION(mu2_);
36723ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool trylock()       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
36733ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
36743ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
36753ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_TRYLOCK_FUNCTION(true, mu2_);
3676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
3677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    ASSERT_EXCLUSIVE_LOCK(mu2_);
3678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void assertShared() ASSERT_SHARED_LOCK(mu1_)
3679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      ASSERT_SHARED_LOCK(mu2_);
36803ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36813ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void test();
3682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void testAssert();
3683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void testAssertShared();
36843ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins};
36853ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36863ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36873ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo1() {
36883ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 1;
36893ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 2;
36903ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36913ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36923ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo2() {
36933ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int result = a + b;
36943ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36953ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36963ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo3() { }
36975696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::lock() { mu1_.Lock();  mu2_.Lock(); }
36985696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::readerlock() { mu1_.ReaderLock();  mu2_.ReaderLock(); }
36995696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::unlock() { mu1_.Unlock();  mu2_.Unlock(); }
37003ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::trylock()       { return true; }
37013ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::readertrylock() { return true; }
37023ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37033ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37043ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::test() {
37053ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Lock();
37063ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo1();             // expected-warning {{}}
37073ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  c = 0;              // expected-warning {{}}
37083ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  *d = 0;             // expected-warning {{}}
37093ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
37103ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37113ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.ReaderLock();
37123ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo2();             // expected-warning {{}}
37133ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int x = c;          // expected-warning {{}}
37143ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int y = *d;         // expected-warning {{}}
37153ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
37163ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37173ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Lock();
37183ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo3();             // expected-warning {{}}
37193ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Unlock();
37203ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37213ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  lock();
37223ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 0;
37233ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 0;
37243ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
37253ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37263ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  readerlock();
37273ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int z = a + b;
37283ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
37293ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37303ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (trylock()) {
37313ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    a = 0;
37323ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    b = 0;
37333ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
37343ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
37353ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37363ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (readertrylock()) {
37373ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    int zz = a + b;
37383ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
37393ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
37403ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
37413ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
3742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Force duplication of attributes
3743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::assertBoth() { }
3744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::assertShared() { }
3745651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::testAssert() {
3747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assertBoth();
3748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 0;
3749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b = 0;
3750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::testAssertShared() {
3753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assertShared();
3754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int zz = a + b;
3755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
37573ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37583ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}  // end namespace MultipleAttributeTest
37593ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37603ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
376191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsnamespace GuardedNonPrimitiveTypeTest {
376291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Data {
376591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
376691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data(int i) : dat(i) { }
376791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  getValue() const { return dat; }
376991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void setValue(int i)  { dat = i; }
377091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  operator[](int i) const { return dat; }
377291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int& operator[](int i)       { return dat; }
377391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void operator()() { }
377591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
377791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int dat;
377891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
377991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass DataCell {
378291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
378391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  DataCell(const Data& d) : dat(d) { }
378491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
378691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data dat;
378791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
378891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsvoid showDataCell(const DataCell& dc);
379191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Foo {
379491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
379591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // method call tests
379691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test() {
379791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(0);         // FIXME -- should be writing \
3798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
379991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_.getValue();  // \
3800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
380191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);      // FIXME -- should be writing \
3803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
380491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();   // \
3805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
380691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(0);      // FIXME -- should be writing \
3808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
380991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();   // \
3810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
381191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_).setValue(0);    // FIXME -- should be writing \
3813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
381491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = (*datap2_).getValue(); // \
3815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
381691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Lock();
381891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(1);
381991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(1);
382091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(1);
382191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
382291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
382391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.ReaderLock();
382491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = data_.getValue();
382591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);  // reads datap1_, writes *datap1_
382691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();
382791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();
382891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
382991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
383091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
383191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // operator tests
383291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test2() {
3833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
3834651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
3835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
3837651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3838651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3839651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
3840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3841651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_();              // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
384791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
384891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
384991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // const operator tests
385091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test3() const {
3851651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
385291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
385391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //FIXME
3854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
385691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
3857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int a = data_[0];       // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
385891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
385991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
386091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
386191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Mutex mu_;
386291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data  data_   GUARDED_BY(mu_);
386391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap1_ GUARDED_BY(mu_);
386491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap2_ PT_GUARDED_BY(mu_);
386591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
386691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
386791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins}  // end namespace GuardedNonPrimitiveTypeTest
386891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
386993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsnamespace GuardedNonPrimitive_MemberAccess {
387193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Cell {
387393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
387493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell(int i);
387593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void cellMethod();
387793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int a;
387993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
388093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
388193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
388293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Foo {
388393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
388493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int   a;
388593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell  c  GUARDED_BY(cell_mu_);
388693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell* cp PT_GUARDED_BY(cell_mu_);
388793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
388893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void myMethod();
388993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
389093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex cell_mu_;
389193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
389293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
389393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
389493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Bar {
389593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsprivate:
389693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex mu_;
389793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo  foo  GUARDED_BY(mu_);
389893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo* foop PT_GUARDED_BY(mu_);
389993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
390093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void test() {
3901651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.myMethod();      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
390293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3903651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
3904651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
390593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3906651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3907651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
390893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3909651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3910651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
391193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3912651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
3913651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
3914651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
3915651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
391693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3917651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3918651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3919651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3920651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
392193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3922651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
392693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  };
392793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
392893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
392993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins}  // namespace GuardedNonPrimitive_MemberAccess
393093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
39310ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39320ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsnamespace TestThrowExpr {
39330ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39340ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsclass Foo {
39350ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  Mutex mu_;
39360ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39370ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  bool hasError();
39380ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39390ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  void test() {
39400ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Lock();
39410ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    if (hasError()) {
39420ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins      throw "ugly";
39430ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    }
39440ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Unlock();
39450ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  }
39460ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins};
39470ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39480ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins}  // end namespace TestThrowExpr
39490ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39500ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
3951ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsnamespace UnevaluatedContextTest {
3952ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3953ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins// parse attribute expressions in an unevaluated context.
3954ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3955ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex1();
3956ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex2();
3957ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3958ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3959ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3960ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3961ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3962ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins}  // end namespace UnevaluatedContextTest
3963ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
39645696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39655696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsnamespace LockUnlockFunctionTest {
39665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39675696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins// Check built-in lock functions
39685696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass LOCKABLE MyLockable  {
39695696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39705696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock()       EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
39715696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION()    { mu_.ReaderLock(); }
39725696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock()     UNLOCK_FUNCTION()         { mu_.Unlock(); }
39735696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39745696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39755696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39765696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39775696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39785696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39795696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass Foo {
39805696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39815696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Correct lock/unlock functions
39825696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
39835696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Lock();
39845696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39855696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39865696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION(mu_) {
39875696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.ReaderLock();
39885696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39895696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39905696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_) {
39915696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Unlock();
39925696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39935696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39945696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check failure to lock.
39955696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}
39965696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39975696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
3998651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
39995696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40005696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
40015696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
40025696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
4003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
40045696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40055696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
40065696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
40075696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
4008651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
40095696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40105696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check locking the wrong thing.
40115696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
40125696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();            // expected-note {{mutex acquired here}}
4013651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4014651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
40155696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40165696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40175696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
40185696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.ReaderLock();      // expected-note {{mutex acquired here}}
4019651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
40215696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40225696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40235696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
4024651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mu2_.Unlock();  // expected-warning {{releasing mutex 'mu2_' that was not held}}
4025651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
40265696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40275696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
40285696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
40295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu2_;
40305696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
40315696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins}  // end namespace LockUnlockFunctionTest
40335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
40345c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40355c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsnamespace AssertHeldTest {
40365c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40375c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsclass Foo {
40385c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinspublic:
40395c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int c;
40405c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int a GUARDED_BY(mu_);
40415c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  Mutex mu_;
40425c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40435c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test1() {
40445c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40455c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40465c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40475c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40485c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40495c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test2() {
40505c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertReaderHeld();
40515c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
4052651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
40535c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40545c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40555c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test3() {
40565c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40575c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40585c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40595c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40605c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40615c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40625c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40635c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40645c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40655c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40665c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
40675c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40685c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40695c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40705c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40715c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40725c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test5() UNLOCK_FUNCTION(mu_) {
40735c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40745c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40755c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40765c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40775c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test6() {
40785c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40795c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40805c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }  // should this be a warning?
40815c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40825c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test7() {
40835c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40845c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40855c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40865c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40875c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40885c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40895c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40905c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40915c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40925c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40935c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40945c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test8() {
40955c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40965c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40975c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40985c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40995c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
41005c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
41015c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
41025c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
41035c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
41045c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
41055c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41065c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test9() {
41075c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
41085c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
41095c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
41105c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
41115c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
41125c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
4113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
41145c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41155c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test10() {
41165c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
41175c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
41185c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
41195c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
41205c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
41215c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
4122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
41235c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41245c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
41255c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41265c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test11() {
41275c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    assertMu();
41285c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
41295c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
41305c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
41315c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins};
41325c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41335c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins}  // end namespace AssertHeldTest
41345c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41355c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
41367336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsnamespace LogicalConditionalTryLock {
41377336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41387336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsclass Foo {
41397336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinspublic:
41407336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  Mutex mu;
41417336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  int a GUARDED_BY(mu);
41427336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool c;
41437336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41447336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool newc();
41457336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41467336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test1() {
41477336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && mu.TryLock()) {
41487336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41497336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41507336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41517336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41527336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41537336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test2() {
41547336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    bool b = mu.TryLock();
41557336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && b) {
41567336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41577336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41587336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41597336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41607336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41617336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test3() {
41627336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c || !mu.TryLock())
41637336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
41647336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
41657336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
41667336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41677336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41687336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test4() {
41697336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c && mu.TryLock()) {
41707336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41717336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      c = newc();
41727336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41737336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41747336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41757336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41767336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test5() {
41777336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c) {
41787336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      if (newc() || !mu.TryLock())
41797336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins        break;
41807336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41817336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41827336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41837336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41847336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41857336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test6() {
41867336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Lock();
41877336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    do {
41887336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41897336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41907336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    } while (newc() && mu.TryLock());
41917336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41927336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41937336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test7() {
41947336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    for (bool b = mu.TryLock(); c && b;) {
41957336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41967336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41977336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41987336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41997336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
42007336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test8() {
42017336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && newc() && mu.TryLock()) {
42027336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
42037336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
42047336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
42057336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
42067336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
42077336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test9() {
42087336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (!(c && newc() && mu.TryLock()))
42097336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
42107336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
42117336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
42127336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
42136b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins
42146b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins  void test10() {
42156b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins    if (!(c || !mu.TryLock())) {
42166b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins      a = 0;
42176b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins      mu.Unlock();
42186b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins    }
42196b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins  }
42207336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins};
42217336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
42227336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins}  // end namespace LogicalConditionalTryLock
42237336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
422443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
422543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
422643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsnamespace PtGuardedByTest {
422743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
422843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsvoid doSomething();
422943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
423043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass Cell {
423143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  public:
423243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  int a;
423343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
423443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
423543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
423643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins// This mainly duplicates earlier tests, but just to make sure...
423743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass PtGuardedBySanityTest {
4238f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Mutex  mu1;
4239f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Mutex  mu2;
4240f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  int*   a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4241f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Cell*  c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4242f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  int    sa[10] GUARDED_BY(mu1);
4243f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Cell   sc[10] GUARDED_BY(mu1);
424443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
424543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test1() {
424643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Lock();
424743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (a == 0) doSomething();  // OK, we don't dereference.
424843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    a = 0;
424943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    c = 0;
4250f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sa[0] == 42) doSomething();
4251f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sa[0] = 57;
4252f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sc[0].a == 42) doSomething();
4253f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sc[0].a = 57;
425443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
425543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
425643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
425743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test2() {
425843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.ReaderLock();
4259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*a == 0) doSomething();      // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *a = 0;                          // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
426143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c->a == 0) doSomething();    // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c->a = 0;                        // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
426443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*c).a == 0) doSomething();  // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*c).a = 0;                      // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4267f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (a[0] == 42) doSomething();     // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a[0] = 57;                         // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c[0].a == 42) doSomething();   // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c[0].a = 57;                       // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
427243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
427343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
427443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
427543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test3() {
427643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Lock();
4277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*a == 0) doSomething();      // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *a = 0;                          // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
427943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c->a == 0) doSomething();    // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c->a = 0;                        // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
428243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*c).a == 0) doSomething();  // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*c).a = 0;                      // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4285f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (a[0] == 42) doSomething();     // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a[0] = 57;                         // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c[0].a == 42) doSomething();   // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c[0].a = 57;                       // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
429043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Unlock();
429143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
429243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4293f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  void test4() {  // Literal arrays
4294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sa[0] == 42) doSomething();     // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sa[0] = 57;                         // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sc[0].a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sc[0].a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sa == 42) doSomething();       // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sa = 57;                           // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*sc).a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*sc).a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sc->a == 42) doSomething();     // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sc->a = 57;                         // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4305f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  }
4306f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4307f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  void test5() {
430843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.ReaderLock();    // OK -- correct use.
430943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Lock();
431043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (*a == 0) doSomething();
431143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    *a = 0;
431243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
431343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (c->a == 0) doSomething();
431443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    c->a = 0;
431543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
431643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if ((*c).a == 0) doSomething();
431743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    (*c).a = 0;
431843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Unlock();
431943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
432043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
432143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
432243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
432343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
432443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass SmartPtr_PtGuardedBy_Test {
43259a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  Mutex mu1;
432643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  Mutex mu2;
43279a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  SmartPtr<int>  sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
43289a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
432943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
43309a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test1() {
43319a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.ReaderLock();
43329a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Lock();
43339a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43349a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sp.get();
43359a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    if (*sp == 0) doSomething();
43369a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    *sp = 0;
43379a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sq->a = 0;
43389a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
4339f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sp[0] == 0) doSomething();
4340f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sp[0] = 0;
4341f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
43429a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Unlock();
43439a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Unlock();
43449a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  }
43459a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43469a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test2() {
43479a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Lock();
43489a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
4349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp.get();                      // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sp == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sp = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq->a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4353f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sp[0] == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp[0] = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq[0].a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
43589a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43599a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Unlock();
43609a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  }
43619a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43629a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test3() {
43639a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Lock();
43649a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43659a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sp.get();
4366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sp == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sp = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq->a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4369f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sp[0] == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp[0] = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq[0].a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
43749a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43759a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Unlock();
437643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
437743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
437843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
437943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins}  // end namespace PtGuardedByTest
438043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
43814444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43824444446abb50f7b0314d82be0afa892f945cc9bcBill Wendlingnamespace NonMemberCalleeICETest {
43834444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43844444446abb50f7b0314d82be0afa892f945cc9bcBill Wendlingclass A {
43854444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling  void Run() {
4386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (RunHelper)();  // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
43874444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling }
43884444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43894444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling void RunHelper() __attribute__((exclusive_locks_required(M)));
43904444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling Mutex M;
43914444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling};
43924444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43934444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling}  // end namespace NonMemberCalleeICETest
43944444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
4395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace pt_guard_attribute_type {
4397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
4398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
4399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void test() {
4401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
4407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace pt_guard_attribute_type
4408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace ThreadAttributesOnLambdas {
4411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass Foo {
4413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Mutex mu_;
4414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void test() {
4418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      LockedFunction();
4420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
4423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      LockedFunction();
4424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      mu_.Lock();
4428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func1();  // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
4431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func2();
4432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func3();
4433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mu_.Unlock();
4434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
4435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
4436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace ThreadAttributesOnLambdas
4438176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4439176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4441176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace AttributeExpressionCornerCases {
4442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4443176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Foo {
4444176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(getMu());
4445176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4446176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex* getMu()   LOCK_RETURNED("");
4447176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex* getUniv() LOCK_RETURNED("*");
4448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test1() {
4450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = 0;
4451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
4454176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = 0;
4455176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4456176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4457176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);
4458176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4459176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test3() {
4460176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo(nullptr);
4461176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4462176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4463176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4464176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4465176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass MapTest {
4466176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct MuCell { Mutex* mu; };
4467176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4468176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MyMap<MyString, Mutex*> map;
4469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MyMap<MyString, MuCell> mapCell;
4470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(map["foo"]);
4472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int b GUARDED_BY(mapCell["foo"].mu);
4473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test() {
4475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    map["foo"]->Lock();
4476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = 0;
4477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    map["foo"]->Unlock();
4478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4479176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test2() {
4481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mapCell["foo"].mu->Lock();
4482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b = 0;
4483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mapCell["foo"].mu->Unlock();
4484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4488176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass PreciseSmartPtr {
4489176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SmartPtr<Mutex> mu;
4490176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int val GUARDED_BY(mu);
4491176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4492176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {
4493176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a.mu->Lock();
4494176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    bool result = (a.val == b.val);   // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
4495176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                      // expected-note {{found near match 'a.mu'}}
4496176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a.mu->Unlock();
4497176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return result;
4498176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4499176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4500176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4501176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4502176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass SmartRedeclare {
4503176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SmartPtr<Mutex> mu;
4504176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int val GUARDED_BY(mu);
4505176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4506176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test()  EXCLUSIVE_LOCKS_REQUIRED(mu);
4507176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4508176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4509176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4510176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4511176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4512176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {
4513176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  val = 0;
4514176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4515176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4516176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {
4517176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  val = 0;
4518176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4519176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4520176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid SmartRedeclare::test3() {
4521176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  val = 0;
4522176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4523176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4524176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4525176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace CustomMutex {
4526176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4527176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4528176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass LOCKABLE BaseMutex { };
4529176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass DerivedMutex : public BaseMutex { };
4530176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4531176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid customLock(const BaseMutex *m)   EXCLUSIVE_LOCK_FUNCTION(m);
4532176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);
4533176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4534176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic struct DerivedMutex custMu;
4535176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4536176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }
4537176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4538176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid customTest() {
4539176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  customLock(reinterpret_cast<BaseMutex*>(&custMu));  // ignore casts
4540176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  doSomethingRequiringLock();
4541176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  customUnlock(reinterpret_cast<BaseMutex*>(&custMu));
4542176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4543176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4544176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end namespace CustomMutex
4545176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4546176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end AttributeExpressionCornerCases
4547176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4548176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4549176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace ScopedLockReturnedInvalid {
4550176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4551176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Opaque;
4552176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4553176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesMutex* getMutex(Opaque* o) LOCK_RETURNED("");
4554176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4555176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid test(Opaque* o) {
4556176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MutexLock lock(getMutex(o));
4557176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4559176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}  // end namespace ScopedLockReturnedInvalid
4560176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4561176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4562176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace NegativeRequirements {
4563176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4564176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Bar {
4565176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex mu;
4566176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(mu);
4567176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4568176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
4569176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4570176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Lock();
4571176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = 0;
4572176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Unlock();
4573176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4574176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4575176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4576176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4577176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Foo {
4578176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex mu;
4579176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(mu);
4580176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4581176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
4582176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void foo() {
4583176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Lock();    // warning?  needs !mu?
4584176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    baz();        // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
4585176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    bar();
4586176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Unlock();
4587176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4588176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4589176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void bar() {
4590176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    bar2();       // expected-warning {{calling function 'bar2' requires holding  '!mu'}}
4591176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4592176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4593176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4594176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    baz();
4595176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4596176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4597176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4598176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Lock();
4599176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    a = 0;
4600176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.Unlock();
4601176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4602176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4603176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test() {
4604176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Bar b;
4605176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b.baz();     // no warning -- in different class.
4606176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4607176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4608176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4609176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}   // end namespace NegativeRequirements
4610176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4611176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4612176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace NegativeThreadRoles {
4613176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef int __attribute__((capability("role"))) ThreadRole;
4615176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4616176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid acquire(ThreadRole R) __attribute__((exclusive_lock_function(R))) __attribute__((no_thread_safety_analysis)) {}
4617176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid release(ThreadRole R) __attribute__((unlock_function(R))) __attribute__((no_thread_safety_analysis)) {}
4618176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4619176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesThreadRole FlightControl, Logger;
4620176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4621176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesextern void enque_log_msg(const char *msg);
4622176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid log_msg(const char *msg) {
4623176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  enque_log_msg(msg);
4624176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4625176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4626176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}
4627176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}
4628176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4629176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {
4630176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */
4631176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
4632176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4633176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4634176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid spawn_fake_flight_control_thread(void) {
4635176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  acquire(FlightControl);
4636176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  flight_control_entry();
4637176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  release(FlightControl);
4638176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4639176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4640176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesextern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
4641176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid logger_entry(void) __attribute__((requires_capability(Logger))) {
4642176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const char *msg;
4643176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4644176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  while ((msg = deque_log_msg())) {
4645176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    dispatch_log(msg);
4646176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4647176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4648176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4649176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid spawn_fake_logger_thread(void) {
4650176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  acquire(Logger);
4651176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  logger_entry();
4652176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  release(Logger);
4653176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4654176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4655176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint main(void) {
4656176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  spawn_fake_flight_control_thread();
4657176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  spawn_fake_logger_thread();
4658176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4659176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (;;)
4660176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ; /* Pretend to dispatch things. */
4661176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4662176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return 0;
4663176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
4664176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4665176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end namespace NegativeThreadRoles
4666176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4667176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4668176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace AssertSharedExclusive {
4669176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4670176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid doSomething();
4671176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4672176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Foo {
4673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex mu;
4674176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(mu);
4675176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test() SHARED_LOCKS_REQUIRED(mu) {
4677176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mu.AssertHeld();
4678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (a > 0)
4679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      doSomething();
4680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4683176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end namespace AssertSharedExclusive
4684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4685176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace RangeBasedForAndReferences {
4687176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4688176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Foo {
4689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct MyStruct {
4690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int a;
4691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  };
4692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex mu;
4694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a GUARDED_BY(mu);
4695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MyContainer<int>  cntr  GUARDED_BY(mu);
4696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MyStruct s GUARDED_BY(mu);
4697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int arr[10] GUARDED_BY(mu);
4698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void nonref_test() {
4700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int b = a;             // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
4701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b = 0;                 // no warning
4702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4703176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void auto_test() {
4705176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto b = a;            // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
4706176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b = 0;                 // no warning
4707176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto &c = a;           // no warning
4708176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    c = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4709176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void ref_test() {
4712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int &b = a;
4713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int &c = b;
4714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int &d = c;
4715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    b = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    c = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    d = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
4718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    MyStruct &rs = s;
4720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    rs.a = 0;              // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
4721176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int (&rarr)[10] = arr;
4723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    rarr[2] = 0;           // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
4724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void ptr_test() {
4727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int *b = &a;
4728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    *b = 0;                // no expected warning yet
4729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4730176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void for_test() {
4732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int total = 0;
4733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    for (int i : cntr) {   // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
4734176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      total += i;
4735176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
4736176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4737176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4738176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4739176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end namespace RangeBasedForAndReferences
4741176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4742176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4743176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4744176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace PassByRefTest {
4745176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4746176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Foo {
4747176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
4748176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Foo() : a(0), b(0) { }
4749176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4750176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int a;
4751176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int b;
4752176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4753176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void operator+(const Foo& f);
4754176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4755176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void operator[](const Foo& g);
4756176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4757176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4758176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate<class T>
4759176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesT&& mymove(T& f);
4760176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4761176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4762176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// test top-level functions
4763176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid copy(Foo f);
4764176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid write1(Foo& f);
4765176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid write2(int a, Foo& f);
4766176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid read1(const Foo& f);
4767176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid read2(int a, const Foo& f);
4768176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid destroy(Foo&& f);
4769176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4770176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid operator/(const Foo& f, const Foo& g);
4771176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid operator*(const Foo& f, const Foo& g);
4772176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4773176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4774176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4775176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4776176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass Bar {
4777176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic:
4778176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Mutex mu;
4779176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Foo           foo   GUARDED_BY(mu);
4780176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Foo           foo2  GUARDED_BY(mu);
4781176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Foo*          foop  PT_GUARDED_BY(mu);
4782176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SmartPtr<Foo> foosp PT_GUARDED_BY(mu);
4783176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4784176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // test methods.
4785176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void mwrite1(Foo& f);
4786176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void mwrite2(int a, Foo& f);
4787176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void mread1(const Foo& f);
4788176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void mread2(int a, const Foo& f);
4789176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4790176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // static methods
4791176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static void smwrite1(Foo& f);
4792176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static void smwrite2(int a, Foo& f);
4793176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static void smread1(const Foo& f);
4794176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static void smread2(int a, const Foo& f);
4795176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4796176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void operator<<(const Foo& f);
4797176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4798176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void test1() {
4799176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    copy(foo);             // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
4800176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4801176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4802176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4803176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4804176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    destroy(mymove(foo));  // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4805176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4806176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mwrite1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4807176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mwrite2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4808176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mread1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4809176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mread2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4810176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4811176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    smwrite1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4812176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    smwrite2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4813176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    smread1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4814176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    smread2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4815176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4816176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo + foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4817176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4818176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo / foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4819176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4820176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo * foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4821176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4822176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    foo[foo2];               // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
4823176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
4824176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    (*this) << foo;          // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
4825176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4826176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    copy(*foop);             // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
4827176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write1(*foop);           // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4828176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write2(10, *foop);       // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4829176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read1(*foop);            // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4830176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read2(10, *foop);        // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4831176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    destroy(mymove(*foop));  // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
4832176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4833176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    copy(*foosp);             // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4834176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write1(*foosp);           // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4835176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write2(10, *foosp);       // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4836176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read1(*foosp);            // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4837176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read2(10, *foosp);        // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4838176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    destroy(mymove(*foosp));  // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
4839176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
48400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // TODO -- these require better smart pointer handling.
4841176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    copy(*foosp.get());
4842176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write1(*foosp.get());
4843176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    write2(10, *foosp.get());
4844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read1(*foosp.get());
4845176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    read2(10, *foosp.get());
4846176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    destroy(mymove(*foosp.get()));
4847176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
4848176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
4849176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4850176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
4851176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}  // end namespace PassByRefTest
4852176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
48530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48540e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesnamespace AcquiredBeforeAfterText {
48550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48560e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo {
48570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
48580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2;
48590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3;
48600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1() {
48620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();
48630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
48640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
48650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
48670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
48680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
48690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test2() {
48720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
48730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
48740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
48750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
48760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test3() {
48790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
48800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
48810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
48820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
48830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {
48860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
48870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
48880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
48910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
48920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
48930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
48960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.AssertHeld();
48970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
48980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
48990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }
49000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }
49020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
49030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49050e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo2 {
49060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1;
49070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2 ACQUIRED_AFTER(mu1);
49080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3 ACQUIRED_AFTER(mu1);
49090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1() {
49110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();
49120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
49130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
49140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
49160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
49170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test2() {
49210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
49220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
49230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
49250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test3() {
49280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
49290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
49300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
49320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
49340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49360e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo3 {
49370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1 ACQUIRED_BEFORE(mu2);
49380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2;
49390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);
49400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu4;
49410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1() {
49430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();
49440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
49450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
49460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Lock();
49470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Unlock();
49490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
49500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
49510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test2() {
49550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Lock();
49560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();     // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
49570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
49590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Unlock();
49600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test3() {
49630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Lock();
49640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
49650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu4.Unlock();
49680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test4() {
49710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
49720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
49730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
49760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
49780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// Test transitive DAG traversal with AFTER
49810e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo4 {
49820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1;
49830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2 ACQUIRED_AFTER(mu1);
49840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3 ACQUIRED_AFTER(mu1);
49850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu4 ACQUIRED_AFTER(mu2, mu3);
49860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu5 ACQUIRED_AFTER(mu4);
49870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu6 ACQUIRED_AFTER(mu4);
49880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu7 ACQUIRED_AFTER(mu5, mu6);
49890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu8 ACQUIRED_AFTER(mu7);
49900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test() {
49920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu8.Lock();
49930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
49940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
49950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu8.Unlock();
49960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
49970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
49980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
49990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// Test transitive DAG traversal with BEFORE
50010e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo5 {
50020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
50030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2 ACQUIRED_BEFORE(mu4);
50040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3 ACQUIRED_BEFORE(mu4);
50050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);
50060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu5 ACQUIRED_BEFORE(mu7);
50070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu6 ACQUIRED_BEFORE(mu7);
50080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu7 ACQUIRED_BEFORE(mu8);
50090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu8;
50100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test() {
50120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu8.Lock();
50130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();  // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
50140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
50150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu8.Unlock();
50160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
50180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50200e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo6 {
50210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu1 ACQUIRED_AFTER(mu3);     // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}}
50220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu2 ACQUIRED_AFTER(mu1);     // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}}
50230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu3 ACQUIRED_AFTER(mu2);     // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}}
50240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu_b ACQUIRED_BEFORE(mu_b);  // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}}
50260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu_a ACQUIRED_AFTER(mu_a);   // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}}
50270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test0() {
50290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_a.Lock();
50300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_b.Lock();
50310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_b.Unlock();
50320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_a.Unlock();
50330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1a() {
50360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();
50370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
50380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1b() {
50410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Lock();
50420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_a.Lock();
50430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_b.Lock();
50440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_b.Unlock();
50450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu_a.Unlock();
50460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu1.Unlock();
50470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test() {
50500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Lock();
50510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu2.Unlock();
50520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test3() {
50550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Lock();
50560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    mu3.Unlock();
50570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
50590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}  // end namespace AcquiredBeforeAfterTest
50610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50630e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesnamespace ScopedAdoptTest {
50640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50650e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesclass Foo {
50660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Mutex mu;
50670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  int a GUARDED_BY(mu);
50680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  int b;
50690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {
50710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    MutexLock slock(&mu, true);
50720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    a = 0;
50730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test2() SHARED_UNLOCK_FUNCTION(mu) {
50760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ReaderMutexLock slock(&mu, true);
50770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    b = a;
50780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
50790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) {  // expected-note {{mutex acquired here}}
50810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    MutexLock slock(&mu, true);
50820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    a = 0;
50830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }  // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
50840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void test4() SHARED_LOCKS_REQUIRED(mu) {     // expected-note {{mutex acquired here}}
50860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ReaderMutexLock slock(&mu, true);
50870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    b = a;
50880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }  // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
50890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
50910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
50920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}  // end namespace ScopedAdoptTest
50930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
509487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
509587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace TestReferenceNoThreadSafetyAnalysis {
509687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
509787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#define TS_UNCHECKED_READ(x) ts_unchecked_read(x)
509887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
509987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Takes a reference to a guarded data member, and returns an unguarded
510087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// reference.
510187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartemplate <class T>
510287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarinline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
510387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return v;
510487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
510587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
510687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartemplate <class T>
510787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarinline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
510887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return v;
510987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
511087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
511187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
511287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass Foo {
511387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarpublic:
511487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Foo(): a(0) { }
511587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
511687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int a;
511787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
511887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
511987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
512087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass Bar {
512187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarpublic:
512287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Bar() : a(0) { }
512387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
512487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Mutex mu;
512587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int a   GUARDED_BY(mu);
512687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Foo foo GUARDED_BY(mu);
512787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
512887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
512987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
513087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid test() {
513187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Bar bar;
513287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const Bar cbar;
513387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
513487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int a = TS_UNCHECKED_READ(bar.a);       // nowarn
513587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  TS_UNCHECKED_READ(bar.a) = 1;           // nowarn
513687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
513787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int b = TS_UNCHECKED_READ(bar.foo).a;   // nowarn
513887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  TS_UNCHECKED_READ(bar.foo).a = 1;       // nowarn
513987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
514087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int c = TS_UNCHECKED_READ(cbar.a);      // nowarn
514187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
514287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
514387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#undef TS_UNCHECKED_READ
514487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
514587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}  // end namespace TestReferenceNoThreadSafetyAnalysis
514687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
514787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
514887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace GlobalAcquiredBeforeAfterTest {
514987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
515087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMutex mu1;
515187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMutex mu2 ACQUIRED_AFTER(mu1);
515287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
515387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid test3() {
515487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  mu2.Lock();
515587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  mu1.Lock();  // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
515687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  mu1.Unlock();
515787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  mu2.Unlock();
515887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
515987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
516087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}  // end namespace  GlobalAcquiredBeforeAfterTest
516187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
516287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
516387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace LockableUnions {
516487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
516587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarunion LOCKABLE MutexUnion {
516687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  int a;
516787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  char* b;
516887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
516987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void Lock()   EXCLUSIVE_LOCK_FUNCTION();
517087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void Unlock() UNLOCK_FUNCTION();
517187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
517287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
517387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMutexUnion muun2;
517487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMutexUnion muun1 ACQUIRED_BEFORE(muun2);
517587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
517687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid test() {
517787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  muun2.Lock();
517887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  muun1.Lock();  // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
517987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  muun1.Unlock();
518087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  muun2.Unlock();
518187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
518287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
518387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}  // end namespace LockableUnions
518487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
518587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// This used to crash.
518687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass acquired_before_empty_str {
518787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void WaitUntilSpaceAvailable() {
518887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    lock_.ReaderLock(); // expected-note {{acquired here}}
518987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  } // expected-warning {{mutex 'lock_' is still held at the end of function}}
519087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  Mutex lock_ ACQUIRED_BEFORE("");
519187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
5192