warn-thread-safety-analysis.cpp revision 7336b9f8c0b58550a74c85a64f06d0fd74e7ad0d
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_; }
839d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
849d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsprivate:
859d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* ptr_;
869d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
879d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
889d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
89d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing destructor calls and cleanup.
90d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsclass MyString {
91d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinspublic:
92d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  MyString(const char* s);
93d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  ~MyString();
94d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins};
95d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
96d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
97d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
1013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
1023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
1033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
1053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
1073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
1083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
109194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
1107336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins   void MyLock() __attribute__((exclusive_lock_function(mu)));
1113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
1123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
1143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
1163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
1177336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  sls_mw.x = 5;
1183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
1193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
1223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
1243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
1283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
1343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
1403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
1593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
1753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
1813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
1893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
1913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
1953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
1973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
203194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
204194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
205194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
206194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
207194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
2083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2108bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
2143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
2168bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'sls_mu' that is already locked}}
2173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
2212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
2253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2260da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // expected-note{{mutex acquired here}}
2273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2280da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu2.Lock(); // expected-note{{mutex acquired here}}
2290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}  \
2300da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
2313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
2332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
2373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
2393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2402e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2492e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
2502e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{unlocking 'sls_mu' that was not locked}}
2513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
254aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2554e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2592e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
2602e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2632e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
2692e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
2702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
2710da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  do {
2720da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
2780da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // \
2792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
2802e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
2860da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
2870da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2880da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock();
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
2932e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
2940da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2952e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2988bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
301aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
3022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
303aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
304aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
305aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
306aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
3072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
308aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
309aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
310aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
311aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
312aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
313aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
314aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
3353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
3368bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'aa_mu' that was not locked}}
3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
3428bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'aa_mu' that is already locked}}
3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3472e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
3482e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
349b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
350b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
351b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
352b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
353b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
354b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
355b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
356b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
357b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
3582f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
359b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3602f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3612f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
362b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3632f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3642f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
365b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
368b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3692e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
370b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
3712e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
372b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
373b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
37405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
37505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
37605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
37705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
37905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
38305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
38405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
38505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
38605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
38705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
38874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
38974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
39074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
39174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
39274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
39374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
39474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
39505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
39905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
40005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
40105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
40305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
40474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
40505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
406af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
407af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
408af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
409af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
41005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
41505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
43205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
43605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
43774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
44274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
44305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
44605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
44774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
44805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
45105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
45274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
45305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
45605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
45774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
45805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
46105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
46274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
46305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
46605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
46774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
46805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
47105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
47274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
47305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
47605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
47705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
47874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
47905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
48005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
48105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
48205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
48374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
48405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
48574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
48605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
48774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
488a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
48974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
49005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
491b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
492eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
493eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
494eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
495eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
496eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
497eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
498eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
499eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
500eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
501eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
502eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
503eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
504eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
50574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
506eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
50774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading variable 'a' requires locking 'mu'}}
508eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
50974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
510eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
511eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
512eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
513eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
514eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
515eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
516eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
51799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
51899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
51999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
52899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52999107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
53699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
53799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
54499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
54799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
54899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
54999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
55099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
5513f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
5523f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'fooA.mu'}}
55399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
55499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
55599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
55699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
55799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
55899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
55999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
56099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
56199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
562a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
56399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
56499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
56599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
56699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
56799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
56899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
56999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
57099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
57199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
5723f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
5733f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.FooPointer->mu'}}
57499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
57599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
57699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
57899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
57999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
58099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
5813f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
5823f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
58399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
58499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
58699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
58799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
58899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
58999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
5903f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
5913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
59299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
59399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
59499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
595a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
596a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
597a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
598a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
599a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
601a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
602a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
603a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
604a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
605a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
606a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
607a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
608a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
6094e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
61074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
611a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6134e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
6144e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
615a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
617a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
618a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
625a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
626a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
628a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
629a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
632a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
633a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
634a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
635a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
636a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
637a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
638a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
639a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
64074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
641a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
642a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6438bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
644a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
645a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
646a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
647a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6484e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
64974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
650a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
651a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6524e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
6534e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
654a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
655a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
656a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
657a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
658a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
659a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
660a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
66174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
662a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
663a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6648bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
665a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
666a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
667a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
668a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
669a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
670a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
671a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
67274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
673a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
674a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
6758bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
676a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
677a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
678a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
679978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
682978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
683978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
692978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
693978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
697978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
698978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
699978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
700978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
701978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
702978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
703978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
704978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
705978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
706978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
707978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
708978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
709978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
710978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
711978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
712978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
713978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
714978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
715978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
717978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
718978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
734978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
735978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
739978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
740978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
741978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
742978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
743978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
744978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
745978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
746af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
747af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
748af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
749af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
750af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
751af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
752cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
753cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
754cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
755cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
756cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
757cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
758cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
759cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
760cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
761cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
762978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
763978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7648bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
765978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
766978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
767978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
768978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
769978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7708bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
771978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
772978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
773978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
774978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
775978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
7768bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
777978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
778978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
779978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
780978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7818bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
782978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
783978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
784978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
785978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
7868bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
787978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
788978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
789978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
790978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
791978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7928bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
793978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
794978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
795978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
796978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
797978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
798978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
79974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
800978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
801978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
802978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
803978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
804978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
805978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
80674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
807978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
808978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
809194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8108121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
811194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
812194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
813194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
814194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
816194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
108923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
109423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1202e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 5;
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1216e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie    g = 2;
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
1225a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
1231a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1234e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 2;
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1245988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
12593f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b2->a_ = 3; // \
12603f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
12613f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b1->mu1_'}}
1262988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
1290a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
12913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
12923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
129374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
129474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
129574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
12963f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
12973f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
129874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
130074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
130174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
13223f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->bar(7); // \
13233f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
13243f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
13253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->a_ = 5; // \
13263f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
13273f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
1364a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1369988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
140374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
140474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1412a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
1413a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins             // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1436a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1438a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1441a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1443a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
1444988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1445988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1446988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1447988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1448988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1449988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1450988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1451988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1452988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1453988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1454988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1455988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1456988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1457988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1458988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1459988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1460988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1461988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1462988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1463988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1464988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1465988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1466988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1467988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1468988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1469988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1470a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
1471988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1472a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
1473988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1474988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1475988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1476988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1477988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14788121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14798121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14818121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14828121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14835696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)));
14845696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)));
14858121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14878121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14888121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14925696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
14935696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
14948121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14968121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14978121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14988121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14998121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
15008121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15018121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
15028121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
15038121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15048121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
15058121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15068121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15078121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
15088121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15098121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
15108121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15118121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
15128121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15138121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15148121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
15158121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
15178121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
1518a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins        // expected-warning {{unlocking 'd2->mu' that was not locked}}
1519a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
15208121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15218121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
15228121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15238121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
15248121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
15253f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
15263f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-note {{found near match 'd1->mu'}}
15278121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
15288121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15298121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15308121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
15318121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1532e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1533f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1534e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1535e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1536e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1537e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1538e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1539e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1540e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1541e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1542e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1543e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1544e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15456db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1546e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1547e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1548e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1549e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1550f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1552f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
155497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
155597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
155697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
155797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1558a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1559a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1560a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1561a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1562a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1563a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
156497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
156597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
156697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
156797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1568a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1569a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
157097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
157197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
157297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1573f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
157497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1575601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1576601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1577601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1578601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1579601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1580601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1581601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1582601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1583601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1584601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1585a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
1586601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1587601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1588601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1589601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
159097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15911fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
16151fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
16161fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16171fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16181fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16191fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16201fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16211fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
16221fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
1623c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
16241fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16251fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16261fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16271fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16281fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16291fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16301fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16311fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16321fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16331fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16341fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1635df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1637df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1638df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1639df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1640df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1641df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1642df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1643df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1644df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1645df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1646df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1647df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1648a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
1649df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1650df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1651df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1652df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1653df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1654df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1655df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1656df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
165760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchinsnamespace TryLockTest {
165860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
172343e3deeabf3ca02da427b63df8604e2daf86e8a3Sylvestre Ledru    if (b) {    // b should be unknown at this point, because of the join point
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1737b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1738b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1739b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1740b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1741b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1742b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1743b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1744b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1745b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1746b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1747b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1748b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1749b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1750b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1751b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1752b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1753b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1754b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
175560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
175660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of exclusive trylock
175760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo11() {
175860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
175960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.TryLock())
176060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
176160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
176260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
176360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.Lock();
176460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
176560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   a = 10;
176660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
176760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
176860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
176960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of shared trylock
177060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo12() {
177160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
177260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.ReaderTryLock())
177360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
177460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
177660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.ReaderLock();
177760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   int i = a;
177960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
178060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
1781b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1782b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
178360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins} // end namespace TrylockTest
178460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1785b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
18197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
18437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
18467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
18477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
184823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18783f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
18793f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bt.fooBase.mu_'}}
18807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
1887a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
18887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
188923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
189023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
189123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
189223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
189323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
189623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
189723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
189823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
189923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1900dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
190123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
190323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
190423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
190523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
190723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
190823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
190923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
19107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
191123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
191223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
191323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
191423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
191523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
191623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
191723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1918dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
191923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
192023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
192223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
192323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
192423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
192523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
192623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
192723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
192923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
193023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
193123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
193223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
19337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
19347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
19367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1938e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1939e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1940e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1941e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1942e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1943e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1944e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1945e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1946e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1947e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1948e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1949e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1950e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1951e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1952e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1953e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1954e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1955e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1956a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
1957e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1958e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1959e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1960e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1961e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1962e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19632e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19642e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19682e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19692e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19712e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19722e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19732e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19742e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19772e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19782e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19802e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19822e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19832e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19842e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19862e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19872e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19882e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19892e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19912e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2052c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2054c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2055c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2056c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2057c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2058c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2059c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2060c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2061c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2063c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2064c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2065c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2066c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2067c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2068c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2069c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2070c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2071a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
2072c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2073a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
2074c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2075a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
2076c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2077a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);  // \
2078a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
2079c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2080c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2081a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
2082c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2083a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
2084c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2085a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
2086c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2087c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2088c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2089c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2090c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2091c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2092a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);
2093c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2094c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2095c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2096c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2097c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2098c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2099c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2100c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2101a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
2102c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2103c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21044bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
21054bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21064bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21074bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
21084bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21094bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
21104bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
21114bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
21124bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21134bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
21144bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
21154bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21164bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
21174bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
21184bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
21194bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
21204bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
21214bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
21224bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21234bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
21244bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
21254bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
21264bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21274bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
21284bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
21294bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
21304bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2131c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2132c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21332f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21342f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
21352f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
21362f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
21372f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
21382f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21392f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
21402f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
21412f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
21422f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21432f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
21442f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
21452f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
21462f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
21472f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21482f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21494bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21504bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21514bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2152d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2153d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2154d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2155d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2156d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2157d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2158d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2159d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2160d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2161d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2162d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2163d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2164d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2165d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
21662a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21672a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
21682a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21692a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
21702a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
21712a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21722a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
21732a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21742a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
21752a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
21762a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
21772a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
21782a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
21792a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
21802a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
21812a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21822287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
21832287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21842287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21852287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
21862287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21872287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
21882287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
21892287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
21902287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
21912287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21922287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
21932287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
21942287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
21952287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
21962287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
21972287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
21982287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
21992287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
22002287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22012287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
22022287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
22032a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
22042287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22052287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
22062287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22077ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22087ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
22097ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22107ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
22117ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
22127ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
22137ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
22147ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
22157ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
22167ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22177ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
22187ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22197ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22200d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
22220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
22240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
22260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
22270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
22300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
22330d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22340d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
22350d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
22360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
22370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
22390d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
22420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22430d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
22440d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
22450d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
22460d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
22470d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
22480d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22490d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
22500d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22550d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
22560d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22570d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
22580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
22610d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22620d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22630d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
22650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22670d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22680d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
22690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
22720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
22730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
22740d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22750d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
22760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
22770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
22780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22800d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
22810d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
22853f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
22863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo().mu_'}}
22870d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22880d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22890d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22900d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
22913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
22923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
22930d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
22973f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
22983f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'bar.getFoo3(a,b).mu_'}}
22990d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
23000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
23020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
23033f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
23043f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'getBarFoo(bar,a).mu_'}}
23050d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
23060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
23080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
23093f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
23103f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
23110d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
23120d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
23130d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23140d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23150da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace MoreLockExpressions
23160da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23170da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23180da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsnamespace TrylockJoinPoint {
23190da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23200da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsclass Foo {
23210da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  Mutex mu;
23220da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  bool c;
23230da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23240da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  void foo() {
23250da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    if (c) {
23260da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      if (!mu.TryLock())
23270da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins        return;
23280da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    } else {
23290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      mu.Lock();
23300da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    }
23310da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    mu.Unlock();
23320da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  }
23330da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins};
23340da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23350da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace TrylockJoinPoint
23360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2338f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsnamespace LockReturned {
2339f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2340f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Foo {
2341f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2342f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int a             GUARDED_BY(mu_);
2343f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);
2344f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2345f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2346f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2347f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2348f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex* getMu() LOCK_RETURNED(mu_);
2349f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2350f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex mu_;
2351f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2352f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2353f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2354f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2355f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2356f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Calls getMu() directly to lock and unlock
2357f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test1(Foo* f1, Foo* f2) {
2358a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
2359a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
2360f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2361a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
2362a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
2363a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
2364f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2365f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Lock();
2366f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2367f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->a = 0;
2368f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo();
23693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  f1->foo2(f2); // \
23703f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
23713f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'f1->mu_'}}
2372f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2373f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Lock();
2374f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo2(f2);
2375f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Unlock();
2376f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2377f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::sfoo(f1);
2378f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2379f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Unlock();
2380f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2381f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2382f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2383f63797c741e646b9482d204c88dee02fb41d7962DeLesley HutchinsMutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2384f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2385f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Bar : public Foo {
2386f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2387f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int  b            GUARDED_BY(getMu());
2388f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());
2389f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2390f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2391f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2392f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2393f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2394f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2395f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2396f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2397f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Use getMu() within other attributes.
2398f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// This requires at lest levels of substitution, more in the case of
2399f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test2(Bar* b1, Bar* b2) {
2400a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
2401a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
2402a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
2403a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
2404a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
2405a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
2406f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2407f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Lock();
2408f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2409f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2410f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
24113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b1->bar2(b2);  // \
24123f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
24133f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // // expected-note {{found near match 'b1->mu_'}}
2414f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2415f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Lock();
2416f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2417f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2418f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Unlock();
2419f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2420f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2421f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2422f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2423f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Unlock();
2424f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2425f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2426f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2427f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Sanity check -- lock the mutex directly, but use attributes that call getMu()
2428f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Also lock the mutex using getFooMu, which calls a lock_returned function.
2429f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test3(Bar* b1, Bar* b2) {
2430f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Lock();
2431f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2432f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
2433f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2434f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Lock();
2435f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2436f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Unlock();
2437f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2438f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2439f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2440f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2441f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Unlock();
2442f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2443f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2444f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins} // end namespace LockReturned
2445f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2446f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2447c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsnamespace ReleasableScopedLock {
2448c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2449c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass Foo {
2450c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  Mutex mu_;
2451c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  bool c;
2452c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  int a GUARDED_BY(mu_);
2453c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2454c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test1();
2455c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test2();
2456c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test3();
24575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test4();
24585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test5();
2459c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
2460c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2461c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2462c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test1() {
2463c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2464c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2465c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2466c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2467c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test2() {
2468c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2469c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  if (c) {            // test join point -- held/not held during release
2470c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins    rlock.Release();
2471c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
2472c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2473c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2474c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test3() {
2475c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2476c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 0;
2477c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2478c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 1;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2479c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2480c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
24815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test4() {
24825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();
24845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test5() {
24885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  if (c) {
24905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    rlock.Release();
24915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  }
24925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  // no warning on join point for managed lock.
24935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2497c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins} // end namespace ReleasableScopedLock
2498c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2499c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
250076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsnamespace TrylockFunctionTest {
250176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsclass Foo {
250376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinspublic:
250476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu1_;
250576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu2_;
250676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool c;
250776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
250976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins};
251076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsbool Foo::lockBoth() {
251276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!mu1_.TryLock())
251376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
251476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  mu2_.Lock();
251676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!c) {
251776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu1_.Unlock();
251876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu2_.Unlock();
251976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
252076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  }
252176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  return true;
252376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}
252476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}  // end namespace TrylockFunctionTest
2527c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2528c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2529c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2530c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsnamespace DoubleLockBug {
2531c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2532c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsclass Foo {
2533c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinspublic:
2534c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  Mutex mu_;
2535c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  int a GUARDED_BY(mu_);
2536c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
25385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int  foo2() SHARED_LOCKS_REQUIRED(mu_);
2539c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins};
2540c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2541c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2543c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  a = 0;
2544c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins}
2545c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
25475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return a;
25485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2552c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2553c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2554879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsnamespace UnlockBug {
2555c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2556879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsclass Foo {
2557879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinspublic:
2558879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  Mutex mutex_;
2559879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2560879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
2561879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2562879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2563879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2564879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2565879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
2566879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2567879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2568879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins};
2569879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2570879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins} // end namespace UnlockBug
2571c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2572c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
25735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2574bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsnamespace FoolishScopedLockableBug {
2575bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2576bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass SCOPED_LOCKABLE WTF_ScopedLockable {
2577bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinspublic:
2578bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2579bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2580bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  // have to call release() manually;
2581bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  ~WTF_ScopedLockable();
2582bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2583bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void release() UNLOCK_FUNCTION();
2584bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2585bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2586bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2587bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass Foo {
2588bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  Mutex mu_;
2589bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  int a GUARDED_BY(mu_);
2590bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  bool c;
2591bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2592bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void doSomething();
2593bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2594bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test1() {
2595bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);
2596bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    wtf.release();
2597bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2598bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2599bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test2() {
2600bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2601bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
2602bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2603bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test3() {
2604bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2605bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2606bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2607bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2608bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2609bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2610bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test4() {
2611bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2612bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2613bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2614bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2615bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2616bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2617bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2618bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2619bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2620bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test5() {
2621bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2622bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2623bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2624bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2625bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2626bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test6() {
2627bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2628bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2629bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2630bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2631bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2632bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2633bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2634bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2635bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2636bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2637bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins} // end namespace FoolishScopedLockableBug
2638bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
26399d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26419d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsnamespace TemporaryCleanupExpr {
26429d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26439d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass Foo {
26449d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  int a GUARDED_BY(getMutexPtr().get());
26459d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26469d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr<Mutex> getMutexPtr();
26479d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26489d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  void test();
26499d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
26509d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26519d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26529d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsvoid Foo::test() {
26539d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  {
26549d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    ReaderMutexLock lock(getMutexPtr().get());
26559d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    int b = a;
265696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
2657a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
26589d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins}
26599d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26609d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins} // end namespace TemporaryCleanupExpr
26619d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26629d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
266396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsnamespace SmartPointerTests {
266596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Foo {
266796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinspublic:
266896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Mutex> mu_;
266996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int a GUARDED_BY(mu_);
267096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int b GUARDED_BY(mu_.get());
267196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int c GUARDED_BY(*mu_);
267296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);
267496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Unlock() UNLOCK_FUNCTION(mu_);
267596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
267796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
267896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
267996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
268096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test4();
268196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test5();
268296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test6();
268396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test7();
268496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test8();
268596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
268696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test0() {
268896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
268996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;  // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
269096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;  // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
269196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
269296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test1() {
269496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
269596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
269696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
269796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
269896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Unlock();
269996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test2() {
270296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();
270396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
270496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
270596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
270696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Unlock();
270796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test3() {
271196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();
271296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
271396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
271496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
271596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
271696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
271796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test4() {
272096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(mu_.get());
272196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
272296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
272396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
272496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
272596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test5() {
272896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(&(*mu_));
272996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
273096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
273196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
273296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
273396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test6() {
273696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Lock();
273796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
273896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
273996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
274096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();
274196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
274296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test7() {
274596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
274696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Lock();
274796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
274896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
274996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
275196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Unlock();
275296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
275596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
275696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
275996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Unlock();
276096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
276296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
276396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Unlock();
276496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
276696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Lock();
276796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
276896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test8() {
277396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
277496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();    // expected-warning {{locking 'mu_' that is already locked}}
277596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();        // expected-warning {{locking 'mu_' that is already locked}}
277696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
277796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();             // expected-warning {{unlocking 'mu_' that was not locked}}
277896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Bar {
278296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Foo> foo;
278396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
278596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
278696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
278796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
278896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
278996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test0() {
2792a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
2793a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
2794a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
279596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
279696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test1() {
279996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Lock();
280096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
280196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
280296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
280396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Unlock();
280496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
280596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test2() {
280896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).mu_->Lock();
280996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
281096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
281196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
281296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->mu_->Unlock();
281396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
281496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test3() {
281796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(foo->mu_.get());
281896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
281996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
282096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
282196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
282296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}  // end namespace SmartPointerTests
282496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
28275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsnamespace DuplicateAttributeTest {
28285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsclass LOCKABLE Foo {
28305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinspublic:
28315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu1_;
28325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu2_;
28335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu3_;
28345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int a GUARDED_BY(mu1_);
28355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int b GUARDED_BY(mu2_);
28365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int c GUARDED_BY(mu3_);
28375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
28395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
28405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);
28425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void slock1() SHARED_LOCK_FUNCTION(mu1_);
28435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void locklots()
28455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_)
28465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_)
28475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock1() UNLOCK_FUNCTION(mu1_);
28505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlocklots()
28525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_)
28535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_)
28545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins};
28565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }
28595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock() UNLOCK_FUNCTION()         { }
28605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {
28625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
28665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  mu1_.ReaderLock();
28675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
28705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::locklots()
28765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
28775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
28785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
28845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
28885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlocklots()
28945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_)
28955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_, mu3_) {
28965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test0() {
29035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();     // expected-warning {{locking 'foo' that is already locked}}
29095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();   // expected-warning {{unlocking 'foo' that was not locked}}
29115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test1() {
29155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
29175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
2921a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.lock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
29225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2924a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();  // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
29255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint test2() {
29295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
29315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d1 = foo.a;
29325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
2935a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.slock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
29365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d2 = foo.a;
29375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2938a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();   // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
29395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return d1 + d2;
29405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test3() {
29445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3(); // \
2953a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2954a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2955a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu3_' that is already locked}}
29565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3(); // \
2961a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2962a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2963a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
29645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid testlots() {
29685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots(); // \
2977a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2978a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2979a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu3_' that is already locked}}
29805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots(); // \
2985a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2986a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2987a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
29885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}  // end namespace DuplicateAttributeTest
29915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
299413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsnamespace TryLockEqTest {
299513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsclass Foo {
299713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex mu_;
299813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int a GUARDED_BY(mu_);
299913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  bool c;
300013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
300213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
300313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_);
300413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test1();
300613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test2();
300713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins};
300813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test1() {
301113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == 0) {
301213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
301313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
301413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
301513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
301613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
301713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() != 0) {
301913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 != tryLockMutexP()) {
302413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(tryLockMutexP() == 0)) {
302913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
303013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
303113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
303313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 0) {
303413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
303513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
303613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
303813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
303913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 == tryLockMutexI()) {
304113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
304213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
304313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
304413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
304513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
304613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 1) {
304813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
304913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
305013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == false) {
305313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
305413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
305513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
305713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
305813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == true) {
306013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
306113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
306213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else {
306413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
306513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#if __has_feature(cxx_nullptr)
306813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == nullptr) {
306913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
307013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
307113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
307213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
307313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
307413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#endif
307513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
307613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins} // end namespace TryLockEqTest
30785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
307996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
3080ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsnamespace ExistentialPatternMatching {
3081ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3082ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Graph {
3083ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3084ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Mutex mu_;
3085ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3086ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3087ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3088ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3089ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3090ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Node {
3091ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3092ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  int a GUARDED_BY(&Graph::mu_);
3093ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3094ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3095ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins    a = 0;
3096ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  }
3097ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3098ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3099ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3100ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid test() {
3101ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g1;
3102ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g2;
3103ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Node n1;
3104ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3105ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;   // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3106ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();   // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
3107ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();
3108ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3109ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();
3110ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3111ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3112ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3113ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3114ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3115ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Lock();
3116ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3117ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3118ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3119ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3120ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3121ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3122ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3123ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3124ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3125ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  UnlockAllGraphs();
3126ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3127ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3128ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3129ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3130ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3131ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3132ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3133ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3134ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();  // expected-warning {{locking 'g1.mu_' that is already locked}}
3135ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3136ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins}
3137ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3138ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins} // end namespace ExistentialPatternMatching
3139ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
31404e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31414e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsnamespace StringIgnoreTest {
31424e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31434e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Foo {
31444e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31454e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  Mutex mu_;
31464e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION("");
31474e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION("");
31484e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void goober() EXCLUSIVE_LOCKS_REQUIRED("");
31494e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void roober() SHARED_LOCKS_REQUIRED("");
31504e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31514e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31524e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31534e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Bar : public Foo {
31544e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31554e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void bar(Foo* f) {
31564e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->unlock();
31574e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->goober();
31584e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->roober();
31594e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->lock();
31604e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  };
31614e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31624e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31634e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins} // end namespace StringIgnoreTest
31644e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31654e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31665408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsnamespace LockReturnedScopeFix {
31675408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31685408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsclass Base {
31695408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsprotected:
31705408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  struct Inner;
31715408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  bool c;
31725408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31735408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  const Mutex& getLock(const Inner* i);
31745408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31755408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
31765408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
31775408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
31785408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31795408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void bar(Inner* i);
31805408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31815408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31825408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31835408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsstruct Base::Inner {
31845408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  Mutex lock_;
31855408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
31865408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31875408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31885408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31895408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsconst Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
31905408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  return i->lock_;
31915408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
31925408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31935408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31945408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::foo(Inner* i) {
31955408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  i->doSomething();
31965408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
31975408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31985408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::bar(Inner* i) {
31995408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  if (c) {
32005408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Lock();
32015408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    unlockInner(i);
32025408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32035408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  else {
32045408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    lockInner(i);
32055408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Unlock();
32065408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32075408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32085408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32095408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins} // end namespace LockReturnedScopeFix
32105408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
3211fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3212fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsnamespace TrylockWithCleanups {
3213fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3214fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstruct Foo {
3215fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Mutex mu_;
3216fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a GUARDED_BY(mu_);
3217fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3218fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3219fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley HutchinsFoo* GetAndLockFoo(const MyString& s)
3220fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3221fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3222fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstatic void test() {
3223fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Foo* lt = GetAndLockFoo("foo");
3224fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  if (!lt) return;
3225fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a = lt->a;
3226fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  lt->mu_.Unlock();
3227fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3228fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
322924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TrylockWithCleanups
3230fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3231fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
32320b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsnamespace UniversalLock {
32330b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32340b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsclass Foo {
32350b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  Mutex mu_;
32360b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  bool c;
32370b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32380b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  int a        GUARDED_BY(mu_);
32390b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void r_foo() SHARED_LOCKS_REQUIRED(mu_);
32400b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
32410b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32420b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test1() {
32430b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    int b;
32440b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32450b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnReads();
32460b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    b = a;
32470b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    r_foo();
32480b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnReads();
32490b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32500b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32510b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32520b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    w_foo();
32530b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32540b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32550b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32560b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // don't warn on joins with universal lock
32570b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test2() {
32580b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32590b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32600b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32610b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0; // \
32620b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
32630b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();  // \
32640b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{unlocking '*' that was not locked}}
32650b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32670b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32680b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // make sure the universal lock joins properly
32690b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test3() {
32700b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32710b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32720b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32730b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32740b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    else {
32750b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32760b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32770b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32780b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32790b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32800b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32810b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32820b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32830b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32840b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // combine universal lock with other locks
32850b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test4() {
32860b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32870b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32880b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32890b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32900b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32910b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32920b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32930b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32940b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32950b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32960b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
32970b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32980b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32990b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33000b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33010b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins};
33020b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
330324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace UniversalLock
330424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsnamespace TemplateLockReturned {
330724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
330824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinstemplate<class T>
330924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass BaseT {
331024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
331124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  virtual void baseMethod() = 0;
331224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
331324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
331424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex mutex_;
331524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  int a GUARDED_BY(mutex_);
331624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
331724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
331824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
331924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass Derived : public BaseT<int> {
332024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
332124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
332224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins    a = 0;
332324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  }
332424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
332524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
332624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TemplateLockReturned
332724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
332824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
3329f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsnamespace ExprMatchingBugFix {
3330f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3331f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Foo {
3332f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3333f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Mutex mu_;
3334f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3335f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3336f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3337f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Bar {
3338f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3339f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  bool c;
3340f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Foo* foo;
3341f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Bar(Foo* f) : foo(f) { }
3342f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3343f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  struct Nested {
3344f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Foo* foo;
3345f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested(Foo* f) : foo(f) { }
3346f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3347f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3348f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  };
3349f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3350f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  void test();
3351f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3352f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3353f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3354f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsvoid Bar::test() {
3355f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  foo->mu_.Lock();
3356f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  if (c) {
3357f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested *n = new Nested(foo);
3358f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    n->unlockFoo();
3359f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3360f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  else {
3361f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    foo->mu_.Unlock();
3362f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3363f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}
3364f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3365f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}; // end namespace ExprMatchingBugfix
3366f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3367f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
33685b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsnamespace ComplexNameTest {
3369f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
33705b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Foo {
33715b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
33725b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
33735b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33745b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_)  { }
33755b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
33765b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33775b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
33785b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
33795b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33805b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Bar {
33815b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
33825b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
33835b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33845b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar()  LOCKS_EXCLUDED(mu_) { }
33855b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Bar() LOCKS_EXCLUDED(mu_) { }
33865b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33875b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
33885b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
33895b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33905b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33915b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test1() {
33925b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo f;           // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
33935b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int a = f[0];    // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
33945b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}                  // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
33955b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33965b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
33975b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test2() {
33985b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Lock();
33995b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  {
34005b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
34015b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
34025b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
34035b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Unlock();
34045b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}
34055b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34065b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};  // end namespace ComplexNameTest
34072a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34082a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34092a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsnamespace UnreachableExitTest {
34102a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34112a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsclass FemmeFatale {
34122a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinspublic:
34132a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale();
34142a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  ~FemmeFatale() __attribute__((noreturn));
34152a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins};
34162a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34172a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid exitNow() __attribute__((noreturn));
3418d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid exitDestruct(const MyString& ms) __attribute__((noreturn));
34192a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34202a237e03c407ff55bd8639b18658a8751955f1dbDeLesley HutchinsMutex fatalmu_;
34212a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34222a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34232a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  exitNow();
34242a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34252a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34262a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34272a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale femme;
34282a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34292a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34302a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsbool c;
34312a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34322a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34332a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  if (c) {
34342a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    exitNow();
34352a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34362a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  else {
34372a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    FemmeFatale femme;
34382a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34392a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34402a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
3441d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3442d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  exitDestruct("foo");
3443d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins}
3444d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
34452a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}   // end namespace UnreachableExitTest
3446186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3447186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3448186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsnamespace VirtualMethodCanonicalizationTest {
3449186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3450186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base {
3451186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3452186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  virtual Mutex* getMutex() = 0;
3453186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3454186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3455186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base2 : public Base {
3456186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3457186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3458186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3459186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3460186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base3 : public Base2 {
3461186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3462186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3463186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3464186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3465186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Derived : public Base3 {
3466186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3467186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();  // overrides Base::getMutex()
3468186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3469186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3470186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3471186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3472186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3473186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  baseFun(d);
3474186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}
3475186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3476186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}  // end namespace VirtualMethodCanonicalizationTest
3477186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3478d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3479d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsnamespace TemplateFunctionParamRemapTest {
3480d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3481d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate <class T>
3482d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsstruct Cell {
3483d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  T dummy_;
3484d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Mutex* mu_;
3485d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3486d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3487d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass Foo {
3488d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3489d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  template <class T>
3490d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3491d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3492d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void test();
3493d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3494d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3495d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3496d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::elr(Cell<T>* c1) { }
3497d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3498d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::test() {
3499d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3500d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  elr(&cell); // \
3501d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3502d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3503d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3504d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3505d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3506d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3507d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3508d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3509d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c1) { }
3510d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3511d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest() {
3512d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3513d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR(&cell); // \
3514d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
3515d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3516d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3517d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3518d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3519d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3520d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3521d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// second declaration
3522d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3523d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c2);
3524d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3525d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3526d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c3) { }
3527d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3528d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// re-declaration after definition
3529d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3530d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c4);
3531d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3532d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest2() {
3533d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3534d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR2(&cell); // \
3535d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
3536d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3537d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3538d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3539d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3540d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass FooT {
3541d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3542d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3543d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3544d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3545d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3546d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid FooT<T>::elr(Cell<T>* c1) { }
3547d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3548d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid testFooT() {
3549d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3550d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  FooT<int> foo;
3551d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  foo.elr(&cell); // \
3552d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3553d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3554d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3555d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}  // end namespace TemplateFunctionParamRemapTest
3556d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3557ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3558ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsnamespace SelfConstructorTest {
3559ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3560ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass SelfLock {
3561ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3562ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock()  EXCLUSIVE_LOCK_FUNCTION(mu_);
3563ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock() UNLOCK_FUNCTION(mu_);
3564ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3565ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3566ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3567ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  Mutex mu_;
3568ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3569ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3570ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass LOCKABLE SelfLock2 {
3571ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3572ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2()  EXCLUSIVE_LOCK_FUNCTION();
3573ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock2() UNLOCK_FUNCTION();
3574ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3575ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3576ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3577ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3578ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3579ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test() {
3580ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock s;
3581ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s.foo();
3582ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3583ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3584ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test2() {
3585ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2 s2;
3586ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s2.foo();
3587ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3588ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3589ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}  // end namespace SelfConstructorTest
3590ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
35913ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
35923ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsnamespace MultipleAttributeTest {
35933ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
35943ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsclass Foo {
35953ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu1_;
35963ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu2_;
35973ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  a GUARDED_BY(mu1_);
35983ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  b GUARDED_BY(mu2_);
35993ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  c GUARDED_BY(mu1_)    GUARDED_BY(mu2_);
36003ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
36013ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36023ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo1()          EXCLUSIVE_LOCKS_REQUIRED(mu1_)
36033ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCKS_REQUIRED(mu2_);
36043ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo2()          SHARED_LOCKS_REQUIRED(mu1_)
36053ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_LOCKS_REQUIRED(mu2_);
36063ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo3()          LOCKS_EXCLUDED(mu1_)
36073ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       LOCKS_EXCLUDED(mu2_);
36083ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void lock()          EXCLUSIVE_LOCK_FUNCTION(mu1_)
36093ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCK_FUNCTION(mu2_);
36105696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerlock()    SHARED_LOCK_FUNCTION(mu1_)
36115696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins                       SHARED_LOCK_FUNCTION(mu2_);
36123ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void unlock()        UNLOCK_FUNCTION(mu1_)
36133ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       UNLOCK_FUNCTION(mu2_);
36143ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool trylock()       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
36153ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
36163ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
36173ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_TRYLOCK_FUNCTION(true, mu2_);
36183ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36193ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void test();
36203ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins};
36213ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36223ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36233ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo1() {
36243ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 1;
36253ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 2;
36263ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36273ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36283ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo2() {
36293ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int result = a + b;
36303ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36313ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36323ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo3() { }
36335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::lock() { mu1_.Lock();  mu2_.Lock(); }
36345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::readerlock() { mu1_.ReaderLock();  mu2_.ReaderLock(); }
36355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::unlock() { mu1_.Unlock();  mu2_.Unlock(); }
36363ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::trylock()       { return true; }
36373ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::readertrylock() { return true; }
36383ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36393ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36403ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::test() {
36413ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Lock();
36423ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo1();             // expected-warning {{}}
36433ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  c = 0;              // expected-warning {{}}
36443ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  *d = 0;             // expected-warning {{}}
36453ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36463ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36473ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.ReaderLock();
36483ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo2();             // expected-warning {{}}
36493ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int x = c;          // expected-warning {{}}
36503ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int y = *d;         // expected-warning {{}}
36513ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36523ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36533ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Lock();
36543ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo3();             // expected-warning {{}}
36553ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Unlock();
36563ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36573ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  lock();
36583ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 0;
36593ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 0;
36603ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36613ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36623ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  readerlock();
36633ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int z = a + b;
36643ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36653ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36663ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (trylock()) {
36673ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    a = 0;
36683ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    b = 0;
36693ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
36703ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
36713ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36723ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (readertrylock()) {
36733ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    int zz = a + b;
36743ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
36753ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
36763ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36773ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36783ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36793ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}  // end namespace MultipleAttributeTest
36803ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36813ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
368291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsnamespace GuardedNonPrimitiveTypeTest {
368391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
368491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
368591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Data {
368691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
368791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data(int i) : dat(i) { }
368891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
368991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  getValue() const { return dat; }
369091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void setValue(int i)  { dat = i; }
369191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
369291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  operator[](int i) const { return dat; }
369391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int& operator[](int i)       { return dat; }
369491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
369591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void operator()() { }
369691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
369791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
369891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int dat;
369991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
370091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
370191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
370291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass DataCell {
370391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
370491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  DataCell(const Data& d) : dat(d) { }
370591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
370691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
370791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data dat;
370891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
370991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsvoid showDataCell(const DataCell& dc);
371291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Foo {
371591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
371691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // method call tests
371791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test() {
371891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(0);         // FIXME -- should be writing \
371991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
372091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_.getValue();  // \
372191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
372291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);      // FIXME -- should be writing \
372491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
372591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();   // \
372691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
372791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(0);      // FIXME -- should be writing \
372991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
373091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();   // \
373191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
373291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_).setValue(0);    // FIXME -- should be writing \
373491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
373591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = (*datap2_).getValue(); // \
373691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
373791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Lock();
373991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(1);
374091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(1);
374191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(1);
374291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
374391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.ReaderLock();
374591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = data_.getValue();
374691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);  // reads datap1_, writes *datap1_
374791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();
374891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();
374991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
375091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
375191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
375291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // operator tests
375391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test2() {
375491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
375591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
375691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
375791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
375891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
375991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
376091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
376191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
376291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
376391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
376591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
376691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_();              // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
376891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
376991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // const operator tests
377191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test3() const {
377291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
377391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //FIXME
377591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
377691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
377791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_[0];       // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
377991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
378091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
378291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Mutex mu_;
378391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data  data_   GUARDED_BY(mu_);
378491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap1_ GUARDED_BY(mu_);
378591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap2_ PT_GUARDED_BY(mu_);
378691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
378791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins}  // end namespace GuardedNonPrimitiveTypeTest
378991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
379193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsnamespace GuardedNonPrimitive_MemberAccess {
379293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
379393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Cell {
379493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
379593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell(int i);
379693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
379793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void cellMethod();
379893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
379993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int a;
380093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
380193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
380293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
380393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Foo {
380493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
380593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int   a;
380693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell  c  GUARDED_BY(cell_mu_);
380793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell* cp PT_GUARDED_BY(cell_mu_);
380893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
380993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void myMethod();
381093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex cell_mu_;
381293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
381393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
381593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Bar {
381693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsprivate:
381793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex mu_;
381893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo  foo  GUARDED_BY(mu_);
381993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo* foop PT_GUARDED_BY(mu_);
382093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void test() {
382293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.myMethod();      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
382393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
382593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
382693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
382893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
382993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
383193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
383293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
383493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                         // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
383593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
383693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                         // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
383793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
383993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                           // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
384093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
384193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                           // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
384293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
384493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                             // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
384593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
384693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                             // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
384793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  };
384893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
384993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
385093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins}  // namespace GuardedNonPrimitive_MemberAccess
385193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
38520ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38530ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsnamespace TestThrowExpr {
38540ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38550ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsclass Foo {
38560ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  Mutex mu_;
38570ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38580ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  bool hasError();
38590ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38600ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  void test() {
38610ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Lock();
38620ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    if (hasError()) {
38630ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins      throw "ugly";
38640ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    }
38650ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Unlock();
38660ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  }
38670ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins};
38680ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38690ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins}  // end namespace TestThrowExpr
38700ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38710ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
3872ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsnamespace UnevaluatedContextTest {
3873ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3874ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins// parse attribute expressions in an unevaluated context.
3875ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3876ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex1();
3877ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex2();
3878ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3879ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3880ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3881ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3882ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3883ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins}  // end namespace UnevaluatedContextTest
3884ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
38855696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
38865696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsnamespace LockUnlockFunctionTest {
38875696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
38885696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins// Check built-in lock functions
38895696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass LOCKABLE MyLockable  {
38905696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
38915696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock()       EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
38925696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION()    { mu_.ReaderLock(); }
38935696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock()     UNLOCK_FUNCTION()         { mu_.Unlock(); }
38945696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
38955696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
38965696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
38975696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
38985696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
38995696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39005696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass Foo {
39015696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39025696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Correct lock/unlock functions
39035696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
39045696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Lock();
39055696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39065696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39075696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION(mu_) {
39085696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.ReaderLock();
39095696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39105696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39115696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_) {
39125696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Unlock();
39135696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39145696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39155696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check failure to lock.
39165696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}
39175696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39185696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39195696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
39205696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39215696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39225696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39235696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39245696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
39255696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39265696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39275696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39285696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
39305696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39315696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check locking the wrong thing.
39325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();            // expected-note {{mutex acquired here}}
39345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
39355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
39365696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39375696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39385696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39395696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.ReaderLock();      // expected-note {{mutex acquired here}}
39405696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
39415696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
39425696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39435696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39445696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39455696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();  // expected-warning {{unlocking 'mu2_' that was not locked}}
39465696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
39475696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39485696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39495696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39505696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu2_;
39515696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39525696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39535696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins}  // end namespace LockUnlockFunctionTest
39545696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39555c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39565c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsnamespace AssertHeldTest {
39575c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39585c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinsclass Foo {
39595c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchinspublic:
39605c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int c;
39615c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  int a GUARDED_BY(mu_);
39625c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  Mutex mu_;
39635c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39645c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test1() {
39655c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
39665c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
39675c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
39685c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39695c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39705c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test2() {
39715c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertReaderHeld();
39725c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
39735c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
39745c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39755c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39765c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test3() {
39775c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
39785c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
39795c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
39805c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
39815c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
39825c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
39835c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
39845c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
39855c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39865c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39875c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
39885c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
39895c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
39905c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
39915c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39925c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39935c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test5() UNLOCK_FUNCTION(mu_) {
39945c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
39955c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
39965c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
39975c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
39985c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test6() {
39995c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.AssertHeld();
40005c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40015c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }  // should this be a warning?
40025c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40035c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test7() {
40045c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40055c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40065c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40075c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40085c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40095c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40105c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40115c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40125c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40135c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40145c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40155c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test8() {
40165c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40175c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();
40185c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40195c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40205c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40215c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40225c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40235c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40245c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    mu_.Unlock();
40255c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40265c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40275c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test9() {
40285c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40295c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40305c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40315c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40325c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
40335c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40345c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
40355c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40365c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test10() {
40375c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    if (c) {
40385c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.Lock();  // expected-note {{mutex acquired here}}
40395c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40405c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    else {
40415c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins      mu_.AssertHeld();
40425c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    }
40435c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
40445c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40455c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
40465c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40475c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  void test11() {
40485c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    assertMu();
40495c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    int b = a;
40505c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins    a = 0;
40515c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins  }
40525c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins};
40535c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40545c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins}  // end namespace AssertHeldTest
40555c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40565c6134fd09bc5b738dafdd1c774edde13d95cb20DeLesley Hutchins
40577336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsnamespace LogicalConditionalTryLock {
40587336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40597336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinsclass Foo {
40607336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchinspublic:
40617336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  Mutex mu;
40627336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  int a GUARDED_BY(mu);
40637336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool c;
40647336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40657336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  bool newc();
40667336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40677336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test1() {
40687336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && mu.TryLock()) {
40697336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
40707336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
40717336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
40727336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
40737336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40747336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test2() {
40757336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    bool b = mu.TryLock();
40767336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && b) {
40777336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
40787336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
40797336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
40807336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
40817336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40827336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test3() {
40837336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c || !mu.TryLock())
40847336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
40857336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
40867336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
40877336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
40887336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40897336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test4() {
40907336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c && mu.TryLock()) {
40917336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
40927336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      c = newc();
40937336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
40947336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
40957336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
40967336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
40977336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test5() {
40987336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    while (c) {
40997336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      if (newc() || !mu.TryLock())
41007336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins        break;
41017336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41027336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41037336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41047336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41057336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41067336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test6() {
41077336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Lock();
41087336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    do {
41097336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41107336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41117336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    } while (newc() && mu.TryLock());
41127336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41137336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41147336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test7() {
41157336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    for (bool b = mu.TryLock(); c && b;) {
41167336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41177336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41187336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41197336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41207336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41217336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test8() {
41227336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (c && newc() && mu.TryLock()) {
41237336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      a = 0;
41247336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      mu.Unlock();
41257336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    }
41267336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41277336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41287336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  void test9() {
41297336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    if (!(c && newc() && mu.TryLock()))
41307336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins      return;
41317336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    a = 0;
41327336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins    mu.Unlock();
41337336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins  }
41347336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins};
41357336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
41367336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins}  // end namespace LogicalConditionalTryLock
41377336b9f8c0b58550a74c85a64f06d0fd74e7ad0dDeLesley Hutchins
4138