warn-thread-safety-analysis.cpp revision 5696884053b4a60dbed01ea8c7e6cd8dcf9b5de9
10ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -fcxx-exceptions %s
213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
53ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
6988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKABLE            __attribute__ ((lockable))
7988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
8988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_BY(x)       __attribute__ ((guarded_by(x)))
9988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_VAR         __attribute__ ((guarded_var))
10988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_BY(x)    __attribute__ ((pt_guarded_by(x)))
11988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_VAR      __attribute__ ((pt_guarded_var))
12988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
13988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
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
67d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing handling of smart pointers.
689d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinstemplate<class T>
699d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass SmartPtr {
709d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinspublic:
719d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(T* p) : ptr_(p) { }
729d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
739d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  ~SmartPtr();
749d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
759d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* get()        const { return ptr_; }
769d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* operator->() const { return ptr_; }
7796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  T& operator*()  const { return *ptr_; }
789d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
799d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsprivate:
809d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  T* ptr_;
819d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
829d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
839d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
84d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins// For testing destructor calls and cleanup.
85d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsclass MyString {
86d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinspublic:
87d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  MyString(const char* s);
88d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  ~MyString();
89d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins};
90d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
91d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
92d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
1003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
1023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
1033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
104194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
105194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   void MyLock() __attribute__((exclusive_lock_function(mu)));
1063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
1073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
1093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
1113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
112194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.x = 5;
1133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
1143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
1173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
1193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
1233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
1293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
1313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
1353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
1373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
1703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
1763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
1863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
1893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
1903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
1913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
1923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
198194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
199194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
200194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
201194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
202194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
2033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
2043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2058bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
2103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
2118bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'sls_mu' that is already locked}}
2123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
2162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
2203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2210da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // expected-note{{mutex acquired here}}
2223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
2230da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu2.Lock(); // expected-note{{mutex acquired here}}
2240da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}  \
2250da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
2263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
2282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
2293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
2303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2312e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
2343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
2352e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
2373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
2452e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{unlocking 'sls_mu' that was not locked}}
2463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
249aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2504e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2542e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
2552e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2582e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
2642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
2652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
2660da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  do {
2670da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
2723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
2730da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Lock();  // \
2742e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
2752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
2810da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
2820da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2830da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    sls_mu.Unlock();
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
2882e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
2890da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2938bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
296aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
2972e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
298aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
299aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
300aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
301aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
3022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
303aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
304aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
305aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
306aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
307aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
308aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
309aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
3103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
3113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
3318bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'aa_mu' that was not locked}}
3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
3353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
3363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
3378bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'aa_mu' that is already locked}}
3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3422e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
3432e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
344b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
345b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
346b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
347b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
348b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
349b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
350b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
351b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
352b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
3532f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
354b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3552f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3562f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
357b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3582f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3592f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
360b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3612e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
363b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
365b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
3662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
367b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
368b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
36905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
37005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
37105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
37205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
37405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
37505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
37705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
37805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
37905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
38374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
38474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
38574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
38674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
38774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
38874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
38974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
39005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
39105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
39205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
39405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
39505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
39974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
40005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
401af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
402af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
403af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
404af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
40505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
40605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40705b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
40805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
41005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
43274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
43605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
43774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
44274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
44305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
44505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
44605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
44774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
44805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
44905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
45105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
45274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
45305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
45505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
45605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
45774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
45805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
45905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
46105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
46274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
46305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
46505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
46605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
46774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
46805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
46905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
47105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
47205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
47374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
47405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
47505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
47605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
47705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
47874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
47905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
48074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
48105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
48274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
483a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
48474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
48505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
486b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
487eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
488eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
489eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
490eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
491eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
492eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
493eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
494eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
495eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
496eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
497eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
498eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
499eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
50074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
501eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
50274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading variable 'a' requires locking 'mu'}}
503eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
50474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
505eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
506eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
507eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
508eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
509eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
510eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
511eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
51299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
51399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
51499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
51599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
51699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
51799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
51899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
51999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
52899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
52999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
53699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
53799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
54499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
54599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
5463f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
5473f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'fooA.mu'}}
54899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
54999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
55099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
55199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
55299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
55399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
55499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
55599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
55699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
557a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
55899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
55999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
56099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
56199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
56299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
56399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
56499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
56599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
56699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
5673f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
5683f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.FooPointer->mu'}}
56999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
57099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
57199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
57299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
57399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
57499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
57599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
5763f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
5773f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
57899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
57999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
58199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
58299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
58399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
58499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
5853f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
5863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note{{found near match 'BarA.Foo.mu'}}
58799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
58899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
58999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
590a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
591a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
592a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
593a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
594a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
595a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
596a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
597a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
598a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
599a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
601a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
602a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
603a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
6044e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
60574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
606a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
607a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6084e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
6094e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
610a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
611a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
613a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
614a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
615a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
617a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
618a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
625a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
626a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
628a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
629a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
632a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
633a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
634a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
63574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
636a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
637a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6388bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
639a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
640a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
641a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
642a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6434e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
64474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
645a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
646a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6474e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
6484e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
649a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
650a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
651a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
652a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
653a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
654a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
655a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
65674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
657a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
658a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6598bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
660a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
661a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
662a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
663a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
664a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
665a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
666a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
66774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
668a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
669a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
6708bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
671a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
672a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
673a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
674978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
675978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
676978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
677978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
678978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
679978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
682978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
683978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
692978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
693978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
697978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
698978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
699978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
700978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
701978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
702978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
703978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
704978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
705978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
706978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
707978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
708978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
709978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
710978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
711978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
712978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
713978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
714978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
715978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
717978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
718978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
734978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
735978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
739978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
740978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
741af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
742af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
743af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
744af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
745af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
746af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
747cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
748cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
749cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
750cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
751cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
752cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
753cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
754cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
755cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
756cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
757978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
758978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7598bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
760978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
761978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
762978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
763978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
764978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7658bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
766978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
767978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
768978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
769978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
770978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
7718bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
772978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
773978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
774978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
775978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7768bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
777978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
778978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
779978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
780978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
7818bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
782978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
783978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
784978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
785978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
786978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7878bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
788978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
789978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
790978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
791978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
792978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
793978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
79474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
795978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
796978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
797978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
798978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
799978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
800978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
80174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
802978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
803978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
804194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8058121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
806194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
807194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
808194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
809194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
8100d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
811194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
812988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
813988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
814988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
815988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
816988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
108423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
108923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1197e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 5;
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1211e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie    g = 2;
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
1220a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
1226a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1229e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikie  w = 2;
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1245988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
12543f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b2->a_ = 3; // \
12553f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
12563f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b1->mu1_'}}
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1261988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1262988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
1285a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
12863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
12873f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
128874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
128974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
129074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
12913f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
12923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'b3->mu1_'}}
129374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
129574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
129674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
13173f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->bar(7); // \
13183f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
13193f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
13203f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins     child->a_ = 5; // \
13213f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
13223f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins       // expected-note {{found near match 'lock_'}}
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
1359a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1369988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
139874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
139974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1404988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1407a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
1408a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins             // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1431a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1433a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1436a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1438a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1443988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1444988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1445988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1446988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1447988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1448988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1449988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1450988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1451988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1452988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1453988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1454988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1455988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1456988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1457988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1458988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1459988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1460988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1461988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1462988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1463988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1464988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1465a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
1466988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1467a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
1468988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1469988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1470988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1471988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1472988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14758121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14768121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14778121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14785696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)));
14795696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)));
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14818121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14828121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14838121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14848121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14858121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14875696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
14885696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14928121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14938121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14948121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14968121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
14978121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
14988121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14998121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
15008121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15018121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15028121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
15038121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15048121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
15058121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
15068121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
15078121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15088121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15098121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
15108121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15112e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
15128121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
1513a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins        // expected-warning {{unlocking 'd2->mu' that was not locked}}
1514a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
15158121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
15168121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
15178121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
15188121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
15198121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
15203f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
15213f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins        // expected-note {{found near match 'd1->mu'}}
15228121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
15238121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
15248121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
15258121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
15268121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1527e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1528f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1529e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1530e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1531e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1532e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1533e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1534e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1535e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1536e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1537e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1538e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1539e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15406db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1541e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1542e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1543e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1544e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1545f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
154697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1547f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
154897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
154997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
155097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
155197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
155297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1553a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1554a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1555a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1556a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1557a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1558a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
155997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
156097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
156197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
156297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1563a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1564a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
156597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
156697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
156797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1568f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
156997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1570601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1571601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1572601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1573601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1574601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1575601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1576601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1577601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1578601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1579601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1580a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
1581601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1582601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1583601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1584601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
158597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15861fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15871fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15881fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15891fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15901fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15911fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16151fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16161fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
16171fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
1618c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
16191fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16201fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16211fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16221fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16231fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16241fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16251fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16261fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16271fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16281fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16291fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1630df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1631df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1632df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1633df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1634df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1635df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1637df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1638df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1639df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1640df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1641df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1642df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1643a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
1644df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1645df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1646df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1647df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1648df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1649df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1650df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1651df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
165260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchinsnamespace TryLockTest {
165360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1654b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1655b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1656b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1657b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1658b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
171843e3deeabf3ca02da427b63df8604e2daf86e8a3Sylvestre Ledru    if (b) {    // b should be unknown at this point, because of the join point
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1737b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1738b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1739b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1740b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1741b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1742b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1743b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1744b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1745b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1746b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1747b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1748b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1749b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
175060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
175160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of exclusive trylock
175260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo11() {
175360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
175460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.TryLock())
175560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
175660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
175760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
175860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.Lock();
175960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
176060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   a = 10;
176160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
176260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
176360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
176460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  // Test merge of shared trylock
176560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  void foo12() {
176660ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   if (cond) {
176760ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     if (!mu.ReaderTryLock())
176860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins       return;
176960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177060ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   else {
177160ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins     mu.ReaderLock();
177260ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   }
177360ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   int i = a;
177460ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins   mu.Unlock();
177560ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins  }
1776b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1777b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
177860ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins} // end namespace TrylockTest
177960ff198a22815b0aec5b96eaae977de067dcd4c1DeLesley Hutchins
1780b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
18197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
18397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
18417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
18427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
184323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18733f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
18743f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bt.fooBase.mu_'}}
18757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
1882a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
188423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
188523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
188623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
188723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
188823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
188923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
189123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
189223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
189323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
189423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1895dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
189623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
189723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
189823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
189923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
190023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
190123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
190223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
190323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
190423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
19057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
190623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
190723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
190823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
190923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
191023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
191123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
191223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1913dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
191423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
191523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
191623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
191723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
191823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
191923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
192023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
192123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
192223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
192423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
192523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
192623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
192723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
19287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
19297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
19317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
19327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1933e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1934e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1935e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1936e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1937e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1938e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1939e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1940e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1941e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1942e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1943e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1944e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1945e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1946e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1947e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1948e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1949e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1950e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1951a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
1952e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1953e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1954e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1955e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1956e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1957e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19582e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19592e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19602e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19612e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19632e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19642e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19662e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19672e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19682e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19692e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19702e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19712e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19722e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19732e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19742e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19772e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19782e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19792e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19802e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19822e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19832e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19842e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19862e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1987c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1988c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1989c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1990c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1991c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2052c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2054c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2055c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2056c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2057c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2058c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2059c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2060c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2061c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2063c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2064c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2065c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2066a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
2067c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2068a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
2069c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2070a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
2071c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2072a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);  // \
2073a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
2074c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2075c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2076a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
2077c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2078a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
2079c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2080a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
2081c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2082c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2083c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2084c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2085c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2086c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2087a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  myFoo.fooT2(dummy);
2088c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2089c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2090c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2091c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2092c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2093c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2094c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2095c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2096a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
2097c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2098c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20994bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
21004bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21014bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21024bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
21034bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21044bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
21054bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
21064bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
21074bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21084bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
21094bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
21104bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21114bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
21124bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
21134bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
21144bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
21154bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
21164bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
21174bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21184bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
21194bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
21204bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
21214bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21224bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
21234bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
21244bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
21254bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2126c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2127c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
21282f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21292f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
21302f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
21312f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
21322f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
21332f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21342f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
21352f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
21362f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
21372f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21382f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
21392f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
21402f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
21412f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
21422f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21432f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21444bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21454bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21464bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2147d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2148d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2149d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2150d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2151d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2152d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2153d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2154d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2155d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2156d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2157d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2158d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2159d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2160d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
21612a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21622a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
21632a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21642a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
21652a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
21662a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21672a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
21682a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21692a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
21702a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
21712a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
21722a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
21732a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
21742a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
21752a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
21762a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21772287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
21782287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21792287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21802287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
21812287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21822287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
21832287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
21842287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
21852287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
21862287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21872287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
21882287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
21892287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
21902287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
21912287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
21922287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
21932287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
21942287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
21952287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21962287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
21972287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
21982a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
21992287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22002287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
22012287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
22027ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22037ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
22047ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22057ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
22067ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
22077ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
22087ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
22097ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
22107ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
22117ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22127ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
22137ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22147ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
22150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22160d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
22170d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22180d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
22190d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22200d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
22210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
22220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
22250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
22260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
22280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
22300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
22310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
22320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22330d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
22340d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
22350d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
22370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
22390d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
22400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
22410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
22420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
22430d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
22440d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
22450d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22460d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22470d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22480d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22490d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22500d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
22510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
22520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
22530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22550d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
22560d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22570d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
22600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22610d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22620d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22630d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
22640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
22670d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
22680d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
22690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
22710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
22720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
22730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22740d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22750d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
22760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
22803f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
22813f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo().mu_'}}
22820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22850d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
22863f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
22873f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
22880d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22890d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22900d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22910d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
22923f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
22933f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'bar.getFoo3(a,b).mu_'}}
22940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22970d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
22983f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
22993f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'getBarFoo(bar,a).mu_'}}
23000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
23010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
23030d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
23043f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
23053f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
23060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
23070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
23080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23090d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23100da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace MoreLockExpressions
23110da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23120da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23130da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsnamespace TrylockJoinPoint {
23140da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23150da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchinsclass Foo {
23160da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  Mutex mu;
23170da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  bool c;
23180da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23190da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  void foo() {
23200da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    if (c) {
23210da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      if (!mu.TryLock())
23220da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins        return;
23230da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    } else {
23240da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins      mu.Lock();
23250da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    }
23260da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins    mu.Unlock();
23270da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins  }
23280da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins};
23290da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins
23300da4414f3d30c34fafb81b13b2cec3680c0bc9e1DeLesley Hutchins} // end namespace TrylockJoinPoint
23310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
23320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2333f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsnamespace LockReturned {
2334f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2335f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Foo {
2336f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2337f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int a             GUARDED_BY(mu_);
2338f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);
2339f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2340f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2341f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2342f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2343f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex* getMu() LOCK_RETURNED(mu_);
2344f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2345f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Mutex mu_;
2346f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2347f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2348f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2349f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2350f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2351f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Calls getMu() directly to lock and unlock
2352f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test1(Foo* f1, Foo* f2) {
2353a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
2354a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
2355f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2356a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
2357a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
2358a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
2359f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2360f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Lock();
2361f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2362f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->a = 0;
2363f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo();
23643f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  f1->foo2(f2); // \
23653f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
23663f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-note {{found near match 'f1->mu_'}}
2367f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2368f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Lock();
2369f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->foo2(f2);
2370f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::getMu(f2)->Unlock();
2371f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2372f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Foo::sfoo(f1);
2373f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2374f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  f1->getMu()->Unlock();
2375f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2376f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2377f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2378f63797c741e646b9482d204c88dee02fb41d7962DeLesley HutchinsMutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2379f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2380f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsclass Bar : public Foo {
2381f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinspublic:
2382f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  int  b            GUARDED_BY(getMu());
2383f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());
2384f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2385f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2386f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2387f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2388f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins};
2389f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2390f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2391f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2392f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Use getMu() within other attributes.
2393f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// This requires at lest levels of substitution, more in the case of
2394f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test2(Bar* b1, Bar* b2) {
2395a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
2396a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
2397a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
2398a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins                   // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
2399a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
2400a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
2401f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2402f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Lock();
2403f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2404f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2405f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
24063f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins  b1->bar2(b2);  // \
24073f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
24083f0ec5209726641782468bd4c7597e79dda78b15DeLesley Hutchins    // // expected-note {{found near match 'b1->mu_'}}
2409f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2410f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Lock();
2411f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2412f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2413f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b2->getMu()->Unlock();
2414f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2415f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2416f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2417f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2418f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->getMu()->Unlock();
2419f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2420f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2421f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2422f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Sanity check -- lock the mutex directly, but use attributes that call getMu()
2423f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins// Also lock the mutex using getFooMu, which calls a lock_returned function.
2424f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchinsvoid test3(Bar* b1, Bar* b2) {
2425f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Lock();
2426f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->b = 0;
2427f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar();
2428f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2429f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Lock();
2430f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->bar2(b2);
2431f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  getFooMu(b2)->Unlock();
2432f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2433f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar(b1);
2434f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  Bar::sbar2(b1);
2435f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2436f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins  b1->mu_.Unlock();
2437f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins}
2438f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2439f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins} // end namespace LockReturned
2440f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2441f63797c741e646b9482d204c88dee02fb41d7962DeLesley Hutchins
2442c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsnamespace ReleasableScopedLock {
2443c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2444c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsclass Foo {
2445c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  Mutex mu_;
2446c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  bool c;
2447c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  int a GUARDED_BY(mu_);
2448c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2449c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test1();
2450c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test2();
2451c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  void test3();
24525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test4();
24535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void test5();
2454c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins};
2455c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2456c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2457c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test1() {
2458c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2459c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2460c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2461c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2462c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test2() {
2463c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2464c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  if (c) {            // test join point -- held/not held during release
2465c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins    rlock.Release();
2466c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  }
2467c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2468c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2469c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchinsvoid Foo::test3() {
2470c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
2471c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 0;
2472c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  rlock.Release();
2473c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins  a = 1;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2474c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins}
2475c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
24765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test4() {
24775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();
24795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::test5() {
24835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  ReleasableMutexLock rlock(&mu_);
24845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  if (c) {
24855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    rlock.Release();
24865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  }
24875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  // no warning on join point for managed lock.
24885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
24895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
24905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
24915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2492c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins} // end namespace ReleasableScopedLock
2493c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2494c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
249576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsnamespace TrylockFunctionTest {
249676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
249776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsclass Foo {
249876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinspublic:
249976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu1_;
250076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  Mutex mu2_;
250176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool c;
250276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
250476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins};
250576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
250676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchinsbool Foo::lockBoth() {
250776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!mu1_.TryLock())
250876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
250976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  mu2_.Lock();
251176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  if (!c) {
251276f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu1_.Unlock();
251376f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    mu2_.Unlock();
251476f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins    return false;
251576f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  }
251676f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
251776f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins  return true;
251876f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}
251976f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252076f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins
252176f0a6e9bc9ee5aae029f959f64fae290727cca4DeLesley Hutchins}  // end namespace TrylockFunctionTest
2522c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2523c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2524c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
2525c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsnamespace DoubleLockBug {
2526c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2527c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinsclass Foo {
2528c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchinspublic:
2529c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  Mutex mu_;
2530c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  int a GUARDED_BY(mu_);
2531c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
25335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int  foo2() SHARED_LOCKS_REQUIRED(mu_);
2534c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins};
2535c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2536c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2538c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins  a = 0;
2539c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins}
2540c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
25415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
25425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return a;
25435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
25455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
25465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2547c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2548c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2549879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsnamespace UnlockBug {
2550c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2551879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinsclass Foo {
2552879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchinspublic:
2553879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  Mutex mutex_;
2554879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2555879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
2556879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2557879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2558879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2559879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2560879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
2561879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins    mutex_.Unlock();
2562879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2563879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins};
2564879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins
2565879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins} // end namespace UnlockBug
2566c36eda1113e014400d32fbbb99be36ff0b41f795DeLesley Hutchins
2567c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6DeLesley Hutchins
25685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
2569bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsnamespace FoolishScopedLockableBug {
2570bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2571bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass SCOPED_LOCKABLE WTF_ScopedLockable {
2572bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinspublic:
2573bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2574bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2575bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  // have to call release() manually;
2576bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  ~WTF_ScopedLockable();
2577bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2578bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void release() UNLOCK_FUNCTION();
2579bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2580bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2581bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2582bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchinsclass Foo {
2583bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  Mutex mu_;
2584bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  int a GUARDED_BY(mu_);
2585bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  bool c;
2586bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2587bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void doSomething();
2588bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2589bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test1() {
2590bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);
2591bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    wtf.release();
2592bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2593bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2594bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test2() {
2595bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2596bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
2597bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2598bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test3() {
2599bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2600bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2601bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2602bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2603bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2604bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2605bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test4() {
2606bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2607bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2608bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2609bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2610bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);
2611bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      wtf.release();
2612bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2613bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  }
2614bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2615bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test5() {
2616bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2617bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2618bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2619bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2620bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2621bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  void test6() {
2622bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    if (c) {
2623bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      doSomething();
2624bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2625bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    else {
2626bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
2627bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins    }
2628bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2629bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins};
2630bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2631bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
2632bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins} // end namespace FoolishScopedLockableBug
2633bbe334142b38d2f9dad3ae2eb7b332c54a5b2cc1DeLesley Hutchins
26349d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
26369d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsnamespace TemporaryCleanupExpr {
26379d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26389d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsclass Foo {
26399d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  int a GUARDED_BY(getMutexPtr().get());
26409d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26419d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  SmartPtr<Mutex> getMutexPtr();
26429d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26439d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  void test();
26449d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins};
26459d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26469d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26479d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchinsvoid Foo::test() {
26489d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins  {
26499d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    ReaderMutexLock lock(getMutexPtr().get());
26509d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins    int b = a;
265196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
2652a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
26539d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins}
26549d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26559d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins} // end namespace TemporaryCleanupExpr
26569d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
26579d6e7f3e12f1a825377ace33161e80caeda8cd06DeLesley Hutchins
265896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
265996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsnamespace SmartPointerTests {
266096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Foo {
266296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinspublic:
266396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Mutex> mu_;
266496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int a GUARDED_BY(mu_);
266596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int b GUARDED_BY(mu_.get());
266696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  int c GUARDED_BY(*mu_);
266796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
266896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);
266996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void Unlock() UNLOCK_FUNCTION(mu_);
267096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
267196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
267296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
267396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
267496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
267596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test4();
267696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test5();
267796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test6();
267896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test7();
267996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test8();
268096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
268196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test0() {
268396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
268496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;  // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
268596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;  // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
268696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
268796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
268896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test1() {
268996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
269096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
269196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
269296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
269396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Unlock();
269496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
269596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
269696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test2() {
269796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();
269896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
269996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
270096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
270196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Unlock();
270296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
270396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
270596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test3() {
270696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();
270796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
270896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
270996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
271096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
271196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
271296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
271496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test4() {
271596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(mu_.get());
271696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
271796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
271896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
271996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
272096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test5() {
272396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(&(*mu_));
272496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
272596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
272696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
272796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
272896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
272996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test6() {
273196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Lock();
273296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  a = 0;
273396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  b = 0;
273496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  c = 0;
273596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();
273696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
273796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
273996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test7() {
274096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
274196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Lock();
274296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
274396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
274496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
274596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
274696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    Unlock();
274796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
274896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
274996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
275096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
275196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Lock();
275496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Unlock();
275596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
275696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
275796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_.get()->Lock();
275896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Unlock();
275996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  {
276196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    (*mu_).Lock();
276296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins    mu_->Unlock();
276396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  }
276496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
276596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
276796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Foo::test8() {
276896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_->Lock();
276996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Lock();    // expected-warning {{locking 'mu_' that is already locked}}
277096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*mu_).Lock();        // expected-warning {{locking 'mu_' that is already locked}}
277196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  mu_.get()->Unlock();
277296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  Unlock();             // expected-warning {{unlocking 'mu_' that was not locked}}
277396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
277496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsclass Bar {
277796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  SmartPtr<Foo> foo;
277896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
277996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test0();
278096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test1();
278196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test2();
278296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  void test3();
278396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins};
278496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
278696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test0() {
2787a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
2788a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
2789a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
279096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
279196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
279396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test1() {
279496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Lock();
279596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
279696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
279796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
279896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->mu_->Unlock();
279996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
280096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
280296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test2() {
280396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).mu_->Lock();
280496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
280596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
280696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
280796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->mu_->Unlock();
280896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
280996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchinsvoid Bar::test3() {
281296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  MutexLock lock(foo->mu_.get());
281396fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo->a = 0;
281496fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  (*foo).b = 0;
281596fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins  foo.get()->c = 0;
281696fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}
281796fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
281896fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins}  // end namespace SmartPointerTests
281996fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282096fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
282196fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
28225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsnamespace DuplicateAttributeTest {
28235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28245381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsclass LOCKABLE Foo {
28255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinspublic:
28265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu1_;
28275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu2_;
28285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Mutex mu3_;
28295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int a GUARDED_BY(mu1_);
28305381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int b GUARDED_BY(mu2_);
28315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int c GUARDED_BY(mu3_);
28325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28335381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
28345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
28355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);
28375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void slock1() SHARED_LOCK_FUNCTION(mu1_);
28385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void locklots()
28405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_)
28415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_)
28425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
28435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock1() UNLOCK_FUNCTION(mu1_);
28455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  void unlocklots()
28475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_)
28485381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_)
28495381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
28505381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins};
28515381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28525381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28535381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }
28545381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock() UNLOCK_FUNCTION()         { }
28555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28565381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {
28575381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28585381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28595381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28605381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
28615696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  mu1_.ReaderLock();
28625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
28655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::locklots()
28715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
28725381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
28735381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Lock();
28745381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Lock();
28755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Lock();
28765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
28795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28805381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28815381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28825381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
28835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid Foo::unlocklots()
28895381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu1_, mu2_)
28905381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins    UNLOCK_FUNCTION(mu2_, mu3_) {
28915381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu1_.Unlock();
28925381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu2_.Unlock();
28935381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  mu3_.Unlock();
28945381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
28955381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28965381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
28975381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test0() {
28985381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
28995381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29005381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29015381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29025381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();
29035381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock();     // expected-warning {{locking 'foo' that is already locked}}
29045381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();
29055381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock();   // expected-warning {{unlocking 'foo' that was not locked}}
29065381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29075381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29085381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29095381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test1() {
29105381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
29125381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29135381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29145381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29155381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock1();
2916a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.lock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
29175381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29185381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2919a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();  // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
29205381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29215381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29225381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29235381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsint test2() {
29245381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29255381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
29265381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d1 = foo.a;
29275381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
29285381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29295381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.slock1();
2930a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.slock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
29315381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  int d2 = foo.a;
29325381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock1();
2933a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins  foo.unlock1();   // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
29345381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  return d1 + d2;
29355381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29365381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29375381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29385381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid test3() {
29395381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29405381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29415381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29425381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29435381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29445381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3();
29455381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29465381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3();
29475381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.lock3(); // \
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.unlock3();
29555381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlock3(); // \
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
29625381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchinsvoid testlots() {
29635381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  Foo foo;
29645381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29655381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29665381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29675381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29685381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29695381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29705381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots();
29715381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.locklots(); // \
2972a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2973a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2974a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{locking 'foo.mu3_' that is already locked}}
29755381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.a = 0;
29765381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.b = 0;
29775381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.c = 0;
29785381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots();
29795381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins  foo.unlocklots(); // \
2980a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2981a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2982a74b715cdc37c4523818a4018faae99d977aa537DeLesley Hutchins    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
29835381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}
29845381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29855381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins}  // end namespace DuplicateAttributeTest
29865381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29875381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
29885381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
298913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsnamespace TryLockEqTest {
299013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsclass Foo {
299213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex mu_;
299313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int a GUARDED_BY(mu_);
299413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  bool c;
299513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
299613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
299713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
299813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_);
299913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test1();
300113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  void test2();
300213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins};
300313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
300513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test1() {
300613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == 0) {
300713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
300813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
300913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
301013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
301113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
301213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() != 0) {
301413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
301513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
301613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
301713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
301813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 != tryLockMutexP()) {
301913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(tryLockMutexP() == 0)) {
302413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
302513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
302613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
302713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
302813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 0) {
302913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
303013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
303113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
303313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
303413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
303513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (0 == tryLockMutexI()) {
303613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
303713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
303813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
303913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
304013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
304113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexI() == 1) {
304313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
304413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
304513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
304613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
304713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == false) {
304813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
304913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
305013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
305213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
305313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
305413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() == true) {
305513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
305613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
305713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
305813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else {
305913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
306013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
306213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#if __has_feature(cxx_nullptr)
306313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (tryLockMutexP() == nullptr) {
306413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
306513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
306613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
306713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
306813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
306913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins#endif
307013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
307113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
307313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchinsvoid Foo::test2() {
307413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins/* FIXME: these tests depend on changes to the CFG.
307513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins *
307613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (mu_.TryLock() && c) {
307713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
307813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
307913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
308013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else return;
308113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
308213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (c && mu_.TryLock()) {
308313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
308413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
308513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
308613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  else return;
308713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
308813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(mu_.TryLock() && c))
308913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
309013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
309113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
309213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
309313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(c && mu_.TryLock()))
309413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
309513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
309613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
309713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
309813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!(mu_.TryLock() == 0) && c) {
309913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    a = 0;
310013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    unlock();
310113106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  }
310213106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
310313106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  if (!mu_.TryLock() || c)
310413106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins    return;
310513106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  a = 0;
310613106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins  unlock();
310713106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins*/
310813106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins}
310913106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins
311013106117060c90d6f84bd2ed7a5c03e0502ff419DeLesley Hutchins} // end namespace TryLockEqTest
31115381c05f51e5b7c7627f1d95b9a3425303ce086aDeLesley Hutchins
311296fac6a7fe89deff7860e536febbd4ae17bb57f3DeLesley Hutchins
3113ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsnamespace ExistentialPatternMatching {
3114ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3115ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Graph {
3116ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3117ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Mutex mu_;
3118ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3119ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3120ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3121ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3122ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3123ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsclass Node {
3124ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinspublic:
3125ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  int a GUARDED_BY(&Graph::mu_);
3126ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3127ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3128ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins    a = 0;
3129ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  }
3130ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3131ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins};
3132ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3133ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchinsvoid test() {
3134ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g1;
3135ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Graph g2;
3136ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  Node n1;
3137ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3138ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;   // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3139ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();   // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
3140ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();
3141ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3142ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();
3143ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3144ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3145ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3146ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3147ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3148ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Lock();
3149ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3150ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3151ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3152ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3153ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3154ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3155ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.a = 0;
3156ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo();
3157ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3158ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  UnlockAllGraphs();
3159ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3160ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3161ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3162ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3163ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3164ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g2.mu_.Unlock();
3165ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3166ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  LockAllGraphs();
3167ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Lock();  // expected-warning {{locking 'g1.mu_' that is already locked}}
3168ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins  g1.mu_.Unlock();
3169ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins}
3170ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
3171ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins} // end namespace ExistentialPatternMatching
3172ee2f032fe0fc86762608458c2a167ae504579a64DeLesley Hutchins
31734e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31744e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsnamespace StringIgnoreTest {
31754e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31764e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Foo {
31774e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31784e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  Mutex mu_;
31794e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION("");
31804e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION("");
31814e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void goober() EXCLUSIVE_LOCKS_REQUIRED("");
31824e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void roober() SHARED_LOCKS_REQUIRED("");
31834e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31844e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31854e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31864e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinsclass Bar : public Foo {
31874e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchinspublic:
31884e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  void bar(Foo* f) {
31894e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->unlock();
31904e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->goober();
31914e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->roober();
31924e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins    f->lock();
31934e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins  };
31944e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins};
31954e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31964e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins} // end namespace StringIgnoreTest
31974e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31984e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins
31995408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsnamespace LockReturnedScopeFix {
32005408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32015408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsclass Base {
32025408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsprotected:
32035408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  struct Inner;
32045408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  bool c;
32055408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32065408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  const Mutex& getLock(const Inner* i);
32075408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32085408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
32095408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
32105408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
32115408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32125408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void bar(Inner* i);
32135408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
32145408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32155408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32165408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsstruct Base::Inner {
32175408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  Mutex lock_;
32185408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
32195408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins};
32205408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32215408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32225408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsconst Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
32235408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  return i->lock_;
32245408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32255408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32265408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32275408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::foo(Inner* i) {
32285408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  i->doSomething();
32295408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32305408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32315408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchinsvoid Base::bar(Inner* i) {
32325408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  if (c) {
32335408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Lock();
32345408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    unlockInner(i);
32355408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32365408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  else {
32375408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    lockInner(i);
32385408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins    i->lock_.Unlock();
32395408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins  }
32405408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins}
32415408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
32425408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins} // end namespace LockReturnedScopeFix
32435408153e9140f34bbca9059638c61cc12bd539cfDeLesley Hutchins
3244fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3245fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsnamespace TrylockWithCleanups {
3246fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3247fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstruct Foo {
3248fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Mutex mu_;
3249fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a GUARDED_BY(mu_);
3250fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins};
3251fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3252fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley HutchinsFoo* GetAndLockFoo(const MyString& s)
3253fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3254fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3255fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchinsstatic void test() {
3256fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  Foo* lt = GetAndLockFoo("foo");
3257fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  if (!lt) return;
3258fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  int a = lt->a;
3259fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins  lt->mu_.Unlock();
3260fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins}
3261fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
326224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TrylockWithCleanups
3263fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
3264fd0f11ccd51154e933fad7dfa134cb4f62c87056DeLesley Hutchins
32650b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsnamespace UniversalLock {
32660b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32670b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchinsclass Foo {
32680b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  Mutex mu_;
32690b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  bool c;
32700b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32710b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  int a        GUARDED_BY(mu_);
32720b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void r_foo() SHARED_LOCKS_REQUIRED(mu_);
32730b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
32740b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32750b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test1() {
32760b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    int b;
32770b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32780b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnReads();
32790b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    b = a;
32800b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    r_foo();
32810b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnReads();
32820b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32830b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
32840b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
32850b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    w_foo();
32860b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
32870b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32880b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
32890b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // don't warn on joins with universal lock
32900b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test2() {
32910b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
32920b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
32930b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
32940b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0; // \
32950b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
32960b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();  // \
32970b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      // expected-warning {{unlocking '*' that was not locked}}
32980b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
32990b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33000b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33010b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // make sure the universal lock joins properly
33020b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test3() {
33030b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    if (c) {
33040b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
33050b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
33060b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
33070b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    else {
33080b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      beginNoWarnOnWrites();
33090b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins      mu_.Lock();
33100b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    }
33110b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    a = 0;
33120b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33130b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33140b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33150b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33160b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33170b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  // combine universal lock with other locks
33180b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  void test4() {
33190b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33200b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33210b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33220b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33230b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33240b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33250b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33260b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33270b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33280b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
33290b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Lock();
33300b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    beginNoWarnOnWrites();
33310b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    mu_.Unlock();
33320b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins    endNoWarnOnWrites();
33330b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins  }
33340b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins};
33350b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins
333624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace UniversalLock
333724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
333824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
333924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsnamespace TemplateLockReturned {
334024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
334124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinstemplate<class T>
334224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass BaseT {
334324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
334424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  virtual void baseMethod() = 0;
334524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
334624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
334724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  Mutex mutex_;
334824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  int a GUARDED_BY(mutex_);
334924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
335024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
335124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
335224a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinsclass Derived : public BaseT<int> {
335324a6c9459a50248e502884f129c789d452f70accDeLesley Hutchinspublic:
335424a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
335524a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins    a = 0;
335624a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins  }
335724a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins};
335824a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
335924a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins}  // end namespace TemplateLockReturned
336024a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
336124a6c9459a50248e502884f129c789d452f70accDeLesley Hutchins
3362f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsnamespace ExprMatchingBugFix {
3363f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3364f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Foo {
3365f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3366f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Mutex mu_;
3367f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3368f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3369f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3370f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsclass Bar {
3371f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinspublic:
3372f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  bool c;
3373f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Foo* foo;
3374f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  Bar(Foo* f) : foo(f) { }
3375f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3376f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  struct Nested {
3377f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Foo* foo;
3378f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested(Foo* f) : foo(f) { }
3379f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3380f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3381f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  };
3382f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3383f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  void test();
3384f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins};
3385f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3386f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3387f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchinsvoid Bar::test() {
3388f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  foo->mu_.Lock();
3389f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  if (c) {
3390f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    Nested *n = new Nested(foo);
3391f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    n->unlockFoo();
3392f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3393f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  else {
3394f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins    foo->mu_.Unlock();
3395f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins  }
3396f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}
3397f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3398f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins}; // end namespace ExprMatchingBugfix
3399f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
3400f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
34015b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsnamespace ComplexNameTest {
3402f9ee0bacd27085417dedf1a9f5df8a4cb5a758c1DeLesley Hutchins
34035b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Foo {
34045b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
34055b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
34065b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34075b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_)  { }
34085b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
34095b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34105b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
34115b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
34125b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34135b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsclass Bar {
34145b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinspublic:
34155b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  static Mutex mu_;
34165b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34175b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar()  LOCKS_EXCLUDED(mu_) { }
34185b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  ~Bar() LOCKS_EXCLUDED(mu_) { }
34195b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34205b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
34215b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};
34225b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34235b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34245b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test1() {
34255b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Foo f;           // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
34265b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  int a = f[0];    // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
34275b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}                  // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
34285b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34295b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34305b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchinsvoid test2() {
34315b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Lock();
34325b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  {
34335b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
34345b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
34355b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
34365b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins  Bar::mu_.Unlock();
34375b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins}
34385b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins
34395b280f28351bbdc103cc50d3b0f52f92d286fa0aDeLesley Hutchins};  // end namespace ComplexNameTest
34402a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34412a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34422a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsnamespace UnreachableExitTest {
34432a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34442a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsclass FemmeFatale {
34452a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinspublic:
34462a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale();
34472a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  ~FemmeFatale() __attribute__((noreturn));
34482a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins};
34492a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34502a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid exitNow() __attribute__((noreturn));
3451d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid exitDestruct(const MyString& ms) __attribute__((noreturn));
34522a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34532a237e03c407ff55bd8639b18658a8751955f1dbDeLesley HutchinsMutex fatalmu_;
34542a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34552a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34562a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  exitNow();
34572a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34582a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34592a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34602a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  FemmeFatale femme;
34612a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34622a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34632a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsbool c;
34642a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
34652a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchinsvoid test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
34662a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  if (c) {
34672a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    exitNow();
34682a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34692a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  else {
34702a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins    FemmeFatale femme;
34712a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins  }
34722a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}
34732a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins
3474d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchinsvoid test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3475d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins  exitDestruct("foo");
3476d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins}
3477d2f388299153d80cbe5ffaaed8a882b59a1b59bcDeLesley Hutchins
34782a237e03c407ff55bd8639b18658a8751955f1dbDeLesley Hutchins}   // end namespace UnreachableExitTest
3479186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3480186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3481186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsnamespace VirtualMethodCanonicalizationTest {
3482186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3483186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base {
3484186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3485186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  virtual Mutex* getMutex() = 0;
3486186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3487186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3488186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base2 : public Base {
3489186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3490186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3491186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3492186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3493186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Base3 : public Base2 {
3494186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3495186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();
3496186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3497186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3498186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsclass Derived : public Base3 {
3499186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinspublic:
3500186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  Mutex* getMutex();  // overrides Base::getMutex()
3501186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins};
3502186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3503186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3504186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3505186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchinsvoid derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3506186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins  baseFun(d);
3507186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}
3508186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3509186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins}  // end namespace VirtualMethodCanonicalizationTest
3510186af2de86aea41d7418158e68f96c1f8620e013DeLesley Hutchins
3511d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3512d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsnamespace TemplateFunctionParamRemapTest {
3513d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3514d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate <class T>
3515d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsstruct Cell {
3516d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  T dummy_;
3517d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Mutex* mu_;
3518d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3519d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3520d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass Foo {
3521d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3522d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  template <class T>
3523d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3524d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3525d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void test();
3526d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3527d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3528d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3529d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::elr(Cell<T>* c1) { }
3530d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3531d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid Foo::test() {
3532d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3533d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  elr(&cell); // \
3534d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3535d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3536d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3537d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3538d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3539d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3540d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3541d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3542d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR(Cell<T>* c1) { }
3543d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3544d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest() {
3545d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3546d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR(&cell); // \
3547d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
3548d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3549d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3550d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3551d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3552d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3553d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3554d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// second declaration
3555d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3556d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c2);
3557d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3558d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3559d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c3) { }
3560d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3561d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins// re-declaration after definition
3562d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3563d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalELR2(Cell<T>* c4);
3564d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3565d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid globalTest2() {
3566d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3567d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  globalELR2(&cell); // \
3568d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
3569d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3570d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3571d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3572d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3573d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsclass FooT {
3574d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinspublic:
3575d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3576d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins};
3577d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3578d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinstemplate<class T>
3579d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid FooT<T>::elr(Cell<T>* c1) { }
3580d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3581d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchinsvoid testFooT() {
3582d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  Cell<int> cell;
3583d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  FooT<int> foo;
3584d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins  foo.elr(&cell); // \
3585d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3586d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}
3587d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3588d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins}  // end namespace TemplateFunctionParamRemapTest
3589d278dbe43aff06865ae3388ba6b4ac5a9d68e179DeLesley Hutchins
3590ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3591ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsnamespace SelfConstructorTest {
3592ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3593ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass SelfLock {
3594ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3595ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock()  EXCLUSIVE_LOCK_FUNCTION(mu_);
3596ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock() UNLOCK_FUNCTION(mu_);
3597ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3598ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3599ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3600ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  Mutex mu_;
3601ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3602ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3603ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsclass LOCKABLE SelfLock2 {
3604ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinspublic:
3605ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2()  EXCLUSIVE_LOCK_FUNCTION();
3606ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  ~SelfLock2() UNLOCK_FUNCTION();
3607ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3608ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3609ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins};
3610ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3611ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3612ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test() {
3613ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock s;
3614ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s.foo();
3615ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3616ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3617ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchinsvoid test2() {
3618ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  SelfLock2 s2;
3619ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins  s2.foo();
3620ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}
3621ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
3622ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins}  // end namespace SelfConstructorTest
3623ef2388b10c41a9696d5d81f42ca79ff005fef7fcDeLesley Hutchins
36243ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36253ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsnamespace MultipleAttributeTest {
36263ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36273ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsclass Foo {
36283ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu1_;
36293ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  Mutex mu2_;
36303ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  a GUARDED_BY(mu1_);
36313ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  b GUARDED_BY(mu2_);
36323ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int  c GUARDED_BY(mu1_)    GUARDED_BY(mu2_);
36333ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
36343ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36353ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo1()          EXCLUSIVE_LOCKS_REQUIRED(mu1_)
36363ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCKS_REQUIRED(mu2_);
36373ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo2()          SHARED_LOCKS_REQUIRED(mu1_)
36383ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_LOCKS_REQUIRED(mu2_);
36393ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void foo3()          LOCKS_EXCLUDED(mu1_)
36403ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       LOCKS_EXCLUDED(mu2_);
36413ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void lock()          EXCLUSIVE_LOCK_FUNCTION(mu1_)
36423ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_LOCK_FUNCTION(mu2_);
36435696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerlock()    SHARED_LOCK_FUNCTION(mu1_)
36445696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins                       SHARED_LOCK_FUNCTION(mu2_);
36453ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void unlock()        UNLOCK_FUNCTION(mu1_)
36463ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       UNLOCK_FUNCTION(mu2_);
36473ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool trylock()       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
36483ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
36493ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
36503ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins                       SHARED_TRYLOCK_FUNCTION(true, mu2_);
36513ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36523ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  void test();
36533ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins};
36543ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36553ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36563ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo1() {
36573ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 1;
36583ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 2;
36593ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36603ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36613ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo2() {
36623ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int result = a + b;
36633ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
36643ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36653ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::foo3() { }
36665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::lock() { mu1_.Lock();  mu2_.Lock(); }
36675696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::readerlock() { mu1_.ReaderLock();  mu2_.ReaderLock(); }
36685696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsvoid Foo::unlock() { mu1_.Unlock();  mu2_.Unlock(); }
36693ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::trylock()       { return true; }
36703ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsbool Foo::readertrylock() { return true; }
36713ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36723ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36733ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchinsvoid Foo::test() {
36743ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Lock();
36753ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo1();             // expected-warning {{}}
36763ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  c = 0;              // expected-warning {{}}
36773ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  *d = 0;             // expected-warning {{}}
36783ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36793ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36803ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.ReaderLock();
36813ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo2();             // expected-warning {{}}
36823ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int x = c;          // expected-warning {{}}
36833ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int y = *d;         // expected-warning {{}}
36843ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu1_.Unlock();
36853ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36863ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Lock();
36873ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  foo3();             // expected-warning {{}}
36883ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  mu2_.Unlock();
36893ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36903ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  lock();
36913ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  a = 0;
36923ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  b = 0;
36933ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36943ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36953ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  readerlock();
36963ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  int z = a + b;
36973ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  unlock();
36983ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
36993ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (trylock()) {
37003ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    a = 0;
37013ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    b = 0;
37023ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
37033ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
37043ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37053ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  if (readertrylock()) {
37063ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    int zz = a + b;
37073ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins    unlock();
37083ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins  }
37093ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}
37103ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37113ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37123ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins}  // end namespace MultipleAttributeTest
37133ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
37143ce9fae275ec05cd648d6093b95eb1d05bc14a98DeLesley Hutchins
371591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsnamespace GuardedNonPrimitiveTypeTest {
371691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
371891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Data {
371991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
372091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data(int i) : dat(i) { }
372191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  getValue() const { return dat; }
372391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void setValue(int i)  { dat = i; }
372491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int  operator[](int i) const { return dat; }
372691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int& operator[](int i)       { return dat; }
372791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
372891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void operator()() { }
372991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
373191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  int dat;
373291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
373391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass DataCell {
373691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
373791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  DataCell(const Data& d) : dat(d) { }
373891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
373991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
374091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data dat;
374191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
374291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsvoid showDataCell(const DataCell& dc);
374591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
374791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsclass Foo {
374891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinspublic:
374991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // method call tests
375091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test() {
375191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(0);         // FIXME -- should be writing \
375291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
375391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_.getValue();  // \
375491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
375591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
375691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);      // FIXME -- should be writing \
375791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
375891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();   // \
375991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
376091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(0);      // FIXME -- should be writing \
376291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
376391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();   // \
376491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
376591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
376691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_).setValue(0);    // FIXME -- should be writing \
376791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
376891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = (*datap2_).getValue(); // \
376991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
377091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Lock();
377291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_.setValue(1);
377391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(1);
377491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap2_->setValue(1);
377591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
377691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
377791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.ReaderLock();
377891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = data_.getValue();
377991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    datap1_->setValue(0);  // reads datap1_, writes *datap1_
378091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap1_->getValue();
378191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    a = datap2_->getValue();
378291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    mu_.Unlock();
378391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
378491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
378591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // operator tests
378691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test2() {
378791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
378891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
378991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
379091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
379191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
379291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
379391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
379491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
379591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins                          // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
379691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
379791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
379891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
379991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    data_();              // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
380191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
380291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  // const operator tests
380491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  void test3() const {
380591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
380691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
380791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //FIXME
380891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
380991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
381091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins    int a = data_[0];       // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
381291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  }
381391e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
381491e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchinsprivate:
381591e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Mutex mu_;
381691e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data  data_   GUARDED_BY(mu_);
381791e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap1_ GUARDED_BY(mu_);
381891e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins  Data* datap2_ PT_GUARDED_BY(mu_);
381991e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins};
382091e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
382191e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins}  // end namespace GuardedNonPrimitiveTypeTest
382291e2061763f5e59f57e59c6f141b74b5ff0408adDeLesley Hutchins
382393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsnamespace GuardedNonPrimitive_MemberAccess {
382593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
382693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Cell {
382793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
382893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell(int i);
382993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void cellMethod();
383193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int a;
383393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
383493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
383693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Foo {
383793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinspublic:
383893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  int   a;
383993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell  c  GUARDED_BY(cell_mu_);
384093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Cell* cp PT_GUARDED_BY(cell_mu_);
384193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void myMethod();
384393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex cell_mu_;
384593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
384693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
384893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsclass Bar {
384993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchinsprivate:
385093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Mutex mu_;
385193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo  foo  GUARDED_BY(mu_);
385293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  Foo* foop PT_GUARDED_BY(mu_);
385393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
385493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  void test() {
385593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.myMethod();      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
385693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
385793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
385893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
385993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
386093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
386193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
386293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
386393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
386493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
386593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
386693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
386793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                         // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
386893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
386993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                         // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
387093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
387293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                           // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
387393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
387493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                           // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
387593699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
387693699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
387793699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                             // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
387893699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
387993699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins                             // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
388093699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins  };
388193699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins};
388293699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
388393699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins}  // namespace GuardedNonPrimitive_MemberAccess
388493699d23cd07c021eac2e26f8e32b58276bfa912DeLesley Hutchins
38850ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38860ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsnamespace TestThrowExpr {
38870ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38880ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchinsclass Foo {
38890ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  Mutex mu_;
38900ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38910ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  bool hasError();
38920ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
38930ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  void test() {
38940ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Lock();
38950ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    if (hasError()) {
38960ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins      throw "ugly";
38970ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    }
38980ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins    mu_.Unlock();
38990ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins  }
39000ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins};
39010ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39020ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins}  // end namespace TestThrowExpr
39030ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
39040ecc2e9ce86b0705bc1a53a9c8f90c433bcdca1bDeLesley Hutchins
3905ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsnamespace UnevaluatedContextTest {
3906ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3907ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins// parse attribute expressions in an unevaluated context.
3908ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3909ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex1();
3910ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsstatic inline Mutex* getMutex2();
3911ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3912ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3913ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3914ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchinsvoid bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3915ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
3916ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins}  // end namespace UnevaluatedContextTest
3917ed4330bc159b8311080d03caacac9a8cbf42370cDeLesley Hutchins
39185696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39195696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsnamespace LockUnlockFunctionTest {
39205696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39215696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins// Check built-in lock functions
39225696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass LOCKABLE MyLockable  {
39235696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39245696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock()       EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
39255696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION()    { mu_.ReaderLock(); }
39265696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock()     UNLOCK_FUNCTION()         { mu_.Unlock(); }
39275696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39285696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39295696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39305696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39315696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39325696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39335696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsclass Foo {
39345696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinspublic:
39355696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Correct lock/unlock functions
39365696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
39375696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Lock();
39385696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39395696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39405696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLock() SHARED_LOCK_FUNCTION(mu_) {
39415696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.ReaderLock();
39425696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39435696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39445696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlock() UNLOCK_FUNCTION(mu_) {
39455696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu_.Unlock();
39465696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }
39475696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39485696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check failure to lock.
39495696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}
39505696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39515696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39525696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
39535696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39545696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39555696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39565696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39575696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
39585696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39595696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39605696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();
39615696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();
39625696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
39635696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39645696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  // Check locking the wrong thing.
39655696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39665696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Lock();            // expected-note {{mutex acquired here}}
39675696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
39685696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
39695696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39705696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39715696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
39725696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.ReaderLock();      // expected-note {{mutex acquired here}}
39735696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
39745696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
39755696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39765696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39775696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
39785696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins    mu2_.Unlock();  // expected-warning {{unlocking 'mu2_' that was not locked}}
39795696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
39805696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39815696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchinsprivate:
39825696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu_;
39835696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins  Mutex mu2_;
39845696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins};
39855696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
39865696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins}  // end namespace LockUnlockFunctionTest
39875696884053b4a60dbed01ea8c7e6cd8dcf9b5de9DeLesley Hutchins
3988