10ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -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
6988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKABLE            __attribute__ ((lockable))
7988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
8988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_BY(x)       __attribute__ ((guarded_by(x)))
9988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_VAR         __attribute__ ((guarded_var))
10988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_BY(x)    __attribute__ ((pt_guarded_by(x)))
11988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_VAR      __attribute__ ((pt_guarded_var))
12988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
13988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
145c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins#define EXCLUSIVE_LOCK_FUNCTION(...)    __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
155c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins#define SHARED_LOCK_FUNCTION(...)       __attribute__ ((shared_lock_function(__VA_ARGS__)))
165c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins#define ASSERT_EXCLUSIVE_LOCK(...)      __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
175c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins#define ASSERT_SHARED_LOCK(...)         __attribute__ ((assert_shared_lock(__VA_ARGS__)))
18988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
19988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_TRYLOCK_FUNCTION(...)    __attribute__ ((shared_trylock_function(__VA_ARGS__)))
20988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define UNLOCK_FUNCTION(...)            __attribute__ ((unlock_function(__VA_ARGS__)))
21988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCK_RETURNED(x)    __attribute__ ((lock_returned(x)))
22988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
23988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_LOCKS_REQUIRED(...) \
24988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
25988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_LOCKS_REQUIRED(...) \
26988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((shared_locks_required(__VA_ARGS__)))
27988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define NO_THREAD_SAFETY_ANALYSIS  __attribute__ ((no_thread_safety_analysis))
283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass  __attribute__((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
395c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();
405c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void AssertReaderHeld() ASSERT_SHARED_LOCK();
413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
431fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) MutexLock {
441fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
451fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
461fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~MutexLock() __attribute__((unlock_function));
471fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
481fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
491fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) ReaderMutexLock {
501fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
511fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
521fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~ReaderMutexLock() __attribute__((unlock_function));
531fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
541fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
55c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass SCOPED_LOCKABLE ReleasableMutexLock {
56c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins public:
57c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
58c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ~ReleasableMutexLock() UNLOCK_FUNCTION();
59c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
60c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void Release() UNLOCK_FUNCTION();
61c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
639d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
640b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// The universal lock, written "*", allows checking to be selectively turned
650b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// off for a particular piece of code.
660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnReads()  SHARED_LOCK_FUNCTION("*");
670b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnReads()    UNLOCK_FUNCTION("*");
680b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
690b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnWrites()   UNLOCK_FUNCTION("*");
700b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
710b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
72d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing handling of smart pointers.
739d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinstemplate<class T>
749d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass SmartPtr {
759d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinspublic:
769d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(T* p) : ptr_(p) { }
779d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
789d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  ~SmartPtr();
799d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
809d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* get()        const { return ptr_; }
819d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* operator->() const { return ptr_; }
8296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  T& operator*()  const { return *ptr_; }
83f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  T& operator[](int i) const { return ptr_[i]; }
849d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
859d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsprivate:
869d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* ptr_;
879d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
889d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
899d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
90d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing destructor calls and cleanup.
91d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsclass MyString {
92d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinspublic:
93d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  MyString(const char* s);
94d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  ~MyString();
95d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins};
96d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
97d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
98d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
1003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
1023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
1033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
1043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
1063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
1083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
1093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
110194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
1117336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins   void MyLock() __attribute__((exclusive_lock_function(mu)));
1123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
1133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
1153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
1173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
1187336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  sls_mw.x = 5;
1193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
1203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
1233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
1253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
1293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
1353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
1603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
1763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
1823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
1903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
1923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
1953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
1973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
1983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
2003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
204194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
205194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
206194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
207194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
208194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
2103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
2123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
2153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
2183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
2222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
2243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
2263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2270da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // expected-note{{mutex acquired here}}
2283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu2.Lock(); // expected-note{{mutex acquired here}}
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
2342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
2383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
2403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2412e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    expected-warning{{releasing mutex 'sls_mu' that was not held}}
2523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
255aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2564e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2602e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
2623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
2702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
2712e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
2720da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  do {
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
2783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
2790da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // \
280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
2812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
2870da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
2890da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock();
2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
2942e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
2962e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
302aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
3032e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
304aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
305aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
306aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
307aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
309aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
310aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
311aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
312aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
313aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
314aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
315aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
3363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{releasing mutex 'aa_mu' that was not held}}
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3482e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
350b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
351b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
352b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
353b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
354b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
355b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
356b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
357b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
358b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
3592f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
360b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3612f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
363b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3642f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
366b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
369b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
371b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
373b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
374b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
37505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
37605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
37705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
37805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
38305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
38405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
38505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
38605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
38705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
38805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
40005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
40105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
40205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
40405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
40605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
407af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
408af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
409af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
410af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
41405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
43705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
44205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
44705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
44905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
45205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
45405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
45705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
45905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
46205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
46405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
46705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
46905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
47205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
47405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
47705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
47805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
48005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
48105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
48205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
48305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
48505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
48705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
489a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
49105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
492b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
493eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
494eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
495eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
496eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
497eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
498eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
499eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
500eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
501eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
502eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
503eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
504eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
505eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
507eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
509eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
511eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
512eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
513eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
514eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
515eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
516eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
517eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
51899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
51999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
52899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
52999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
53699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
53799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
54499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
54599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
54899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
54999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
55099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
55199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
5533f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'fooA.mu'}}
55499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
55599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
55699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
55799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
55899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
55999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
56099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
56199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
56299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
56499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
56599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
56699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
56799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
56899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
56999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
57099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
57199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
57299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
5743f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.FooPointer->mu'}}
57599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
57699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
57799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
57999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
58099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
58199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
5833f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
58499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
58599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
58799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
58899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
58999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
59099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
5923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
59399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
59499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
59599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
596a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
597a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
598a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
599a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
601a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
602a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
603a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
604a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
605a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
606a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
607a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
608a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
609a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
6104e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
613a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6144e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
617a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
618a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
625a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
626a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
628a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
629a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
632a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
633a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
634a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
635a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
636a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
637a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
638a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
639a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
640a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
642a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
643a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
645a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
646a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
647a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
648a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6494e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
651a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
652a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6534e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
655a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
656a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
657a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
658a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
659a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
660a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
661a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
663a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
664a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
666a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
667a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
668a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
669a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
670a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
671a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
672a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
674a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
675a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
677a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
678a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
679a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
682978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
683978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
692978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
693978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
697978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
698978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
699978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
700978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
701978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
702978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
703978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
704978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
705978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
706978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
707978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
708978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
709978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
710978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
711978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
712978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
713978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
714978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
715978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
717978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
718978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
734978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
735978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
739978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
740978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
741978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
742978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
743978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
744978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
745978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
746978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
747af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
748af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
749af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
750af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
751af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
752af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
753cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
754cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
755cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
756cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
757cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
758cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
759cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
760cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
761cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
762cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
763978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
764978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
766978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
767978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
768978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
769978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
770978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
772978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
773978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
774978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
775978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
776978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
778978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
779978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
780978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
781978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
783978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
784978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
785978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
786978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
788978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
789978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
790978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
791978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
792978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
794978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
795978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
796978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
797978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
798978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
799978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
801978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
802978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
803978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
804978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
805978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
806978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
808978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
809978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
810194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8118121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
812194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
813194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
814194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
815194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8160d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
817194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
109023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
109523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1203e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 5;
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1217e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie    g = 2;
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
1226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
1232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1235e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 2;
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1245988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
12603f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b2->a_ = 3; // \
1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
12623f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b1->mu1_'}}
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
1291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
12933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
1294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
12983f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
1299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
1301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
13233f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->bar(7); // \
1324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
13253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
13263f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->a_ = 5; // \
1327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
13283f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
1365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1369988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
1404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1436988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1438988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1443988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1445988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1446988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1447988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1448988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1449988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1450988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1451988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1452988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1453988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1454988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1455988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1456988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1457988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1458988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1459988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1460988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1461988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1462988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1463988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1464988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1465988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1466988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1467988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1468988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1469988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1470988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1475988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1476988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1477988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1478988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14798121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14818121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14828121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14838121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14845696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)));
14855696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)));
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14878121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14888121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14928121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14935696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
14945696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14968121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14978121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14988121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14998121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
15008121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
15018121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15028121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
15038121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
15048121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15058121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
15068121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15078121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15088121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
15098121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15108121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
15118121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15128121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
15138121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15148121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15158121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
15168121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
15188121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
1519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
15218121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15228121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
15238121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15248121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
15258121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
1526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
15273f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-note {{found near match 'd1->mu'}}
15288121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
15298121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15308121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15318121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
15328121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1533e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1534f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1535e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1536e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1537e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1538e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1539e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1540e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1541e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1542e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1543e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1544e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1545e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15466db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1547e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1548e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1549e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1550e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1551f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1553f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
155597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
155697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
155797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
155897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1559a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1560a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1561a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1562a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1563a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1564a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
156597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
156697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
156797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
156897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
157197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
157297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
157397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1574f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
157597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1576601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1577601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1578601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1579601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1580601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1581601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1582601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1583601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1584601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1585601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1587601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1588601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1589601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1590601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
159197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
16151fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
16161fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
16171fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16181fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16191fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16201fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16211fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16221fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
1623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{acquiring mutex 'mu1' that is already held}}
1624c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
16251fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16261fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16271fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16281fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16291fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16301fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16311fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16321fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16331fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16341fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16351fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1637df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1638df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1639df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1640df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1641df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1642df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1643df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1644df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1645df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1646df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1647df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1648df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo();  // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1650df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1651df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1652df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1653df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1654df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1655df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1656df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1657df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
165860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchinsnamespace TryLockTest {
165960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
172443e3deeabf3ca02da427b63df8604e2daf86e8a3Sylvestre Ledru    if (b) {    // b should be unknown at this point, because of the join point
1725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      a = 8;    // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1737b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1738b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1739b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1740b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1741b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1742b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1743b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1744b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1745b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1746b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1747b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1748b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1749b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1750b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        a = 10;  // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1752b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1753b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1754b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1755b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
175660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
175760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of exclusive trylock
175860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo11() {
175960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
176060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.TryLock())
176160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
176260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
176360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
176460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.Lock();
176560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
176660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   a = 10;
176760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
176860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
176960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
177060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of shared trylock
177160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo12() {
177260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
177360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.ReaderTryLock())
177460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
177560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
177760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.ReaderLock();
177860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   int i = a;
178060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
178160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
1782b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1783b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
178460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins} // end namespace TrylockTest
178560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1786b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
18447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
18477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
18487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
184923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
1879651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
18803f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bt.fooBase.mu_'}}
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
1888651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
18897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
189023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
189123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
189223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
189323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
189423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
189723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
189823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
189923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
190023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1901dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
190223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
190423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
190523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
190623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
190823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
190923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
191023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
19117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
191223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
191323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
191423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
191523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
191623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
191723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
191823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1919dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
192023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
192123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
192323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
192423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
192523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
192623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
192723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
192823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
193023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
193123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
193223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
193323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
19347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
19357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
19377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1939e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1940e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1941e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1942e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1943e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1944e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1945e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1946e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1947e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1948e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1949e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1950e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1951e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1952e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1953e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1954e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1955e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1956e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
1958e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1959e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1960e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1961e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1962e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1963e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19652e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19682e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19692e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19712e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19722e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19732e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19742e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19772e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19782e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19802e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19822e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
1983651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
19842e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19862e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19872e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19882e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19892e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19912e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19922e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2052c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2054c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2055c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2056c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2057c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2058c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2059c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2060c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2061c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2063c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2064c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2065c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2066c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2067c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2068c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2069c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2070c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2071c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2072651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2073c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2074651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2075c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2076651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
2077c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2078a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);  // \
2079651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
2080c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2081c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2082651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2083c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2084651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2085c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2086651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2087c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2088c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2089c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2090c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2091c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2092c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2093a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);
2094c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2095c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2096c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2097c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2098c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2099c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2100c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2101c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2103c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2104c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21054bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
21064bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21074bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21084bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
21094bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21104bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
21114bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
21124bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
21134bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21144bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
21154bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
21164bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21174bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
21184bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
21194bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
21204bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
21214bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
21224bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
21234bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21244bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
21254bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
21264bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
21274bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21284bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
21294bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
2130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
21314bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2132c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2133c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21342f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21352f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
21362f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
21372f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
21382f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
21392f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21402f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
21412f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
21422f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
21432f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21442f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
21452f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
21462f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
21472f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
21482f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21492f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21504bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21514bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21524bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2153d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2154d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2155d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2156d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2157d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2158d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2159d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2160d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2161d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2162d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2163d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2164d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2165d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2166d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
21672a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21682a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
21692a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21702a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
21712a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
21722a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21732a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
21742a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21752a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
21762a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
21772a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
21782a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
21792a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
21802a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
21812a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
21822a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21832287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
21842287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21852287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21862287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
21872287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21882287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
21892287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
21902287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
21912287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
21922287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21932287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
21942287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
2195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
21962287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
2197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
21982287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
2199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
22002287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
22012287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22022287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
22032287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
22042a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
22052287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22062287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
22072287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22087ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22097ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
22107ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22117ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
22127ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
22137ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
22147ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
22157ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
22167ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
22177ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22187ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
22197ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22207ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
22230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
22250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
22270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
22280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
22310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22330d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
22340d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22350d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
22360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
22370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
22380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22390d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
22400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
22430d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22440d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
22450d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
22460d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
22470d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
22480d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
22490d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22500d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
22510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22550d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22560d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
22570d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
22590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22610d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
22620d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22630d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
22660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22670d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22680d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
22700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
22730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
22740d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
22750d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
22770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
22780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
22790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22800d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22810d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
22820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22850d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
2286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
22873f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo().mu_'}}
22880d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22890d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22900d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22910d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
2292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
22933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
22940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22970d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
2298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a,c).mu_' exclusively}} \
22993f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'bar.getFoo3(a,b).mu_'}}
23000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
23010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
23030d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
2304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar,b).mu_' exclusively}} \
23053f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'getBarFoo(bar,a).mu_'}}
23060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
23070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
23090d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{writing variable 'a' requires holding mutex '((a#_)#_#fooArray[b]).mu_' exclusively}} \
23113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
23120d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
23130d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
23140d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23160da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace MoreLockExpressions
23170da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23180da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23190da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsnamespace TrylockJoinPoint {
23200da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23210da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsclass Foo {
23220da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  Mutex mu;
23230da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  bool c;
23240da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23250da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  void foo() {
23260da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    if (c) {
23270da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      if (!mu.TryLock())
23280da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins        return;
23290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    } else {
23300da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      mu.Lock();
23310da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    }
23320da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    mu.Unlock();
23330da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  }
23340da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins};
23350da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23360da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace TrylockJoinPoint
23370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2339f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsnamespace LockReturned {
2340f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2341f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Foo {
2342f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2343f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int a             GUARDED_BY(mu_);
2344f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);
2345f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2346f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2347f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2348f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2349f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex* getMu() LOCK_RETURNED(mu_);
2350f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2351f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex mu_;
2352f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2353f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2354f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2355f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2356f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2357f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Calls getMu() directly to lock and unlock
2358f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test1(Foo* f1, Foo* f2) {
2359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->a = 0;       // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->foo();       // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2361f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2365f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2366f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Lock();
2367f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2368f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->a = 0;
2369f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo();
23703f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  f1->foo2(f2); // \
2371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
23723f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'f1->mu_'}}
2373f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2374f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Lock();
2375f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo2(f2);
2376f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Unlock();
2377f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2378f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::sfoo(f1);
2379f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2380f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Unlock();
2381f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2382f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2383f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2384f63797c741e646b9482d204c88dee02fb41d7962DeLesley HutchinsMutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2385f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2386f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Bar : public Foo {
2387f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2388f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int  b            GUARDED_BY(getMu());
2389f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());
2390f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2391f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2392f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2393f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2394f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2395f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2396f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2397f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2398f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Use getMu() within other attributes.
2399f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// This requires at lest levels of substitution, more in the case of
2400f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test2(Bar* b1, Bar* b2) {
2401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->bar();       // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2407f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2408f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Lock();
2409f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2410f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2411f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
24123f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b1->bar2(b2);  // \
2413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
24143f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // // expected-note {{found near match 'b1->mu_'}}
2415f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2416f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Lock();
2417f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2418f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2419f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Unlock();
2420f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2421f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2422f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2423f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2424f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Unlock();
2425f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2426f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2427f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2428f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Sanity check -- lock the mutex directly, but use attributes that call getMu()
2429f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Also lock the mutex using getFooMu, which calls a lock_returned function.
2430f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test3(Bar* b1, Bar* b2) {
2431f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Lock();
2432f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2433f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
2434f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2435f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Lock();
2436f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2437f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Unlock();
2438f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2439f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2440f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2441f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2442f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Unlock();
2443f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2444f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2445f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins} // end namespace LockReturned
2446f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2447f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2448c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsnamespace ReleasableScopedLock {
2449c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2450c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass Foo {
2451c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  Mutex mu_;
2452c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  bool c;
2453c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  int a GUARDED_BY(mu_);
2454c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2455c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test1();
2456c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test2();
2457c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test3();
24585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test4();
24595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test5();
2460c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
2461c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2462c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2463c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test1() {
2464c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2465c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2466c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2467c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2468c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test2() {
2469c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2470c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  if (c) {            // test join point -- held/not held during release
2471c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins    rlock.Release();
2472c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
2473c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2474c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2475c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test3() {
2476c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2477c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 0;
2478c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 1;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2480c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2481c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
24825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test4() {
24835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();
2485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
24865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test5() {
24895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  if (c) {
24915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    rlock.Release();
24925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  }
24935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  // no warning on join point for managed lock.
2494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
24955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2498c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins} // end namespace ReleasableScopedLock
2499c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2500c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
250176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsnamespace TrylockFunctionTest {
250276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsclass Foo {
250476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinspublic:
250576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu1_;
250676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu2_;
250776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool c;
250876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
251076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins};
251176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsbool Foo::lockBoth() {
251376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!mu1_.TryLock())
251476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
251576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  mu2_.Lock();
251776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!c) {
251876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu1_.Unlock();
251976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu2_.Unlock();
252076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
252176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  }
252276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  return true;
252476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}
252576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}  // end namespace TrylockFunctionTest
2528c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2529c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2530c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2531c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsnamespace DoubleLockBug {
2532c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2533c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsclass Foo {
2534c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinspublic:
2535c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  Mutex mu_;
2536c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  int a GUARDED_BY(mu_);
2537c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
25395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int  foo2() SHARED_LOCKS_REQUIRED(mu_);
2540c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins};
2541c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2542c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2544c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  a = 0;
2545c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins}
2546c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
25485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return a;
25495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2553c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2554c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2555879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsnamespace UnlockBug {
2556c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2557879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsclass Foo {
2558879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinspublic:
2559879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  Mutex mutex_;
2560879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2561879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
2562879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2564879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2565879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2566879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
2567879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2569879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins};
2570879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2571879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins} // end namespace UnlockBug
2572c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2573c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
25745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2575bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsnamespace FoolishScopedLockableBug {
2576bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2577bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass SCOPED_LOCKABLE WTF_ScopedLockable {
2578bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinspublic:
2579bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2580bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2581bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  // have to call release() manually;
2582bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  ~WTF_ScopedLockable();
2583bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2584bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void release() UNLOCK_FUNCTION();
2585bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2586bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2587bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2588bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass Foo {
2589bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  Mutex mu_;
2590bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  int a GUARDED_BY(mu_);
2591bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  bool c;
2592bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2593bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void doSomething();
2594bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2595bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test1() {
2596bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);
2597bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    wtf.release();
2598bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2599bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2600bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test2() {
2601bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
2603bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2604bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test3() {
2605bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2606bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2607bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2608bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2609bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2610bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2611bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test4() {
2612bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2613bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2614bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2615bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2616bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2617bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2618bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2619bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2620bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2621bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test5() {
2622bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2623bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2624bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2626bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2627bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test6() {
2628bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2629bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2630bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2631bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2632bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2633bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
2635bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2636bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2637bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2638bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins} // end namespace FoolishScopedLockableBug
2639bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
26409d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26429d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsnamespace TemporaryCleanupExpr {
26439d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26449d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass Foo {
26459d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  int a GUARDED_BY(getMutexPtr().get());
26469d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26479d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr<Mutex> getMutexPtr();
26489d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26499d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  void test();
26509d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
26519d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26529d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26539d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsvoid Foo::test() {
26549d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  {
26559d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    ReaderMutexLock lock(getMutexPtr().get());
26569d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    int b = a;
265796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
2658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int b = a;  // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
26599d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins}
26609d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26619d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins} // end namespace TemporaryCleanupExpr
26629d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26639d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
266496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsnamespace SmartPointerTests {
266696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Foo {
266896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinspublic:
266996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Mutex> mu_;
267096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int a GUARDED_BY(mu_);
267196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int b GUARDED_BY(mu_.get());
267296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int c GUARDED_BY(*mu_);
267396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);
267596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Unlock() UNLOCK_FUNCTION(mu_);
267696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
267896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
267996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
268096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
268196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test4();
268296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test5();
268396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test6();
268496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test7();
268596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test8();
268696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
268796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test0() {
2689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b = 0;  // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  c = 0;  // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
269296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
269396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test1() {
269596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
269696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
269796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
269896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
269996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Unlock();
270096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test2() {
270396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();
270496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
270596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
270696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
270796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Unlock();
270896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test3() {
271296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();
271396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
271496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
271596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
271696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
271796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
271896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test4() {
272196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(mu_.get());
272296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
272396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
272496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
272596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
272696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test5() {
272996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(&(*mu_));
273096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
273196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
273296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
273396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
273496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test6() {
273796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Lock();
273896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
273996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
274096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
274196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();
274296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
274396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test7() {
274696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
274796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Lock();
274896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
274996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
275296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Unlock();
275396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
275696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
275796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
276096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Unlock();
276196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
276396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
276496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Unlock();
276596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
276796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Lock();
276896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
276996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
277096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test8() {
277496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
2775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  mu_.get()->Lock();    // expected-warning {{acquiring mutex 'mu_' that is already held}}
2776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (*mu_).Lock();        // expected-warning {{acquiring mutex 'mu_' that is already held}}
277796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
2778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Unlock();             // expected-warning {{releasing mutex 'mu_' that was not held}}
277996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
278096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Bar {
278396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Foo> foo;
278496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
278696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
278796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
278896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
278996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
279096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test0() {
2793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo->a = 0;         // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
2794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
2795651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
279696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
279796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test1() {
280096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Lock();
280196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
280296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
280396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
280496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Unlock();
280596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
280696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test2() {
280996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).mu_->Lock();
281096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
281196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
281296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
281396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->mu_->Unlock();
281496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
281596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test3() {
281896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(foo->mu_.get());
281996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
282096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
282196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
282296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
282396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}  // end namespace SmartPointerTests
282596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
28285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsnamespace DuplicateAttributeTest {
28295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsclass LOCKABLE Foo {
28315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinspublic:
28325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu1_;
28335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu2_;
28345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu3_;
28355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int a GUARDED_BY(mu1_);
28365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int b GUARDED_BY(mu2_);
28375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int c GUARDED_BY(mu3_);
28385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
28405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
28415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);
28435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void slock1() SHARED_LOCK_FUNCTION(mu1_);
28445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void locklots()
28465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_)
28475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_)
28485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock1() UNLOCK_FUNCTION(mu1_);
28515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlocklots()
28535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_)
28545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_)
28555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins};
28575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }
28605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock() UNLOCK_FUNCTION()         { }
28615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {
28635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
28675696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  mu1_.ReaderLock();
28685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
28715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::locklots()
28775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
28785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
28795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
28855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
28895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlocklots()
28955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_)
28965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_, mu3_) {
28975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
29005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test0() {
29045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
2909651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.lock();     // expected-warning {{acquiring mutex 'foo' that is already held}}
29105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
2911651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock();   // expected-warning {{releasing mutex 'foo' that was not held}}
29125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test1() {
29165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
29185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
2922651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.lock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
29235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29245381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock1();  // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
29265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint test2() {
29305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
29325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d1 = foo.a;
29335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
2936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.slock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
29375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d2 = foo.a;
29385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2939651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  foo.unlock1();   // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
29405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return d1 + d2;
29415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test3() {
29455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3(); // \
2954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
2955651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
2956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
29575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3(); // \
2962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
2963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
2964651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
29655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid testlots() {
29695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots(); // \
2978651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
2979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
2980651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
29815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots(); // \
2986651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
2987651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
2988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
29895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}  // end namespace DuplicateAttributeTest
29925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
299513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsnamespace TryLockEqTest {
299613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsclass Foo {
299813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex mu_;
299913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int a GUARDED_BY(mu_);
300013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  bool c;
300113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
300313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
300413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_);
300513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test1();
300713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test2();
300813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins};
300913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test1() {
301213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == 0) {
3013651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
301413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
301513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
301613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
301713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
301813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() != 0) {
302013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 != tryLockMutexP()) {
302513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(tryLockMutexP() == 0)) {
303013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
303113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
303213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
303413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 0) {
3035651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
303613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
303713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
303913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
304013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 == tryLockMutexI()) {
3042651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
304313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
304413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
304513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
304613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
304713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 1) {
304913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
305013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
305113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == false) {
3054651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
305513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
305613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
305813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
305913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == true) {
306113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
306213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
306313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else {
3065651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
306613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#if __has_feature(cxx_nullptr)
306913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == nullptr) {
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#endif
307613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
307713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins} // end namespace TryLockEqTest
30795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
308096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
3081ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsnamespace ExistentialPatternMatching {
3082ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3083ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Graph {
3084ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3085ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Mutex mu_;
3086ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3087ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3088ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3089ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3090ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3091ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Node {
3092ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3093ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  int a GUARDED_BY(&Graph::mu_);
3094ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3095ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3096ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins    a = 0;
3097ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  }
3098ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3099ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3100ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3101ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid test() {
3102ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g1;
3103ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g2;
3104ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Node n1;
3105ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.a = 0;   // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo();   // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3108ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();
3109ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3110ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();
3111ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3112ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3114ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3115ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3116ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Lock();
3117ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3118ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3120ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3121ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3122ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3123ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3124ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3126ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  UnlockAllGraphs();
3127ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3128ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3129ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3130ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3131ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3132ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3133ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3134ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  g1.mu_.Lock();  // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3136ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3137ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins}
3138ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3139ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins} // end namespace ExistentialPatternMatching
3140ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
31414e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31424e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsnamespace StringIgnoreTest {
31434e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31444e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Foo {
31454e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31464e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  Mutex mu_;
31474e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION("");
31484e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION("");
31494e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void goober() EXCLUSIVE_LOCKS_REQUIRED("");
31504e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void roober() SHARED_LOCKS_REQUIRED("");
31514e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31524e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31534e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31544e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Bar : public Foo {
31554e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31564e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void bar(Foo* f) {
31574e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->unlock();
31584e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->goober();
31594e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->roober();
31604e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->lock();
31614e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  };
31624e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31634e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31644e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins} // end namespace StringIgnoreTest
31654e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31664e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31675408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsnamespace LockReturnedScopeFix {
31685408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31695408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsclass Base {
31705408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsprotected:
31715408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  struct Inner;
31725408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  bool c;
31735408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31745408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  const Mutex& getLock(const Inner* i);
31755408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31765408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
31775408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
31785408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
31795408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31805408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void bar(Inner* i);
31815408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31825408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31835408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31845408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsstruct Base::Inner {
31855408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  Mutex lock_;
31865408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
31875408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31885408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31895408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31905408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsconst Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
31915408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  return i->lock_;
31925408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
31935408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31945408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31955408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::foo(Inner* i) {
31965408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  i->doSomething();
31975408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
31985408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31995408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::bar(Inner* i) {
32005408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  if (c) {
32015408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Lock();
32025408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    unlockInner(i);
32035408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32045408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  else {
32055408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    lockInner(i);
32065408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Unlock();
32075408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32085408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32095408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32105408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins} // end namespace LockReturnedScopeFix
32115408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
3212fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3213fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsnamespace TrylockWithCleanups {
3214fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3215fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstruct Foo {
3216fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Mutex mu_;
3217fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a GUARDED_BY(mu_);
3218fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3219fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3220fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley HutchinsFoo* GetAndLockFoo(const MyString& s)
3221fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3222fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3223fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstatic void test() {
3224fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Foo* lt = GetAndLockFoo("foo");
3225fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  if (!lt) return;
3226fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a = lt->a;
3227fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  lt->mu_.Unlock();
3228fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3229fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
323024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TrylockWithCleanups
3231fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3232fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
32330b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsnamespace UniversalLock {
32340b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32350b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsclass Foo {
32360b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  Mutex mu_;
32370b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  bool c;
32380b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32390b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  int a        GUARDED_BY(mu_);
32400b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void r_foo() SHARED_LOCKS_REQUIRED(mu_);
32410b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
32420b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32430b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test1() {
32440b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    int b;
32450b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32460b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnReads();
32470b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    b = a;
32480b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    r_foo();
32490b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnReads();
32500b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32510b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32520b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32530b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    w_foo();
32540b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32550b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32560b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32570b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // don't warn on joins with universal lock
32580b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test2() {
32590b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32600b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32610b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32620b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0; // \
3263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
32640b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();  // \
3265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{releasing mutex '*' that was not held}}
32660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32670b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32680b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32690b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // make sure the universal lock joins properly
32700b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test3() {
32710b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32720b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32730b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32740b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32750b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    else {
32760b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32770b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32780b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32790b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32800b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32810b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32820b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32830b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32840b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32850b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // combine universal lock with other locks
32860b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test4() {
32870b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32880b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32890b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32900b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32910b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32920b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32930b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32940b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32950b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32960b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32970b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32980b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32990b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33000b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33010b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33020b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins};
33030b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
330424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace UniversalLock
330524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsnamespace TemplateLockReturned {
330824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinstemplate<class T>
331024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass BaseT {
331124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
331224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  virtual void baseMethod() = 0;
331324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
331424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
331524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex mutex_;
331624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  int a GUARDED_BY(mutex_);
331724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
331824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
331924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
332024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass Derived : public BaseT<int> {
332124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
332224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
332324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins    a = 0;
332424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  }
332524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
332624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
332724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TemplateLockReturned
332824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
332924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
3330f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsnamespace ExprMatchingBugFix {
3331f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3332f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Foo {
3333f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3334f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Mutex mu_;
3335f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3336f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3337f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3338f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Bar {
3339f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3340f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  bool c;
3341f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Foo* foo;
3342f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Bar(Foo* f) : foo(f) { }
3343f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3344f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  struct Nested {
3345f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Foo* foo;
3346f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested(Foo* f) : foo(f) { }
3347f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3348f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3349f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  };
3350f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3351f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  void test();
3352f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3353f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3354f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3355f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsvoid Bar::test() {
3356f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  foo->mu_.Lock();
3357f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  if (c) {
3358f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested *n = new Nested(foo);
3359f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    n->unlockFoo();
3360f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3361f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  else {
3362f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    foo->mu_.Unlock();
3363f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3364f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}
3365f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3366f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}; // end namespace ExprMatchingBugfix
3367f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3368f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
33695b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsnamespace ComplexNameTest {
3370f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
33715b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Foo {
33725b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
33735b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
33745b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33755b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_)  { }
33765b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
33775b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33785b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
33795b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
33805b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33815b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Bar {
33825b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
33835b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
33845b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33855b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar()  LOCKS_EXCLUDED(mu_) { }
33865b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Bar() LOCKS_EXCLUDED(mu_) { }
33875b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33885b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
33895b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
33905b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33915b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33925b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test1() {
3393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Foo f;           // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
3394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int a = f[0];    // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
3395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}                  // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
33965b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33975b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33985b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test2() {
33995b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Lock();
34005b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  {
3401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
3402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
3403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
34045b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Unlock();
34055b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}
34065b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34075b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};  // end namespace ComplexNameTest
34082a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34092a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34102a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsnamespace UnreachableExitTest {
34112a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34122a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsclass FemmeFatale {
34132a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinspublic:
34142a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale();
34152a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  ~FemmeFatale() __attribute__((noreturn));
34162a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins};
34172a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34182a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid exitNow() __attribute__((noreturn));
3419d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid exitDestruct(const MyString& ms) __attribute__((noreturn));
34202a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34212a237e03c407ff55bd8639b18658a8751955f1dbDeLesley HutchinsMutex fatalmu_;
34222a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34232a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34242a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  exitNow();
34252a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34262a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34272a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34282a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale femme;
34292a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34302a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34312a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsbool c;
34322a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34332a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34342a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  if (c) {
34352a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    exitNow();
34362a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34372a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  else {
34382a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    FemmeFatale femme;
34392a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34402a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34412a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
3442d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3443d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  exitDestruct("foo");
3444d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins}
3445d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
34462a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}   // end namespace UnreachableExitTest
3447186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3448186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3449186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsnamespace VirtualMethodCanonicalizationTest {
3450186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3451186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base {
3452186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3453186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  virtual Mutex* getMutex() = 0;
3454186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3455186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3456186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base2 : public Base {
3457186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3458186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3459186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3460186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3461186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base3 : public Base2 {
3462186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3463186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3464186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3465186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3466186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Derived : public Base3 {
3467186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3468186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();  // overrides Base::getMutex()
3469186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3470186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3471186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3472186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3473186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3474186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  baseFun(d);
3475186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}
3476186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3477186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}  // end namespace VirtualMethodCanonicalizationTest
3478186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3479d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3480d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsnamespace TemplateFunctionParamRemapTest {
3481d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3482d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate <class T>
3483d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsstruct Cell {
3484d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  T dummy_;
3485d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Mutex* mu_;
3486d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3487d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3488d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass Foo {
3489d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3490d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  template <class T>
3491d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3492d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3493d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void test();
3494d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3495d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3496d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3497d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::elr(Cell<T>* c1) { }
3498d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3499d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::test() {
3500d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3501d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  elr(&cell); // \
3502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3503d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3504d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3505d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3506d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3507d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3508d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3509d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3510d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c1) { }
3511d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3512d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest() {
3513d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3514d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR(&cell); // \
3515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
3516d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3517d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3518d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3519d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3520d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3521d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3522d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// second declaration
3523d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3524d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c2);
3525d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3526d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3527d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c3) { }
3528d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3529d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// re-declaration after definition
3530d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3531d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c4);
3532d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3533d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest2() {
3534d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3535d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR2(&cell); // \
3536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
3537d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3538d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3539d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3540d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3541d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass FooT {
3542d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3543d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3544d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3545d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3546d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3547d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid FooT<T>::elr(Cell<T>* c1) { }
3548d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3549d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid testFooT() {
3550d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3551d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  FooT<int> foo;
3552d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  foo.elr(&cell); // \
3553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3554d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3555d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3556d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}  // end namespace TemplateFunctionParamRemapTest
3557d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3558ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3559ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsnamespace SelfConstructorTest {
3560ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3561ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass SelfLock {
3562ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3563ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock()  EXCLUSIVE_LOCK_FUNCTION(mu_);
3564ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock() UNLOCK_FUNCTION(mu_);
3565ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3566ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3567ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3568ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  Mutex mu_;
3569ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3570ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3571ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass LOCKABLE SelfLock2 {
3572ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3573ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2()  EXCLUSIVE_LOCK_FUNCTION();
3574ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock2() UNLOCK_FUNCTION();
3575ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3576ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3577ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3578ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3579ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3580ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test() {
3581ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock s;
3582ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s.foo();
3583ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3584ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3585ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test2() {
3586ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2 s2;
3587ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s2.foo();
3588ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3589ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3590ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}  // end namespace SelfConstructorTest
3591ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
35923ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
35933ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsnamespace MultipleAttributeTest {
35943ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
35953ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsclass Foo {
35963ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu1_;
35973ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu2_;
35983ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  a GUARDED_BY(mu1_);
35993ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  b GUARDED_BY(mu2_);
36003ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  c GUARDED_BY(mu1_)    GUARDED_BY(mu2_);
36013ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
36023ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36033ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo1()          EXCLUSIVE_LOCKS_REQUIRED(mu1_)
36043ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCKS_REQUIRED(mu2_);
36053ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo2()          SHARED_LOCKS_REQUIRED(mu1_)
36063ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_LOCKS_REQUIRED(mu2_);
36073ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo3()          LOCKS_EXCLUDED(mu1_)
36083ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       LOCKS_EXCLUDED(mu2_);
36093ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void lock()          EXCLUSIVE_LOCK_FUNCTION(mu1_)
36103ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCK_FUNCTION(mu2_);
36115696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerlock()    SHARED_LOCK_FUNCTION(mu1_)
36125696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins                       SHARED_LOCK_FUNCTION(mu2_);
36133ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void unlock()        UNLOCK_FUNCTION(mu1_)
36143ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       UNLOCK_FUNCTION(mu2_);
36153ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool trylock()       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
36163ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
36173ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
36183ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_TRYLOCK_FUNCTION(true, mu2_);
3619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
3620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    ASSERT_EXCLUSIVE_LOCK(mu2_);
3621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void assertShared() ASSERT_SHARED_LOCK(mu1_)
3622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      ASSERT_SHARED_LOCK(mu2_);
36233ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36243ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void test();
3625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void testAssert();
3626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void testAssertShared();
36273ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins};
36283ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36293ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36303ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo1() {
36313ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 1;
36323ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 2;
36333ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36343ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36353ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo2() {
36363ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int result = a + b;
36373ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36383ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36393ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo3() { }
36405696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::lock() { mu1_.Lock();  mu2_.Lock(); }
36415696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::readerlock() { mu1_.ReaderLock();  mu2_.ReaderLock(); }
36425696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::unlock() { mu1_.Unlock();  mu2_.Unlock(); }
36433ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::trylock()       { return true; }
36443ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::readertrylock() { return true; }
36453ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36463ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36473ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::test() {
36483ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Lock();
36493ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo1();             // expected-warning {{}}
36503ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  c = 0;              // expected-warning {{}}
36513ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  *d = 0;             // expected-warning {{}}
36523ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36533ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36543ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.ReaderLock();
36553ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo2();             // expected-warning {{}}
36563ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int x = c;          // expected-warning {{}}
36573ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int y = *d;         // expected-warning {{}}
36583ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36593ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36603ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Lock();
36613ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo3();             // expected-warning {{}}
36623ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Unlock();
36633ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36643ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  lock();
36653ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 0;
36663ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 0;
36673ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36683ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36693ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  readerlock();
36703ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int z = a + b;
36713ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36723ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36733ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (trylock()) {
36743ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    a = 0;
36753ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    b = 0;
36763ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
36773ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
36783ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36793ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (readertrylock()) {
36803ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    int zz = a + b;
36813ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
36823ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
36833ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36843ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
3685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Force duplication of attributes
3686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::assertBoth() { }
3687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::assertShared() { }
3688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::testAssert() {
3690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assertBoth();
3691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  a = 0;
3692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  b = 0;
3693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Foo::testAssertShared() {
3696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assertShared();
3697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int zz = a + b;
3698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
37003ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37013ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}  // end namespace MultipleAttributeTest
37023ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37033ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
370491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsnamespace GuardedNonPrimitiveTypeTest {
370591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
370691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
370791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Data {
370891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
370991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data(int i) : dat(i) { }
371091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  getValue() const { return dat; }
371291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void setValue(int i)  { dat = i; }
371391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  operator[](int i) const { return dat; }
371591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int& operator[](int i)       { return dat; }
371691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void operator()() { }
371891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
372091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int dat;
372191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
372291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass DataCell {
372591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
372691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  DataCell(const Data& d) : dat(d) { }
372791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
372991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data dat;
373091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
373191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsvoid showDataCell(const DataCell& dc);
373491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Foo {
373791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
373891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // method call tests
373991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test() {
374091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(0);         // FIXME -- should be writing \
3741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
374291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_.getValue();  // \
3743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
374491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);      // FIXME -- should be writing \
3746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
374791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();   // \
3748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
374991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
375091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(0);      // FIXME -- should be writing \
3751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
375291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();   // \
3753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
375491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
375591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_).setValue(0);    // FIXME -- should be writing \
3756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
375791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = (*datap2_).getValue(); // \
3758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
375991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Lock();
376191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(1);
376291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(1);
376391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(1);
376491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
376591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.ReaderLock();
376791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = data_.getValue();
376891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);  // reads datap1_, writes *datap1_
376991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();
377091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();
377191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
377291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
377391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // operator tests
377591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test2() {
3776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
3777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
3778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
3780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
3783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
3784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3785651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
3788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    data_();              // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
379091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
379191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // const operator tests
379391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test3() const {
3794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
379591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //FIXME
3797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
3798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
379991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
3800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int a = data_[0];       // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
380191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
380291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
380491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Mutex mu_;
380591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data  data_   GUARDED_BY(mu_);
380691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap1_ GUARDED_BY(mu_);
380791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap2_ PT_GUARDED_BY(mu_);
380891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
380991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins}  // end namespace GuardedNonPrimitiveTypeTest
381191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsnamespace GuardedNonPrimitive_MemberAccess {
381493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Cell {
381693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
381793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell(int i);
381893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void cellMethod();
382093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int a;
382293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
382393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Foo {
382693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
382793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int   a;
382893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell  c  GUARDED_BY(cell_mu_);
382993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell* cp PT_GUARDED_BY(cell_mu_);
383093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void myMethod();
383293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex cell_mu_;
383493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
383593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Bar {
383893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsprivate:
383993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex mu_;
384093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo  foo  GUARDED_BY(mu_);
384193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo* foop PT_GUARDED_BY(mu_);
384293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void test() {
3844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.myMethod();      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
384593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
3847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
384893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3849651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3850651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
385193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
3853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
385493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
3856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
3857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
3858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
385993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3860651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3861651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3862651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3863651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
386493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
3865651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3866651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
3867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
3868651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
386993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  };
387093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
387193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins}  // namespace GuardedNonPrimitive_MemberAccess
387393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
38740ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38750ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsnamespace TestThrowExpr {
38760ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38770ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsclass Foo {
38780ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  Mutex mu_;
38790ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38800ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  bool hasError();
38810ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38820ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  void test() {
38830ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Lock();
38840ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    if (hasError()) {
38850ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins      throw "ugly";
38860ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    }
38870ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Unlock();
38880ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  }
38890ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins};
38900ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38910ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins}  // end namespace TestThrowExpr
38920ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38930ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
3894ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsnamespace UnevaluatedContextTest {
3895ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3896ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins// parse attribute expressions in an unevaluated context.
3897ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3898ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex1();
3899ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex2();
3900ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3901ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3902ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3903ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3904ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3905ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins}  // end namespace UnevaluatedContextTest
3906ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
39075696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39085696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsnamespace LockUnlockFunctionTest {
39095696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39105696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins// Check built-in lock functions
39115696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass LOCKABLE MyLockable  {
39125696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39135696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock()       EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
39145696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION()    { mu_.ReaderLock(); }
39155696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock()     UNLOCK_FUNCTION()         { mu_.Unlock(); }
39165696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39175696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39185696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39195696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39205696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39215696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39225696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass Foo {
39235696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39245696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Correct lock/unlock functions
39255696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
39265696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Lock();
39275696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39285696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION(mu_) {
39305696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.ReaderLock();
39315696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_) {
39345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Unlock();
39355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39365696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39375696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check failure to lock.
39385696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}
39395696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39405696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
3941651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
39425696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39435696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39445696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39455696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
3946651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
39475696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39485696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39495696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39505696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
3951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
39525696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39535696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check locking the wrong thing.
39545696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39555696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();            // expected-note {{mutex acquired here}}
3956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
3957651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
39585696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39595696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39605696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39615696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.ReaderLock();      // expected-note {{mutex acquired here}}
3962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
3963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
39645696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39655696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
3967651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mu2_.Unlock();  // expected-warning {{releasing mutex 'mu2_' that was not held}}
3968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
39695696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39705696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39715696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39725696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu2_;
39735696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39745696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39755696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins}  // end namespace LockUnlockFunctionTest
39765696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39775c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39785c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsnamespace AssertHeldTest {
39795c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39805c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsclass Foo {
39815c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinspublic:
39825c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int c;
39835c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int a GUARDED_BY(mu_);
39845c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  Mutex mu_;
39855c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39865c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test1() {
39875c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
39885c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
39895c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
39905c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39915c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39925c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test2() {
39935c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertReaderHeld();
39945c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
3995651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
39965c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39975c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39985c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test3() {
39995c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40005c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40015c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40025c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40035c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40045c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40055c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40065c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40075c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40085c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40095c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
40105c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40115c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40125c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40135c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40145c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40155c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test5() UNLOCK_FUNCTION(mu_) {
40165c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40175c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40185c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40195c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40205c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test6() {
40215c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40225c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40235c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }  // should this be a warning?
40245c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40255c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test7() {
40265c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40275c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40285c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40295c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40305c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40315c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40325c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40335c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40345c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40355c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40365c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40375c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test8() {
40385c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40395c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40405c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40415c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40425c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40435c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40445c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40455c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40465c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40475c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40485c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40495c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test9() {
40505c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40515c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40525c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40535c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40545c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
40555c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
4056651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
40575c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40585c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test10() {
40595c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40605c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
40615c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40625c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40635c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40645c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
4065651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
40665c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40675c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
40685c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40695c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test11() {
40705c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    assertMu();
40715c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40725c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40735c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40745c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins};
40755c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40765c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins}  // end namespace AssertHeldTest
40775c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40785c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40797336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsnamespace LogicalConditionalTryLock {
40807336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40817336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsclass Foo {
40827336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinspublic:
40837336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  Mutex mu;
40847336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  int a GUARDED_BY(mu);
40857336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool c;
40867336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40877336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool newc();
40887336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40897336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test1() {
40907336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && mu.TryLock()) {
40917336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
40927336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
40937336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
40947336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
40957336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40967336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test2() {
40977336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    bool b = mu.TryLock();
40987336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && b) {
40997336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41007336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41017336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41027336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41037336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41047336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test3() {
41057336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c || !mu.TryLock())
41067336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
41077336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
41087336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
41097336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41107336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41117336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test4() {
41127336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c && mu.TryLock()) {
41137336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41147336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      c = newc();
41157336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41167336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41177336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41187336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41197336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test5() {
41207336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c) {
41217336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      if (newc() || !mu.TryLock())
41227336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins        break;
41237336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41247336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41257336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41267336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41277336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41287336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test6() {
41297336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Lock();
41307336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    do {
41317336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41327336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41337336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    } while (newc() && mu.TryLock());
41347336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41357336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41367336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test7() {
41377336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    for (bool b = mu.TryLock(); c && b;) {
41387336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41397336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41407336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41417336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41427336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41437336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test8() {
41447336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && newc() && mu.TryLock()) {
41457336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41467336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41477336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41487336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41497336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41507336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test9() {
41517336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (!(c && newc() && mu.TryLock()))
41527336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
41537336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
41547336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
41557336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41566b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins
41576b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins  void test10() {
41586b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins    if (!(c || !mu.TryLock())) {
41596b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins      a = 0;
41606b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins      mu.Unlock();
41616b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins    }
41626b725d120b6b068d9ec3a224133b21c55b5e8befDeLesley Hutchins  }
41637336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins};
41647336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41657336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins}  // end namespace LogicalConditionalTryLock
41667336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
416743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
416843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
416943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsnamespace PtGuardedByTest {
417043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
417143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsvoid doSomething();
417243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
417343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass Cell {
417443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  public:
417543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  int a;
417643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
417743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
417843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
417943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins// This mainly duplicates earlier tests, but just to make sure...
418043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass PtGuardedBySanityTest {
4181f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Mutex  mu1;
4182f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Mutex  mu2;
4183f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  int*   a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4184f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Cell*  c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4185f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  int    sa[10] GUARDED_BY(mu1);
4186f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  Cell   sc[10] GUARDED_BY(mu1);
418743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
418843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test1() {
418943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Lock();
419043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (a == 0) doSomething();  // OK, we don't dereference.
419143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    a = 0;
419243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    c = 0;
4193f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sa[0] == 42) doSomething();
4194f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sa[0] = 57;
4195f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sc[0].a == 42) doSomething();
4196f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sc[0].a = 57;
419743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
419843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
419943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
420043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test2() {
420143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.ReaderLock();
4202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*a == 0) doSomething();      // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *a = 0;                          // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
420443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c->a == 0) doSomething();    // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c->a = 0;                        // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
420743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*c).a == 0) doSomething();  // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*c).a = 0;                      // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4210f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (a[0] == 42) doSomething();     // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a[0] = 57;                         // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c[0].a == 42) doSomething();   // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c[0].a = 57;                       // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
421543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
421643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
421743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
421843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  void test3() {
421943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Lock();
4220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*a == 0) doSomething();      // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *a = 0;                          // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
422243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c->a == 0) doSomething();    // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c->a = 0;                        // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
422543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*c).a == 0) doSomething();  // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*c).a = 0;                      // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4228f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (a[0] == 42) doSomething();     // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    a[0] = 57;                         // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (c[0].a == 42) doSomething();   // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    c[0].a = 57;                       // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
423343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Unlock();
423443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
423543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
4236f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  void test4() {  // Literal arrays
4237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sa[0] == 42) doSomething();     // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sa[0] = 57;                         // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sc[0].a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sc[0].a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sa == 42) doSomething();       // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sa = 57;                           // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((*sc).a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    (*sc).a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sc->a == 42) doSomething();     // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sc->a = 57;                         // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4248f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  }
4249f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4250f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins  void test5() {
425143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.ReaderLock();    // OK -- correct use.
425243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Lock();
425343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (*a == 0) doSomething();
425443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    *a = 0;
425543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
425643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if (c->a == 0) doSomething();
425743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    c->a = 0;
425843399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
425943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    if ((*c).a == 0) doSomething();
426043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    (*c).a = 0;
426143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu2.Unlock();
426243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins    mu1.Unlock();
426343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
426443399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
426543399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
426643399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
426743399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchinsclass SmartPtr_PtGuardedBy_Test {
42689a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  Mutex mu1;
426943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  Mutex mu2;
42709a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  SmartPtr<int>  sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
42719a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
427243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
42739a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test1() {
42749a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.ReaderLock();
42759a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Lock();
42769a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
42779a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sp.get();
42789a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    if (*sp == 0) doSomething();
42799a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    *sp = 0;
42809a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sq->a = 0;
42819a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
4282f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    if (sp[0] == 0) doSomething();
4283f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins    sp[0] = 0;
4284f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
42859a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Unlock();
42869a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Unlock();
42879a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  }
42889a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
42899a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test2() {
42909a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Lock();
42919a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
4292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp.get();                      // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sp == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sp = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq->a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4296f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sp[0] == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp[0] = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq[0].a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
43019a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43029a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu2.Unlock();
43039a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  }
43049a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43059a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins  void test3() {
43069a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Lock();
43079a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43089a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    sp.get();
4309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (*sp == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    *sp = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq->a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4312f9495911c46a5f90d8cf14774c11ff521d505c7eDeLesley Hutchins
4313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sp[0] == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sp[0] = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sq[0].a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
43179a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins
43189a2f84b2f03e79fb21f9db9e029045fba09dedefDeLesley Hutchins    mu1.Unlock();
431943399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins  }
432043399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins};
432143399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
432243399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins}  // end namespace PtGuardedByTest
432343399fb0e79687043b7904195e95a23e44bd6ca1DeLesley Hutchins
43244444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43254444446abb50f7b0314d82be0afa892f945cc9bcBill Wendlingnamespace NonMemberCalleeICETest {
43264444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43274444446abb50f7b0314d82be0afa892f945cc9bcBill Wendlingclass A {
43284444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling  void Run() {
4329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  (RunHelper)();  // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
43304444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling }
43314444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43324444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling void RunHelper() __attribute__((exclusive_locks_required(M)));
43334444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling Mutex M;
43344444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling};
43354444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
43364444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling}  // end namespace NonMemberCalleeICETest
43374444446abb50f7b0314d82be0afa892f945cc9bcBill Wendling
4338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace pt_guard_attribute_type {
4340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
4341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
4342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void test() {
4344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
4348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
4349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
4350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace pt_guard_attribute_type
4351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace ThreadAttributesOnLambdas {
4354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass Foo {
4356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Mutex mu_;
4357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void test() {
4361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      LockedFunction();
4363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
4366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      LockedFunction();
4367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      mu_.Lock();
4371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
4372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func1();  // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
4374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func2();
4375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    func3();
4376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mu_.Unlock();
4377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
4378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
4379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace ThreadAttributesOnLambdas
4381