warn-thread-safety-analysis.cpp revision 4bda3eca138d39585c9e475ad25aa9ff053f923b
13ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
23ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKABLE            __attribute__ ((lockable))
4988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
5988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_BY(x)       __attribute__ ((guarded_by(x)))
6988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define GUARDED_VAR         __attribute__ ((guarded_var))
7988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_BY(x)    __attribute__ ((pt_guarded_by(x)))
8988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define PT_GUARDED_VAR      __attribute__ ((pt_guarded_var))
9988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
10988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
11988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_LOCK_FUNCTION(...)   __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
12988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_LOCK_FUNCTION(...)      __attribute__ ((shared_lock_function(__VA_ARGS__)))
13988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
14988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_TRYLOCK_FUNCTION(...)    __attribute__ ((shared_trylock_function(__VA_ARGS__)))
15988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define UNLOCK_FUNCTION(...)            __attribute__ ((unlock_function(__VA_ARGS__)))
16988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCK_RETURNED(x)    __attribute__ ((lock_returned(x)))
17988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
18988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define EXCLUSIVE_LOCKS_REQUIRED(...) \
19988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
20988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define SHARED_LOCKS_REQUIRED(...) \
21988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  __attribute__ ((shared_locks_required(__VA_ARGS__)))
22988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski#define NO_THREAD_SAFETY_ANALYSIS  __attribute__ ((no_thread_safety_analysis))
233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//  Helper fields
263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass  __attribute__((lockable)) Mutex {
303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski public:
313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Lock() __attribute__((exclusive_lock_function));
323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void ReaderLock() __attribute__((shared_lock_function));
333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void Unlock() __attribute__((unlock_function));
343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool TryLock() __attribute__((exclusive_trylock_function(true)));
353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
391fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) MutexLock {
401fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
411fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
421fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~MutexLock() __attribute__((unlock_function));
431fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
441fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
451fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsclass __attribute__((scoped_lockable)) ReaderMutexLock {
461fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins public:
471fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
481fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  ~ReaderMutexLock() __attribute__((unlock_function));
491fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
501fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu;
533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex sls_mu2 __attribute__((acquired_after(sls_mu)));
553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guard_var __attribute__((guarded_var)) = 0;
563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiint sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskibool getBool();
593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass MutexWrapper {
613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski   Mutex mu;
63194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   int x __attribute__((guarded_by(mu)));
64194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski   void MyLock() __attribute__((exclusive_lock_function(mu)));
653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutexWrapper sls_mw;
683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_0() {
703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Lock();
71194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.x = 5;
723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mw.mu.Unlock();
733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_2() {
763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guard_var;
783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_3() {
823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_4() {
883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guard_var = 2;
903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_5() {
943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  int x = sls_guardby_var;
963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_6() {
1003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_guardby_var = 2;
1023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_7() {
1063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Lock();
1083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu2.Unlock();
1093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_8() {
1133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_9() {
1213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_6() {
1293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
1353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
1363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_good_7() {
1433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  while (getBool()) {
1453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
1473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
1483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        sls_mu.Lock();
1493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski        continue;
1503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
1513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
1523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock();
1533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
1543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
157194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid sls_fun_good_8() {
158194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.MyLock();
159194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  sls_mw.mu.Unlock();
160194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
161194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
1623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_1() {
1633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
1648bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
1653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_2() {
1683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock();
1693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Lock(); // \
1708bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'sls_mu' that is already locked}}
1713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
1723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
1733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_3() {
1752e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
1762e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
1773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_4() {
1793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock(); // \
1812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} \
1822e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  expected-note{{mutex acquired here}}
1832e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
1843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  else
1853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu2.Lock(); // \
1862e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  expected-note{{mutex acquired here}}
1872e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
1883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_5() {
1902e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
1913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool())
1923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
1932e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
1943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
1953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_6() {
1963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  if (getBool()) {
1972e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
1983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } else {
1993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    } else {
2023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      getBool(); // EMPTY
2033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2062e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
2072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    expected-warning{{unlocking 'sls_mu' that was not locked}}
2083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_7() {
211aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Lock();
2124e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while (getBool()) {
2133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Unlock();
2143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    if (getBool()) {
2153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      if (getBool()) {
2162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        continue; // \
2172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski      }
2193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    }
2202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_8() {
2262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note{{mutex acquired here}}
2272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
2282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  // FIXME: TERRIBLE SOURCE LOCATION!
2292e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  do { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2304e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Unlock();
2313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_9() {
2353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  do {
2363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski    sls_mu.Lock(); // \
2372e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
2382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // expected-note{{mutex acquired here}}
2393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  } while (getBool());
2403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock();
2413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_10() {
2442e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
2454e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  while(getBool()) {
2462e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2482e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
2493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid sls_fun_bad_11() {
2512e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  while (getBool()) { // \
2522e5156274b8051217565b557bfa14c80f7990e9cRichard Smith   expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
2532e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    sls_mu.Lock(); // expected-note {{mutex acquired here}}
2543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  }
2553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  sls_mu.Unlock(); // \
2568bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'sls_mu' that was not locked}}
2573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
259aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smithvoid sls_fun_bad_12() {
2602e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  sls_mu.Lock(); // expected-note {{mutex acquired here}}
261aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  while (getBool()) {
262aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Unlock();
263aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    if (getBool()) {
264aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      if (getBool()) {
2652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
266aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith      }
267aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    }
268aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith    sls_mu.Lock();
269aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  }
270aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith  sls_mu.Unlock();
271aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith}
272aacde7174af6c5759b52dc0ceb7b167d323afb6aRichard Smith
2733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski//-----------------------------------------//
2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// Handling lock expressions in attribute args
2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski// -------------------------------------------//
2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiMutex aa_mu;
2783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskiclass GlobalLocker {
2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskipublic:
2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  void globalUnlock() __attribute__((unlock_function(aa_mu)));
2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski};
2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin SadowskiGlobalLocker glock;
2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_1() {
2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_1() {
2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock(); // \
2948bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{unlocking 'aa_mu' that was not locked}}
2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_2() {
2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock();
2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalLock(); // \
3008bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning{{locking 'aa_mu' that is already locked}}
3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski  glock.globalUnlock();
3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski}
3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski
3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskivoid aa_fun_bad_3() {
3052e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  glock.globalLock(); // expected-note{{mutex acquired here}}
3062e5156274b8051217565b557bfa14c80f7990e9cRichard Smith} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
307b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
308b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
309b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Regression tests for unusual method names
310b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski//--------------------------------------------------//
311b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
312b4d0a9678f8c592990593233e64c59247f40a74aCaitlin SadowskiMutex wmu;
313b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
314b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski// Test diagnostics for other method names.
315b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowskiclass WeirdMethods {
316b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
319b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
322b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
325b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
327b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
3282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
329b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
330b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
33105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
33205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
33305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
33405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
33505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
33605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
33705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
33805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
33905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
34005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
34105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
34205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
34305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
34405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
34574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
34674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
34774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
34874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
34974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
35074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
35174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
35205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
35305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
35405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
35505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
35605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
35705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
35805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
35905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
36005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
36174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
36205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
363af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
364af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
365af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
366af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
36705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
36805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
36905b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
37005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
37205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
37305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
37405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
37505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
37605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
37805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
37905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
38405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
38505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
38605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
38705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
38905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
39005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
39105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
39305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
39474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
39505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
39974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
40005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
40105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
40305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
40474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
40505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
40605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
40805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
40974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
41005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
41474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
41505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
41974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
42005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
42474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
42505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
42974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
43005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
43574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
43605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
44074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
44274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
44474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
445a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
44674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
448b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
449eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
450eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
451eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
452eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
453eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
454eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
455eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
456eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
457eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
458eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
459eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
460eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
461eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
46274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
463eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
46474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading variable 'a' requires locking 'mu'}}
465eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
46674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
467eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
468eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
469eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
470eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
471eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
472eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
473eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
47499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
47599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
47699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
47799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
47899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
47999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
48099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
48199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
48299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
48399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
48499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
48599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
48699107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
48799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
48899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
48999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
49099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
49199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
49299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
49399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
49499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
49599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
49699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
49799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
49899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
49999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
50099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
50199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
50299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
50399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
50499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
50599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
50699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
50799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
50874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
50999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
51099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
51199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
51299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
51399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
51499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
51599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
51699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
51799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
51874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
51999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
52874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
52999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
53674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
53799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
54474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
54599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
54699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
548a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
549a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
550a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
551a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
552a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
553a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
554a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
555a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
556a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
557a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
558a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
559a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
560a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
561a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
5624e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
56374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
564a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
565a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
5664e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
5674e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
568a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
569a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
570a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
571a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
572a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
573a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
574a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
575a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
576a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
577a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
578a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
579a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
580a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
581a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
582a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
583a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
584a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
585a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
586a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
587a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
588a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
589a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
590a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
591a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
592a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
59374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
594a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
595a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
5968bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
597a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
598a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
599a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6014e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
60274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
603a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
604a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6054e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
6064e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
607a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
608a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
609a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
610a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
611a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
613a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
61474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
615a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6178bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
618a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
62574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
626a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
6288bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
629a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
632978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
633978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
634978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
635978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
636978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
637978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
638978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
639978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
640978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
641978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
642978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
643978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
644978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
645978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
646978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
647978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
648978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
649978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
650978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
651978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
652978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
653978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
654978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
655978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
656978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
657978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
658978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
659978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
660978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
661978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
662978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
663978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
664978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
665978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
666978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
667978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
668978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
669978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
670978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
671978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
672978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
673978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
674978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
675978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
676978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
677978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
678978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
679978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
682978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
683978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
692978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
693978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
697978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
698978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
699af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
700af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
701af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
702af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
703af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
704af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
705cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
706cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
707cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
708cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
709cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
710cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
711cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
712cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
713cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
714cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
715978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7178bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
718978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7238bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
724978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
7298bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
730978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7348bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
735978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
7398bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
740978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
741978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
742978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
743978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
744978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7458bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
746978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
747978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
748978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
749978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
750978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
751978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
75274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
753978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
754978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
755978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
756978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
757978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
758978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
75974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
760978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
761978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
762194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
7638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
764194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
765194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
766194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
767194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
768194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin SadowskiMutex UPmu;
769194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// FIXME: add support for lock expressions involving arrays.
770194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin SadowskiMutex mua[5];
771194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
772f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsint x __attribute__((guarded_by(UPmu = sls_mu)));
773f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsint y __attribute__((guarded_by(mua[0])));
774194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
775194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
776194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid testUnparse() {
777f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  x = 5; // \
778f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
779f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  y = 5; // \
780f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
781194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
782194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
783194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid testUnparse2() {
784194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  mua[0].Lock(); // \
785f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
786194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  (&(mua[0]) + 4)->Lock(); // \
787f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
788194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
789194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
790988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
791988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
792988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
793988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
794988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
795988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
796988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
797988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
798988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
799988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
800988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
801988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
802988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
803988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
804988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
805988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
806988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
807988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
808988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
809988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
810988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
811988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
812988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
813988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
814988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
815988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
816988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
106223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
106723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 5.2;
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    g = 2.3;
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
119874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
120474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 2.5;
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
123274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1245988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
126174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
126274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
126374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
126474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
126574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
126674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
126774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
126974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
127074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
1291988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
129274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski     child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
1293988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1295988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1296988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
132974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
136874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
136974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
140374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1404988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
140874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
1436988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
1438988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14438121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14448121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14458121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14468121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14478121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14488121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
14498121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)))           { }
14508121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14518121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14528121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14538121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14548121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14558121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14568121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14578121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
14588121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
14598121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14608121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14618121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14628121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
14658121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14668121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
14678121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
14688121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14698121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
14708121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14718121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14728121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
14738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
14758121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14768121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
14778121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14788121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14798121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14812e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
14828121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
14838121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{unlocking 'mu' that was not locked}}
14842e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    } // expected-warning {{mutex 'mu' is still locked at the end of function}}
14858121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
14878121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14888121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
14928121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14938121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14948121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1496e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1497f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1498e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1499e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1500e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1501e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1502e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1503e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1504e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1505e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1506e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1507e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1508e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15096db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1510e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1511e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1512e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1513e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1514f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1515f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsnamespace invalid_lock_expression_test {
1516f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1517f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsclass LOCKABLE MyLockable {
1518f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinspublic:
1519f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable() __attribute__((exclusive_lock_function)) { }
15206db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins  ~MyLockable() { }
1521f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins};
1522f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1523f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins// create an empty lock expression
1524f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsvoid foo() {
1525f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable lock;  // \
1526f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning {{cannot resolve lock expression}}
1527f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins}
1528f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1529f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins} // end namespace invalid_lock_expression_test
1530f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
153197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1532f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
153397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
153497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
153597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
153697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
153797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1538a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1539a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1540a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1541a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1542a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1543a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
154497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
154597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
154697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
154797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1548a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
154997f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith      return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
155097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
155197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
155297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1553f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
155497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1555601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1556601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1557601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1558601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1559601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1560601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1561601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1562601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1563601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1564601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1565601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
1566601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1567601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1568601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1569601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
157097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15711fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15721fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15731fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15741fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15751fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15761fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15771fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15781fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
15791fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15801fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
15811fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15821fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
15831fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
15841fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
15851fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15861fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15871fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
15881fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
15891fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
15901fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
15911fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }   // expected-warning {{unlocking 'mu1' that was not locked}}
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1615df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1616df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1617df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1618df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1619df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1620df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1621df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1622df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1623df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1624df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1625df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1626df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1627df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1628df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
1629df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1630df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1631df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1632df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1633df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1634df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1635df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1637b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1638b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1639b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1640b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1641b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1642b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1643b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1644b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1645b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1646b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1647b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1648b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1649b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1650b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1651b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1652b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1653b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1654b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1655b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1656b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1657b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1658b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {    // b should be unknown at this point, becuase of the join point
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
17527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
17547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
17567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
17577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
17607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
17627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
17697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
17717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
17727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
17747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
17757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
17767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
17797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
17807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
17847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
17857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
179823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
183823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
183923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
184023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
184123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
184223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
184323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
184423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
184523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
184623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
184723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
184823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
184923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
185123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
185223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
185323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
185523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
185623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
185723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
18587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
185923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
186023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
186123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
186223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
186323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
186423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
186623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
186723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
186923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
187023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
187123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
187223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
187323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
187423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
187623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
187723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
187923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
18807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
18817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1885e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1886e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1887e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1888e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1889e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1890e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1891e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1892e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1893e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1894e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1895e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1896e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1897e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1898e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1899e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1900e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1901e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1902e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1903e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
1904e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1905e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1906e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1907e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1908e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1909e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19102e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19112e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19142e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19152e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19192e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19292e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19302e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19312e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19352e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19372e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1939c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1940c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1941c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1942c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1943c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1944c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1945c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1946c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
1947c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
1948c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
1949c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1950c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1951c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
1952c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1953c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1954c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
1955c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1956c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1957c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
1958c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1959c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1960c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1961c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
1962c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1963c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
1964c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1965c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1966c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
1967c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1968c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1969c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1970c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
1971c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
1972c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1973c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1974c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1975c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
1976c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1977c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1978c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
1979c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
1980c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1981c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1982c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1983c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1984c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
1985c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1986c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1987c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
1988c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1989c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
1990c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
1991c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);  // expected warning
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20524bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
20534bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20544bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20554bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
20564bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20574bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
20584bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
20594bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
20604bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20614bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
20624bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
20634bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20644bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
20654bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
20664bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
20674bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
20684bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
20694bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
20704bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20714bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
20724bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
20734bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
20744bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20754bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
20764bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
20774bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
20784bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2079c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2080c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20814bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
20824bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20834bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2084