warn-thread-safety-analysis.cpp revision 3f0ec5209726641782468bd4c7597e79dda78b15
113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %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__)))
14988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_LOCK_FUNCTION(...)   __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
15988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_LOCK_FUNCTION(...)      __attribute__ ((shared_lock_function(__VA_ARGS__)))
16988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
17988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_TRYLOCK_FUNCTION(...)    __attribute__ ((shared_trylock_function(__VA_ARGS__)))
18988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define UNLOCK_FUNCTION(...)            __attribute__ ((unlock_function(__VA_ARGS__)))
19988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCK_RETURNED(x)    __attribute__ ((lock_returned(x)))
20988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
21988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_LOCKS_REQUIRED(...) \
22988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
23988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_LOCKS_REQUIRED(...) \
24988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((shared_locks_required(__VA_ARGS__)))
25988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define NO_THREAD_SAFETY_ANALYSIS  __attribute__ ((no_thread_safety_analysis))
263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass  __attribute__((lockable)) Mutex {
293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski public:
303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Lock() __attribute__((exclusive_lock_function));
313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void ReaderLock() __attribute__((shared_lock_function));
323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Unlock() __attribute__((unlock_function));
333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool TryLock() __attribute__((exclusive_trylock_function(true)));
343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
381fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) MutexLock {
391fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
401fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
411fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~MutexLock() __attribute__((unlock_function));
421fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
431fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
441fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) ReaderMutexLock {
451fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
461fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
471fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~ReaderMutexLock() __attribute__((unlock_function));
481fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
491fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
50c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass SCOPED_LOCKABLE ReleasableMutexLock {
51c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins public:
52c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
53c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ~ReleasableMutexLock() UNLOCK_FUNCTION();
54c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
55c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void Release() UNLOCK_FUNCTION();
56c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
589d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
590b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// The universal lock, written "*", allows checking to be selectively turned
600b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins// off for a particular piece of code.
610b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnReads()  SHARED_LOCK_FUNCTION("*");
620b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnReads()    UNLOCK_FUNCTION("*");
630b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
640b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsvoid endNoWarnOnWrites()   UNLOCK_FUNCTION("*");
650b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
679d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinstemplate<class T>
689d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass SmartPtr {
699d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinspublic:
709d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(T* p) : ptr_(p) { }
719d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
729d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  ~SmartPtr();
739d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
749d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* get()        const { return ptr_; }
759d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* operator->() const { return ptr_; }
7696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  T& operator*()  const { return *ptr_; }
779d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
789d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsprivate:
799d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* ptr_;
809d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
819d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
829d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
94194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
95194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   void MyLock() __attribute__((exclusive_lock_function(mu)));
963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
1013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
102194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.x = 5;
1033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
1043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
1073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
1093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
1133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
1193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
1253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
1273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
1523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
1603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
1763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
1813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
1823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
188194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
189194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
190194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
191194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
192194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
1933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
1958bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
1993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
2018bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'sls_mu' that is already locked}}
2023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
2062e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
2103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2110da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // expected-note{{mutex acquired here}}
2123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2130da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu2.Lock(); // expected-note{{mutex acquired here}}
2140da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}  \
2150da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
2163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
2182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
2223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
2243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
2352e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{unlocking 'sls_mu' that was not locked}}
2363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
239aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2404e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
2452e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2482e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
2542e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
2552e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
2560da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  do {
2570da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
2623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
2630da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // \
2642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
2652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
2663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
2710da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
2720da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2730da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock();
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
2782e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
2790da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2802e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2838bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
286aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
2872e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
288aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
289aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
290aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
291aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
2922e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
293aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
294aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
295aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
296aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
297aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
298aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
299aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
3053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
3083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
3093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
3103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
3113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
3218bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'aa_mu' that was not locked}}
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
3278bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'aa_mu' that is already locked}}
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
3332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
334b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
335b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
336b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
337b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
338b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
339b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
340b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
341b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
342b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
3432f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
344b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3452f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3462f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
347b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3482f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3492f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
350b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3512e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3522e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
353b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3542e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
355b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
3562e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
357b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
358b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
35905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
36005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
36105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
36205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
36305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
36405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
36505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
36605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
36705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
36805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
36905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
37005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
37105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
37205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
37374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
37474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
37574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
37674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
37774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
37874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
37974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
38405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
38505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
38605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
38805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
38974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
39005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
391af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
392af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
393af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
394af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
39505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
40005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
40105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
40205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
40305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
40405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
40605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
40705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
40805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
40905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
41405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
42274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
42774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
43274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
43605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
43774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
44274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
44305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
44605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
44774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
44805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
45105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
45274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
45305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
45605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
45774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
45805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
46105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
46205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
46374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
46405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
46705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
46874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
46905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
47074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
47105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
47274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
473a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
47474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
47505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
476b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
477eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
478eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
479eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
480eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
481eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
482eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
483eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
484eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
485eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
486eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
487eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
488eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
489eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
49074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
491eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
49274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading variable 'a' requires locking 'mu'}}
493eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
49474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
495eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
496eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
497eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
498eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
499eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
500eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
501eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
50299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
50399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
50499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
50599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
50699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
50799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
50899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
50999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
51099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
51199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
51299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
51399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
51499107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
51599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
51699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
51799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
51899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
51999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
52899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
52999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
5363f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
5373f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'fooA.mu'}}
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
54499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
54599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
54699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
547a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
54899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
54999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
55099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
55199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
55299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
55399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
55499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
55599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
55699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
5573f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
5583f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.FooPointer->mu'}}
55999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
56099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
56199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
56299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
56399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
56499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
56599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
5663f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
5673f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
56899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
56999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
57099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
57299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
57399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
57499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
5753f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
5763f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
57799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
57899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
57999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
580a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
581a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
582a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
583a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
584a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
585a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
586a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
587a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
588a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
589a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
590a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
591a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
592a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
593a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
5944e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
59574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
596a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
597a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
5984e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
5994e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
601a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
602a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
603a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
604a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
605a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
606a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
607a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
608a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
609a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
610a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
611a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
613a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
614a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
615a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
617a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
618a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
62574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
626a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6288bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
629a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
632a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6334e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
63474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
635a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
636a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6374e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
6384e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
639a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
640a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
641a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
642a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
643a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
644a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
645a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
64674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
647a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
648a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6498bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
650a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
651a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
652a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
653a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
654a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
655a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
656a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
65774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
658a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
659a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
6608bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
661a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
662a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
663a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
664978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
665978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
666978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
667978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
668978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
669978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
670978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
671978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
672978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
673978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
674978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
675978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
676978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
677978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
678978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
679978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
682978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
683978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
692978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
693978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
697978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
698978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
699978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
700978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
701978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
702978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
703978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
704978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
705978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
706978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
707978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
708978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
709978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
710978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
711978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
712978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
713978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
714978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
715978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
717978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
718978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
731af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
732af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
733af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
734af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
735af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
736af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
737cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
738cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
739cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
740cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
741cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
742cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
743cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
744cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
745cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
746cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
747978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
748978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7498bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
750978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
751978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
752978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
753978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
754978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7558bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
756978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
757978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
758978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
759978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
760978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
7618bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
762978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
763978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
764978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
765978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7668bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
767978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
768978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
769978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
770978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
7718bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
772978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
773978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
774978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
775978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
776978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7778bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
778978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
779978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
780978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
781978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
782978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
783978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
78474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
785978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
786978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
787978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
788978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
789978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
790978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
79174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
792978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
793978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
794194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
7958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
796194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
797194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
798194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
799194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
801194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
802988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
803988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
804988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
805988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
806988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
807988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
808988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
809988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
810988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
811988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
812988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
813988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
814988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
815988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
816988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
107423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
107923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1187e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 5;
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1201e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie    g = 2;
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
1210a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
1216a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1219e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 2;
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
12443f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b2->a_ = 3; // \
12453f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
12463f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b1->mu1_'}}
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1261988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1262988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
1275a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
12763f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
12773f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
127874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
127974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
128074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
12813f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
12823f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
128374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
128574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
128674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1291988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1292988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1293988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1295988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1296988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
13073f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->bar(7); // \
13083f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
13093f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
13103f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->a_ = 5; // \
13113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
13123f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
1349a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1369988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
138874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
138974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1397a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
1398a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins             // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1404988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1421a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1423a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1426a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1428a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1436988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1438988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1443988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1444988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1445988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1446988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1447988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1448988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1449988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1450988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1451988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1452988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1453988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1454988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1455a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
1456988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1457a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
1458988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1459988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1460988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1461988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1462988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14658121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14668121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14678121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14688121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
14698121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)))           { }
14708121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14718121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14728121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14758121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14768121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14778121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
14788121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
14798121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14818121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14828121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14838121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14848121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
14858121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
14878121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
14888121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14928121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
14938121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14948121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14968121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
14978121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14988121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14998121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
15008121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15012e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
15028121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
1503a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins        // expected-warning {{unlocking 'd2->mu' that was not locked}}
1504a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
15058121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15068121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
15078121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15088121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
15098121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
15103f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
15113f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-note {{found near match 'd1->mu'}}
15128121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
15138121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15148121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15158121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
15168121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1517e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1518f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1519e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1520e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1521e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1522e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1523e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1524e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1525e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1526e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1527e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1528e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1529e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15306db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1531e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1532e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1533e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1534e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1535f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1536f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsnamespace invalid_lock_expression_test {
1537f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1538f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsclass LOCKABLE MyLockable {
1539f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinspublic:
1540f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable() __attribute__((exclusive_lock_function)) { }
15416db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins  ~MyLockable() { }
1542f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins};
1543f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1544f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins// create an empty lock expression
1545f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsvoid foo() {
1546f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable lock;  // \
1547f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning {{cannot resolve lock expression}}
1548f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins}
1549f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1550f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins} // end namespace invalid_lock_expression_test
1551f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1553f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
155497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
155597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
155697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
155797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
155897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1559a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1560a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1561a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1562a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1563a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1564a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
156597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
156697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
156797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
156897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1569a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1570a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
157197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
157297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
157397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1574f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
157597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1576601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1577601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1578601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1579601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1580601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1581601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1582601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1583601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1584601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1585601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1586a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
1587601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1588601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1589601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1590601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
159197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
16151fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
16161fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
16171fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16181fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16191fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16201fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16211fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16221fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
16231fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
1624c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
16251fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16261fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16271fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16281fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16291fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16301fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16311fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16321fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16331fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16341fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16351fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1637df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1638df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1639df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1640df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1641df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1642df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1643df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1644df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1645df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1646df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1647df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1648df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1649a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
1650df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1651df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1652df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1653df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1654df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1655df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1656df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1657df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1658b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
172243e3deeabf3ca02da427b63df8604e2daf86e8a3Sylvestre Ledru    if (b) {    // b should be unknown at this point, because of the join point
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1737b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1738b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1739b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1740b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1741b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1742b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1743b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1744b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1745b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1746b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1747b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1748b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1749b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1750b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1751b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1752b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1753b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1754b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1755b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1756b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
17737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
17757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
17777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
17787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
17817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
17837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
181923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18493f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
18503f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bt.fooBase.mu_'}}
18517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
1858a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
18597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
186023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
186123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
186223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
186323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
186423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
186723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
186823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
186923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
187023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1871dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
187223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
187423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
187523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
187623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
187823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
187923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
188023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
188223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
188323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
188423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
188523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
188623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
188723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
188823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1889dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
189023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
189123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
189323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
189423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
189523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
189623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
189723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
189823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
190023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
190123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
190323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
19047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
19057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
19077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1909e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1910e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1911e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1912e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1913e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1914e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1915e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1916e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1917e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1918e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1919e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1920e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1921e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1922e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1923e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1924e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1925e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1926e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1927a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
1928e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1929e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1930e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1931e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1932e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1933e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19352e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19372e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19392e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19402e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19412e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19422e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19432e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19452e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19462e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19472e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19482e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19492e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19502e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19512e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19522e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19532e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19542e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19552e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19562e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19572e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19582e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19592e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19602e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19612e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1963c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1964c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1965c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1966c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1967c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1968c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1969c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1970c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
1971c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
1972c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
1973c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1974c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1975c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
1976c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1977c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1978c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
1979c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1980c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1981c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
1982c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1983c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1984c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1985c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
1986c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1987c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
1988c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1989c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1990c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
1991c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2042a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2044a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2046a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2048a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);  // \
2049a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2052a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2054a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
2055c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2056a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
2057c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2058c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2059c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2060c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2061c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2063a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);
2064c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2065c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2066c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2067c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2068c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2069c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2070c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2071c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2072a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
2073c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2074c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20754bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
20764bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20774bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20784bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
20794bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20804bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
20814bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
20824bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
20834bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20844bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
20854bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
20864bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20874bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
20884bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
20894bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
20904bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
20914bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
20924bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
20934bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20944bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
20954bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
20964bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
20974bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20984bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
20994bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
21004bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
21014bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2102c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2103c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21042f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21052f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
21062f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
21072f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
21082f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
21092f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21102f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
21112f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
21122f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
21132f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21142f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
21152f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
21162f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
21172f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
21182f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21192f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21204bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21214bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21224bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2123d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2124d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2125d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2126d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2127d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2128d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2129d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2130d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2131d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2132d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2133d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2134d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2135d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2136d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
21372a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21382a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
21392a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21402a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
21412a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
21422a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21432a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
21442a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21452a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
21462a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
21472a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
21482a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
21492a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
21502a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
21512a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
21522a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21532287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
21542287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21552287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21562287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
21572287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21582287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
21592287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
21602287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
21612287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
21622287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21632287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
21642287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
21652287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
21662287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
21672287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
21682287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
21692287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
21702287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
21712287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21722287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
21732287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
21742a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
21752287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21762287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
21772287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21787ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21797ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
21807ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21817ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
21827ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
21837ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
21847ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
21857ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
21867ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
21877ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21887ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
21897ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21907ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21910d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21920d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
21930d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
21950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
21960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
21970d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
21980d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
21990d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
22010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22030d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
22040d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22050d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
22060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
22070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
22080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22090d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
22100d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22110d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22120d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
22130d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22140d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
22150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
22160d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
22170d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
22180d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
22190d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22200d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
22210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
22270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
22290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
22320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22330d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22340d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22350d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
22360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22390d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
22400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
22430d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
22440d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
22450d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22460d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
22470d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
22480d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
22490d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22500d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
22520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22550d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
22563f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
22573f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo().mu_'}}
22580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22610d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
22623f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
22633f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
22640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22670d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
22683f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
22693f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'bar.getFoo3(a,b).mu_'}}
22700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
22743f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
22753f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'getBarFoo(bar,a).mu_'}}
22760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
22803f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
22813f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
22820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
22840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22850d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22860da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace MoreLockExpressions
22870da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
22880da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
22890da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsnamespace TrylockJoinPoint {
22900da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
22910da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsclass Foo {
22920da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  Mutex mu;
22930da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  bool c;
22940da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
22950da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  void foo() {
22960da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    if (c) {
22970da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      if (!mu.TryLock())
22980da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins        return;
22990da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    } else {
23000da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      mu.Lock();
23010da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    }
23020da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    mu.Unlock();
23030da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  }
23040da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins};
23050da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23060da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace TrylockJoinPoint
23070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2309f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsnamespace LockReturned {
2310f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2311f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Foo {
2312f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2313f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int a             GUARDED_BY(mu_);
2314f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);
2315f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2316f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2317f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2318f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2319f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex* getMu() LOCK_RETURNED(mu_);
2320f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2321f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex mu_;
2322f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2323f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2324f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2325f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2326f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2327f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Calls getMu() directly to lock and unlock
2328f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test1(Foo* f1, Foo* f2) {
2329a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
2330a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
2331f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2332a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
2333a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
2334a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
2335f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2336f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Lock();
2337f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2338f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->a = 0;
2339f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo();
23403f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  f1->foo2(f2); // \
23413f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
23423f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'f1->mu_'}}
2343f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2344f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Lock();
2345f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo2(f2);
2346f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Unlock();
2347f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2348f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::sfoo(f1);
2349f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2350f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Unlock();
2351f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2352f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2353f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2354f63797c741e646b9482d204c88dee02fb41d7962DeLesley HutchinsMutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2355f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2356f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Bar : public Foo {
2357f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2358f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int  b            GUARDED_BY(getMu());
2359f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());
2360f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2361f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2362f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2363f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2364f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2365f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2366f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2367f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2368f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Use getMu() within other attributes.
2369f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// This requires at lest levels of substitution, more in the case of
2370f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test2(Bar* b1, Bar* b2) {
2371a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
2372a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
2373a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
2374a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
2375a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
2376a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
2377f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2378f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Lock();
2379f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2380f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2381f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
23823f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b1->bar2(b2);  // \
23833f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
23843f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // // expected-note {{found near match 'b1->mu_'}}
2385f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2386f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Lock();
2387f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2388f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2389f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Unlock();
2390f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2391f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2392f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2393f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2394f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Unlock();
2395f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2396f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2397f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2398f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Sanity check -- lock the mutex directly, but use attributes that call getMu()
2399f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Also lock the mutex using getFooMu, which calls a lock_returned function.
2400f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test3(Bar* b1, Bar* b2) {
2401f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Lock();
2402f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2403f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
2404f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2405f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Lock();
2406f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2407f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Unlock();
2408f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2409f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2410f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2411f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2412f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Unlock();
2413f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2414f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2415f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins} // end namespace LockReturned
2416f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2417f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2418c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsnamespace ReleasableScopedLock {
2419c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2420c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass Foo {
2421c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  Mutex mu_;
2422c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  bool c;
2423c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  int a GUARDED_BY(mu_);
2424c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2425c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test1();
2426c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test2();
2427c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test3();
24285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test4();
24295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test5();
2430c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
2431c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2432c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2433c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test1() {
2434c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2435c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2436c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2437c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2438c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test2() {
2439c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2440c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  if (c) {            // test join point -- held/not held during release
2441c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins    rlock.Release();
2442c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
2443c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2444c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2445c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test3() {
2446c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2447c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 0;
2448c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2449c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 1;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2450c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2451c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
24525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test4() {
24535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();
24555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test5() {
24595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  if (c) {
24615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    rlock.Release();
24625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  }
24635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  // no warning on join point for managed lock.
24645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2468c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins} // end namespace ReleasableScopedLock
2469c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2470c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
247176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsnamespace TrylockFunctionTest {
247276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
247376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsclass Foo {
247476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinspublic:
247576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu1_;
247676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu2_;
247776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool c;
247876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
247976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
248076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins};
248176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
248276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsbool Foo::lockBoth() {
248376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!mu1_.TryLock())
248476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
248576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
248676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  mu2_.Lock();
248776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!c) {
248876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu1_.Unlock();
248976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu2_.Unlock();
249076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
249176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  }
249276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
249376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  return true;
249476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}
249576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
249676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
249776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}  // end namespace TrylockFunctionTest
2498c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2499c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2500c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2501c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsnamespace DoubleLockBug {
2502c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2503c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsclass Foo {
2504c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinspublic:
2505c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  Mutex mu_;
2506c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  int a GUARDED_BY(mu_);
2507c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
25095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int  foo2() SHARED_LOCKS_REQUIRED(mu_);
2510c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins};
2511c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2512c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2514c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  a = 0;
2515c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins}
2516c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
25185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return a;
25195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2523c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2524c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2525879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsnamespace UnlockBug {
2526c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2527879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsclass Foo {
2528879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinspublic:
2529879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  Mutex mutex_;
2530879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2531879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
2532879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2533879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2534879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2535879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2536879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
2537879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2538879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2539879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins};
2540879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2541879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins} // end namespace UnlockBug
2542c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2543c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
25445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2545bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsnamespace FoolishScopedLockableBug {
2546bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2547bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass SCOPED_LOCKABLE WTF_ScopedLockable {
2548bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinspublic:
2549bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2550bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2551bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  // have to call release() manually;
2552bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  ~WTF_ScopedLockable();
2553bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2554bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void release() UNLOCK_FUNCTION();
2555bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2556bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2557bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2558bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass Foo {
2559bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  Mutex mu_;
2560bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  int a GUARDED_BY(mu_);
2561bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  bool c;
2562bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2563bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void doSomething();
2564bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2565bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test1() {
2566bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);
2567bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    wtf.release();
2568bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2569bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2570bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test2() {
2571bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2572bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
2573bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2574bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test3() {
2575bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2576bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2577bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2578bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2579bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2580bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2581bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test4() {
2582bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2583bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2584bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2585bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2586bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2587bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2588bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2589bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2590bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2591bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test5() {
2592bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2593bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2594bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2595bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2596bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2597bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test6() {
2598bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2599bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2600bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2601bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2602bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2603bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2604bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2605bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2606bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2607bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2608bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins} // end namespace FoolishScopedLockableBug
2609bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
26109d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26129d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsnamespace TemporaryCleanupExpr {
26139d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26149d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass Foo {
26159d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  int a GUARDED_BY(getMutexPtr().get());
26169d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26179d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr<Mutex> getMutexPtr();
26189d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26199d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  void test();
26209d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
26219d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26229d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26239d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsvoid Foo::test() {
26249d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  {
26259d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    ReaderMutexLock lock(getMutexPtr().get());
26269d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    int b = a;
262796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
2628a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
26299d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins}
26309d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26319d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins} // end namespace TemporaryCleanupExpr
26329d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26339d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
263496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
263596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsnamespace SmartPointerTests {
263696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
263796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Foo {
263896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinspublic:
263996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Mutex> mu_;
264096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int a GUARDED_BY(mu_);
264196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int b GUARDED_BY(mu_.get());
264296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int c GUARDED_BY(*mu_);
264396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
264496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);
264596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Unlock() UNLOCK_FUNCTION(mu_);
264696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
264796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
264896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
264996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
265096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
265196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test4();
265296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test5();
265396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test6();
265496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test7();
265596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test8();
265696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
265796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
265896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test0() {
265996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
266096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;  // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
266196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;  // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
266296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
266396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test1() {
266596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
266696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
266796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
266896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
266996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Unlock();
267096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
267196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test2() {
267396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();
267496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
267596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
267696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
267796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Unlock();
267896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
267996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test3() {
268296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();
268396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
268496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
268596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
268696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
268796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
268896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test4() {
269196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(mu_.get());
269296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
269396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
269496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
269596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
269696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test5() {
269996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(&(*mu_));
270096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
270196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
270296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
270396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test6() {
270796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Lock();
270896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
270996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
271096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
271196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();
271296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
271396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test7() {
271696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
271796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Lock();
271896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
271996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
272096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
272196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
272296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Unlock();
272396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
272496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
272596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
272696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
272796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
272896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
272996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
273096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Unlock();
273196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
273296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
273396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
273496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Unlock();
273596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
273696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
273796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Lock();
273896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
273996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
274096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
274196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
274396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test8() {
274496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
274596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();    // expected-warning {{locking 'mu_' that is already locked}}
274696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();        // expected-warning {{locking 'mu_' that is already locked}}
274796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
274896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();             // expected-warning {{unlocking 'mu_' that was not locked}}
274996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
275096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
275196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
275296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Bar {
275396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Foo> foo;
275496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
275596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
275696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
275796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
275896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
275996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
276096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test0() {
2763a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
2764a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
2765a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
276696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
276796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test1() {
277096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Lock();
277196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
277296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
277396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
277496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Unlock();
277596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test2() {
277996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).mu_->Lock();
278096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
278196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
278296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
278396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->mu_->Unlock();
278496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
278596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test3() {
278896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(foo->mu_.get());
278996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
279096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
279196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
279296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
279396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}  // end namespace SmartPointerTests
279596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
27985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsnamespace DuplicateAttributeTest {
27995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsclass LOCKABLE Foo {
28015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinspublic:
28025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu1_;
28035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu2_;
28045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu3_;
28055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int a GUARDED_BY(mu1_);
28065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int b GUARDED_BY(mu2_);
28075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int c GUARDED_BY(mu3_);
28085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
28105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
28115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);
28135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void slock1() SHARED_LOCK_FUNCTION(mu1_);
28145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void locklots()
28165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_)
28175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_)
28185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock1() UNLOCK_FUNCTION(mu1_);
28215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlocklots()
28235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_)
28245381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_)
28255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins};
28275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }
28305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock() UNLOCK_FUNCTION()         { }
28315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {
28335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
28375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
28415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::locklots()
28475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
28485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
28495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
28555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
28595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlocklots()
28655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_)
28665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_, mu3_) {
28675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test0() {
28745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
28755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
28765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
28775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
28795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();     // expected-warning {{locking 'foo' that is already locked}}
28805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
28815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();   // expected-warning {{unlocking 'foo' that was not locked}}
28825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test1() {
28865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
28875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
28885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
28895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
28905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
2892a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.lock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
28935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
28945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2895a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();  // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
28965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint test2() {
29005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
29025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d1 = foo.a;
29035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
2906a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.slock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
29075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d2 = foo.a;
29085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2909a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();   // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
29105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return d1 + d2;
29115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test3() {
29155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29165381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29195381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3(); // \
2924a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2925a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2926a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu3_' that is already locked}}
29275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3(); // \
2932a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2933a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2934a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
29355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid testlots() {
29395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots(); // \
2948a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2949a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2950a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu3_' that is already locked}}
29515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots(); // \
2956a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2957a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2958a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
29595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29615381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}  // end namespace DuplicateAttributeTest
29625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
296513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsnamespace TryLockEqTest {
296613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
296713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsclass Foo {
296813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex mu_;
296913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int a GUARDED_BY(mu_);
297013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  bool c;
297113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
297213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
297313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
297413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_);
297513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
297613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test1();
297713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test2();
297813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins};
297913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
298013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
298113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test1() {
298213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == 0) {
298313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
298413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
298513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
298613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
298713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
298813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
298913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() != 0) {
299013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
299113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
299213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
299313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 != tryLockMutexP()) {
299513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
299613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
299713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
299813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(tryLockMutexP() == 0)) {
300013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
300113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
300213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
300313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 0) {
300513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
300613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
300713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
300813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
300913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
301013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 == tryLockMutexI()) {
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 (tryLockMutexI() == 1) {
301913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == false) {
302413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
302513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
302613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
302813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
302913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
303013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == true) {
303113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
303213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
303313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else {
303513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
303613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
303813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#if __has_feature(cxx_nullptr)
303913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == nullptr) {
304013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
304113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
304213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
304313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
304413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
304513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#endif
304613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
304713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test2() {
305013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins/* FIXME: these tests depend on changes to the CFG.
305113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins *
305213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() && c) {
305313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
305413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
305513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else return;
305713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (c && mu_.TryLock()) {
305913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
306013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
306113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else return;
306313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(mu_.TryLock() && c))
306513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
306613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
306713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
306813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(c && mu_.TryLock()))
307013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
307113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
307213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
307313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(mu_.TryLock() == 0) && c) {
307513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
307613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
307713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
307813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!mu_.TryLock() || c)
308013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
308113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
308213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
308313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins*/
308413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
308513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
308613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins} // end namespace TryLockEqTest
30875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
308896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
3089ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsnamespace ExistentialPatternMatching {
3090ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3091ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Graph {
3092ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3093ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Mutex mu_;
3094ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3095ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3096ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3097ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3098ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3099ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Node {
3100ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3101ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  int a GUARDED_BY(&Graph::mu_);
3102ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3103ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3104ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins    a = 0;
3105ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  }
3106ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3107ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3108ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3109ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid test() {
3110ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g1;
3111ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g2;
3112ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Node n1;
3113ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3114ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;   // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3115ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();   // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
3116ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();
3117ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3118ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();
3119ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3120ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3121ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3122ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3123ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3124ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Lock();
3125ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3126ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3127ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3128ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3129ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3130ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3131ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3132ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3133ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3134ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  UnlockAllGraphs();
3135ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3136ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3137ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3138ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3139ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3140ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3141ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3142ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3143ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();  // expected-warning {{locking 'g1.mu_' that is already locked}}
3144ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3145ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins}
3146ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3147ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins} // end namespace ExistentialPatternMatching
3148ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
31494e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31504e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsnamespace StringIgnoreTest {
31514e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31524e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Foo {
31534e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31544e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  Mutex mu_;
31554e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION("");
31564e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION("");
31574e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void goober() EXCLUSIVE_LOCKS_REQUIRED("");
31584e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void roober() SHARED_LOCKS_REQUIRED("");
31594e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31604e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31614e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31624e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Bar : public Foo {
31634e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31644e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void bar(Foo* f) {
31654e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->unlock();
31664e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->goober();
31674e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->roober();
31684e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->lock();
31694e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  };
31704e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31714e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31724e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins} // end namespace StringIgnoreTest
31734e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31744e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31755408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsnamespace LockReturnedScopeFix {
31765408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31775408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsclass Base {
31785408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsprotected:
31795408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  struct Inner;
31805408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  bool c;
31815408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31825408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  const Mutex& getLock(const Inner* i);
31835408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31845408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
31855408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
31865408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
31875408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31885408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void bar(Inner* i);
31895408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31905408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31915408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31925408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsstruct Base::Inner {
31935408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  Mutex lock_;
31945408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
31955408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
31965408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31975408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
31985408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsconst Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
31995408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  return i->lock_;
32005408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32015408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32025408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32035408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::foo(Inner* i) {
32045408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  i->doSomething();
32055408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32065408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32075408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::bar(Inner* i) {
32085408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  if (c) {
32095408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Lock();
32105408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    unlockInner(i);
32115408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32125408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  else {
32135408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    lockInner(i);
32145408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Unlock();
32155408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32165408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32175408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32185408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins} // end namespace LockReturnedScopeFix
32195408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
3220fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3221fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsnamespace TrylockWithCleanups {
3222fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3223fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsclass MyString {
3224fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinspublic:
3225fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  MyString(const char* s);
3226fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  ~MyString();
3227fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3228fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3229fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstruct Foo {
3230fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Mutex mu_;
3231fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a GUARDED_BY(mu_);
3232fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3233fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3234fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley HutchinsFoo* GetAndLockFoo(const MyString& s)
3235fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3236fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3237fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstatic void test() {
3238fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Foo* lt = GetAndLockFoo("foo");
3239fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  if (!lt) return;
3240fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a = lt->a;
3241fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  lt->mu_.Unlock();
3242fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3243fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3244fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3245fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3246fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
32470b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsnamespace UniversalLock {
32480b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32490b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsclass Foo {
32500b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  Mutex mu_;
32510b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  bool c;
32520b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32530b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  int a        GUARDED_BY(mu_);
32540b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void r_foo() SHARED_LOCKS_REQUIRED(mu_);
32550b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
32560b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32570b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test1() {
32580b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    int b;
32590b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32600b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnReads();
32610b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    b = a;
32620b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    r_foo();
32630b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnReads();
32640b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32650b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32670b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    w_foo();
32680b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32690b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32700b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32710b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // don't warn on joins with universal lock
32720b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test2() {
32730b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32740b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32750b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32760b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0; // \
32770b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
32780b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();  // \
32790b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{unlocking '*' that was not locked}}
32800b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32810b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32820b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32830b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // make sure the universal lock joins properly
32840b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test3() {
32850b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32860b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32870b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32880b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32890b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    else {
32900b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32910b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
32920b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32930b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32940b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32950b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
32960b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32970b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32980b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32990b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // combine universal lock with other locks
33000b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test4() {
33010b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33020b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33030b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33040b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33050b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33060b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33070b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33080b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33090b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33100b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33110b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33120b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33130b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33140b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33150b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33160b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins};
33170b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33180b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins}
3319