warn-thread-safety-analysis.cpp revision 0d95dfcc0e07a81596ab7c3e9e86ab663fd4541c
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 {
3162f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // FIXME: can't currently check inside constructors and destructors.
317b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  WeirdMethods() {
3182f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3192f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
320b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  ~WeirdMethods() {
3212f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
3222f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
323b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  void operator++() {
3242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
3252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
326b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski  operator int*() {
3272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    wmu.Lock(); // expected-note {{mutex acquired here}}
328b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski    return 0;
3292e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
330b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski};
331b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
33205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski//-----------------------------------------------//
33305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// Errors for guarded by or guarded var variables
33405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski// ----------------------------------------------//
33505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
33605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_gvar __attribute__((pt_guarded_var));
33705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiint *pgb_var __attribute__((pt_guarded_by(sls_mu)));
33805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
33905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass PGBFoo {
34005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
34105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
34205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *pgb_field __attribute__((guarded_by(sls_mu2)))
34305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski                 __attribute__((pt_guarded_by(sls_mu)));
34405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
34505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    pgb_field = &x; // \
34674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
34774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
34874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
34974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
35074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
35174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
35274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
35305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
35405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
35505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
35605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskiclass GBFoo {
35705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski public:
35805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int gb_field __attribute__((guarded_by(sls_mu)));
35905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
36005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  void testFoo() {
36105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski    gb_field = 0; // \
36274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
36305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  }
364af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
365af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  void testNoAnal() __attribute__((no_thread_safety_analysis)) {
366af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski    gb_field = 0;
367af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  }
36805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski};
36905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37005b436ef550837e2141c55c590fb16010b8658d8Caitlin SadowskiGBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
37105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_0() {
37305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
37405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var;
37505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
37605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
37705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
37805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_1() {
37905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Lock();
38005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 2;
38105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_mu.Unlock();
38205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
38305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_2() {
38505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x;
38605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  pgb_var = &x;
38705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
38805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
38905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_fun_3() {
39005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int *x = pgb_var;
39105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
39205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_0() {
39405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var = 1; // \
39574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
39605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
39705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
39805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_1() {
39905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guard_var; // \
40074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
40105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
40205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_2() {
40405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guardby_var = 1; // \
40574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
40605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
40705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
40805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_3() {
40905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = sls_guardby_var; // \
41074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
41105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_4() {
41405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_gvar = 1; // \
41574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
41605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
41705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
41805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_5() {
41905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_gvar; // \
42074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
42105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_6() {
42405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  *pgb_var = 1; // \
42574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
42605b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
42705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
42805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_7() {
42905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  int x = *pgb_var; // \
43074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
43105b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43305b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_8() {
43405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  GBFoo G;
43505b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  G.gb_field = 0; // \
43674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
43705b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
43805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski
43905b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowskivoid gb_bad_9() {
44005b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var++; // \
44174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44205b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  sls_guard_var--; // \
44374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44405b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski  ++sls_guard_var; // \
44574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
446a49d1d8a34381802040c3d7fa218e93b457d2b1dCaitlin Sadowski  --sls_guard_var;// \
44774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
44805b436ef550837e2141c55c590fb16010b8658d8Caitlin Sadowski}
449b4d0a9678f8c592990593233e64c59247f40a74aCaitlin Sadowski
450eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski//-----------------------------------------------//
451eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// Warnings on variables with late parsed attributes
452eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski// ----------------------------------------------//
453eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
454eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskiclass LateFoo {
455eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowskipublic:
456eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int a __attribute__((guarded_by(mu)));
457eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int b;
458eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
459eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void foo() __attribute__((exclusive_locks_required(mu))) { }
460eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
461eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  void test() {
462eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    a = 0; // \
46374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
464eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    b = a; // \
46574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{reading variable 'a' requires locking 'mu'}}
466eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    c = 0; // \
46774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
468eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  }
469eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
470eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  int c __attribute__((guarded_by(mu)));
471eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
472eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  Mutex mu;
473eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski};
474eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
47599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskiclass LateBar {
47699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski public:
47799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int a_ __attribute__((guarded_by(mu1_)));
47899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int b_;
47999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int *q __attribute__((pt_guarded_by(mu)));
48099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu1_;
48199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
48299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo;
48399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo Foo2;
48499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo *FooPointer;
48599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski};
48699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
48799107ebc0a5aea953b736e12757e0919d5249d43Caitlin SadowskiLateBar b1, *b3;
48899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
48999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_0() {
49099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooA;
49199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo FooB;
49299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Lock();
49399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.a = 5;
49499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  FooA.mu.Unlock();
49599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
49699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
49799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_1() {
49899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
49999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
50099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2;
50199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
50299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
50399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
50499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_0() {
50599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooA;
50699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateFoo fooB;
50799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Lock();
50899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooB.a = 5; // \
50974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
51099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  fooA.mu.Unlock();
51199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
51299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
51399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_1() {
51499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  Mutex mu;
51599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Lock();
51699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Lock();
51799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  int res = b1.a_ + b3->b_;
51899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b3->b_ = *b1.q; // \
51974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
52099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.mu1_.Unlock();
52199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  b1.b_ = res;
52299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  mu.Unlock();
52399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
52499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
52599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_2() {
52699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
52799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Lock();
52899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.a = 2; // \
52974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
53099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->mu.Unlock();
53199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
53299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
53399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_3() {
53499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
53599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
53699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.FooPointer->a = 2; // \
53774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
53899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
53999107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54099107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
54199107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowskivoid late_bad_4() {
54299107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  LateBar BarA;
54399107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Lock();
54499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo2.a = 2; // \
54574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
54699107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski  BarA.Foo.mu.Unlock();
54799107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski}
54899107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski
549a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski//-----------------------------------------------//
550a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// Extra warnings for shared vs. exclusive locks
551a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski// ----------------------------------------------//
552a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
553a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_0() {
554a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Lock();
555a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
556a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
557a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
558a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
559a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
560a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
561a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
562a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_1() {
5634e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.ReaderLock(); // \
56474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
565a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
566a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
5674e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.Lock();  // \
5684e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
569a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
570a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
571a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
572a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
573a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_3() {
574a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
575a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
576a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
577a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock();
578a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
579a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
580a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
581a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
582a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_4() {
583a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
584a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
585a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
586a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock();
587a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  int x = sls_guardby_var;
588a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
589a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
590a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
591a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_fun_8() {
592a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
593a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
59474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
595a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
596a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
5978bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
598a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
599a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
600a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
601a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_0() {
6024e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski  sls_mu.Lock();  // \
60374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
604a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  do {
605a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Unlock();
6064e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski    sls_mu.ReaderLock();  // \
6074e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
608a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  } while (getBool());
609a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
610a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
611a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
612a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_1() {
613a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
614a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
61574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
616a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
617a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
6188bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
619a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
620a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
621a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
622a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski
623a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowskivoid shared_bad_2() {
624a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  if (getBool())
625a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.ReaderLock(); // \
62674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
627a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  else
628a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski    sls_mu.Lock(); // \
6298bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski      // expected-note {{the other lock of mutex 'sls_mu' is here}}
630a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  *pgb_var = 1;
631a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski  sls_mu.Unlock();
632a53257c94a4d871e64070f72edb687dcfb08c15dCaitlin Sadowski}
633978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
634978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski// FIXME: Add support for functions (not only methods)
635978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRBar {
636978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
637978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
638978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
639978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void le_fun() __attribute__((locks_excluded(sls_mu)));
640978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
641978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
642978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskiclass LRFoo {
643978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski public:
644978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void test() __attribute__((exclusive_locks_required(sls_mu)));
645978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  void testShared() __attribute__((shared_locks_required(sls_mu2)));
646978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski};
647978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
648978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
649978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid elr_fun() {}
650978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
651978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRFoo MyLRFoo;
652978191e0906606e32965cebcf81627d8e8711b13Caitlin SadowskiLRBar Bar;
653978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
654978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_0() {
655978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
656978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun();
657978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
658978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
659978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
660978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_1() {
661978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Lock();
662978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
663978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
664978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
665978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
666978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_2() {
667978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
668978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s();
669978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
670978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
671978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
672978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_3() {
673978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
674978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test();
675978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
676978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
677978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
678978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_4() {
679978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Lock();
680978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
681978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
682978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
683978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
684978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_5() {
685978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.ReaderLock();
686978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared();
687978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu2.Unlock();
688978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
689978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
690978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_6() {
691978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun();
692978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
693978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
694978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_fun_7() {
695978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
696978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  elr_fun();
697978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
698978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
699978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
700af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() __attribute__((no_thread_safety_analysis));
701af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
702af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowskivoid es_fun_8() {
703af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski  Bar.aa_elr_fun_s();
704af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski}
705af37061fea31f3f1d0638edb5486e8d72c701522Caitlin Sadowski
706cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() __attribute__((shared_locks_required(aa_mu)));
707cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_9() {
708cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
709cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
710cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
711cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
712cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowskivoid es_fun_10() {
713cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski  Bar.aa_elr_fun_s();
714cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski}
715cb96751b25a934b22402c1e4e0805db7608a5f2bCaitlin Sadowski
716978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_0() {
717978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7188bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
719978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
720978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
721978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_1() {
722978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.ReaderLock();
723978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun(); // \
7248bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
725978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  aa_mu.Unlock();
726978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
727978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
728978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_2() {
729978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.aa_elr_fun_s(); // \
7308bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
731978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
732978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
733978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_3() {
734978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7358bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
736978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
737978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
738978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_4() {
739978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.testShared(); // \
7408bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
741978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
742978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
743978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_5() {
744978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
745978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  MyLRFoo.test(); // \
7468bccabeac6b98650dfd88bd1fc84e841eb42af4bCaitlin Sadowski    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
747978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
748978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
749978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
750978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_6() {
751978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Lock();
752978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
75374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
754978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
755978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
756978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski
757978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowskivoid es_bad_7() {
758978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.ReaderLock();
759978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  Bar.le_fun(); // \
76074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
761978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski  sls_mu.Unlock();
762978191e0906606e32965cebcf81627d8e8711b13Caitlin Sadowski}
763194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
7648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
765194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski//-----------------------------------------------//
766194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// Unparseable lock expressions
767194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// ----------------------------------------------//
768194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
7690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins// FIXME -- derive new tests for unhandled expressions
770194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
771988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
772988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
773988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
774988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
775988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
776988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
777988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
778988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
779988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
780988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
781988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
782988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
783988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
784988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
785988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
786988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
787988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
788988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
789988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
790988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
791988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
792988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
793988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
794988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
795988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
796988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
797988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
798988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
799988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
800988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
801988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
802988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
803988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
804988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
805988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
806988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
807988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
808988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
809988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
810988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
811988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
812988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
813988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
814988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
815988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
816988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
104323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
104823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1063988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1068988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 5.2;
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    g = 2.3;
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
117974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
118574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 2.5;
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1199988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1205988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
121374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1233988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
124274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
124374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
124474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
124574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
124674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
124774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
124874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
125074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
125174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1261988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1262988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1263988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1264988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1265988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1266988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1267988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1268988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1270988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1271988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
127374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski     child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1291988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1292988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1293988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1295988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1296988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
131074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1330988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
134974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
135074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1369988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1370988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
138474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
138974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1404988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1409988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14248121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14258121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14268121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14278121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14288121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14298121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
14308121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)))           { }
14318121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14328121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14338121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14348121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14358121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14368121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14378121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14388121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
14398121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
14408121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14418121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14428121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14438121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14448121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14458121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
14468121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14478121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
14488121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
14498121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14508121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
14518121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14528121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14538121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
14548121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14558121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
14568121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14578121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
14588121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14598121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14608121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
14618121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14622e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
14638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
14648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{unlocking 'mu' that was not locked}}
14652e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    } // expected-warning {{mutex 'mu' is still locked at the end of function}}
14668121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14678121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
14688121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14698121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
14708121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
14718121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
14728121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
14738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14758121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
14768121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1477e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1478f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1479e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1480e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1481e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1482e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1483e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1484e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1485e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1486e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1487e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1488e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1489e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
14906db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1491e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1492e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1493e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1494e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1495f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1496f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsnamespace invalid_lock_expression_test {
1497f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1498f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsclass LOCKABLE MyLockable {
1499f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinspublic:
1500f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable() __attribute__((exclusive_lock_function)) { }
15016db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins  ~MyLockable() { }
1502f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins};
1503f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1504f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins// create an empty lock expression
1505f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsvoid foo() {
1506f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable lock;  // \
1507f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning {{cannot resolve lock expression}}
1508f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins}
1509f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1510f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins} // end namespace invalid_lock_expression_test
1511f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
151297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1513f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
151497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
151597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
151697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
151797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
151897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1519a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1520a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1521a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1522a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1523a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1524a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
152597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
152697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
152797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
152897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1529a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
153097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith      return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
153197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
153297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
153397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1534f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
153597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1536601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1537601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1538601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1539601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1540601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1541601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1542601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1543601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1544601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1545601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1546601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
1547601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1548601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1549601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1550601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
155197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15521fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15531fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15541fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15551fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15561fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15571fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15581fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15591fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
15601fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15611fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
15621fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15631fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
15641fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
15651fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
15661fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15671fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15681fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
15691fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
15701fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
15711fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
15721fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
15731fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15741fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
15751fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
15761fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
15771fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15781fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15791fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15801fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
15811fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
15821fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
15831fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
15841fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }   // expected-warning {{unlocking 'mu1' that was not locked}}
15851fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15861fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
15871fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
15881fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
15891fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
15901fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15911fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1596df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1597df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1598df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1599df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1600df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1601df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1602df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1603df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1604df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1605df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1606df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1607df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1608df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1609df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
1610df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1611df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1612df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1613df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1614df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1615df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1616df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1617df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1618b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1619b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1620b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1621b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1622b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1623b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1624b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1625b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1626b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1627b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1628b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1629b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1630b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1631b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1632b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1633b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1634b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1635b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1636b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1637b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1638b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1639b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1640b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1641b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1642b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1643b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1644b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1645b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1646b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1647b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1648b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1649b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1650b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1651b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1652b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1653b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1654b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1655b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1656b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1657b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1658b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {    // b should be unknown at this point, becuase of the join point
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
17337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
17357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
17377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
17387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
17417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
17437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
17507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
17527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
17537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
17557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
17567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
17577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
17607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
17617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
17657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
17667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
17677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
17747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
17777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
17787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
177923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
17807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
17817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
17847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
17857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
17997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
181923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
182023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
182123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
182223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
182323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
182423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
182523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
182623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
182723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
182823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
182923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1830dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
183123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
183223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
183323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
183423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
183523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
183623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
183723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
183823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
183923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
18407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
184123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
184223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
184323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
184423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
184523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
184623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
184723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1848dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
184923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
185023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
185223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
185323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
185423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
185523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
185623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
185723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
185923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
186023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
186223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
18637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
18647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
18667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1868e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1869e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1870e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1871e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1872e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1873e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1874e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1875e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1876e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1877e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1878e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1879e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1880e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1881e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1882e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1883e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1884e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1885e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1886e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
1887e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1888e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1889e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1890e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1891e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1892e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
18932e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
18942e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
18952e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
18962e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
18972e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
18982e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
18992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19002e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19012e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19032e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19042e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19052e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19062e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19072e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19082e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19092e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19102e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19112e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19122e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19142e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19152e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19192e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1922c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1923c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1924c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1925c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1926c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1927c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1928c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1929c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
1930c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
1931c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
1932c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1933c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1934c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
1935c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1936c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1937c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
1938c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1939c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1940c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
1941c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1942c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1943c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1944c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
1945c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1946c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
1947c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1948c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1949c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
1950c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1951c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1952c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1953c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
1954c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
1955c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1956c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1957c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1958c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
1959c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1960c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1961c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
1962c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
1963c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1964c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1965c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1966c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1967c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
1968c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1969c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1970c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
1971c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1972c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
1973c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
1974c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1975c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
1976c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1977c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
1978c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
1979c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1980c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1981c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
1982c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
1983c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
1984c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1985c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1986c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
1987c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
1988c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
1989c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1990c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1991c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);  // expected warning
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20354bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
20364bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20374bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20384bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
20394bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20404bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
20414bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
20424bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
20434bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20444bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
20454bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
20464bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20474bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
20484bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
20494bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
20504bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
20514bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
20524bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
20534bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20544bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
20554bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
20564bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
20574bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20584bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
20594bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
20604bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
20614bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2062c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2063c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20642f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20652f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
20662f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
20672f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
20682f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
20692f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20702f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
20712f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
20722f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
20732f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20742f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
20752f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
20762f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
20772f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
20782f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20792f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20804bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
20814bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20824bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2083d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsnamespace InvalidNonstatic {
2084d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2085d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// Forward decl here causes bogus "invalid use of non-static data member"
2086d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins// on reference to mutex_ in guarded_by attribute.
2087d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo;
2088d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2089d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchinsclass Foo {
2090d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  Mutex* mutex_;
2091d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2092d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins  int foo __attribute__((guarded_by(mutex_)));
2093d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins};
2094d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
2095d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins}  // end namespace InvalidNonStatic
2096d08d599da101f3fe3fd79e853f1dcea6be89d7c2DeLesley Hutchins
20972a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
20982a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsnamespace NoReturnTest {
20992a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21002a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsbool condition();
21012a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid fatal() __attribute__((noreturn));
21022a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21032a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley HutchinsMutex mu_;
21042a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21052a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchinsvoid test1() {
21062a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  MutexLock lock(&mu_);
21072a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  if (condition()) {
21082a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    fatal();
21092a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins    return;
21102a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins  }
21112a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins}
21122a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins
21132287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace NoReturnTest
21142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21152287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21162287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsnamespace TestMultiDecl {
21172287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21182287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsclass Foo {
21192287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinspublic:
21202287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) a;
21212287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  int GUARDED_BY(mu_) b, c;
21222287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21232287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  void foo() {
21242287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    a = 0; // \
21252287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
21262287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    b = 0; // \
21272287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
21282287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    c = 0; // \
21292287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
21302287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  }
21312287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21322287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchinsprivate:
21332287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  Mutex mu_;
21342a35be803c405221f5f23c7bdedb91f09efdd3acDeLesley Hutchins};
21352287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21362287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins} // end namespace TestMultiDecl
21372287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
21387ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21397ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsnamespace WarnNoDecl {
21407ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21417ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchinsclass Foo {
21427ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins  void foo(int a);  __attribute__(( // \
21437ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{declaration does not declare anything}}
21447ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    exclusive_locks_required(a))); // \
21457ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins    // expected-warning {{attribute exclusive_locks_required ignored}}
21467ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins};
21477ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21487ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins} // end namespace WarnNoDecl
21497ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21507ec419aa8f4ff83bc8ff707b45b9bec47fef3a1aDeLesley Hutchins
21510d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21520d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsnamespace MoreLockExpressions {
21530d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21540d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Foo {
21550d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
21560d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Mutex mu_;
21570d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a GUARDED_BY(mu_);
21580d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
21590d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21600d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsclass Bar {
21610d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinspublic:
21620d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
21630d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo* f;
21640d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21650d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo()              { return *f; }
21660d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo2(int c)        { return *f; }
21670d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFoo3(int c, int d) { return *f; }
21680d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21690d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo& getFooey() { return *f; }
21700d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins};
21710d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21720d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley HutchinsFoo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
21730d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21740d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchinsvoid test() {
21750d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo foo;
21760d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Foo *fooArray;
21770d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  Bar bar;
21780d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int a;
21790d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int b;
21800d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  int c;
21810d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21820d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
21830d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
21840d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
21850d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21860d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Lock();   // test parenthesis
21870d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().a = 0;
21880d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (bar.getFoo().mu_).Unlock();
21890d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21900d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
21910d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).a = 0;
21920d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
21930d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21940d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
21950d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).a = 0;
21960d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
21970d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
21980d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
21990d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).a = 0;
22000d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22010d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22020d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Lock();
22030d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).a = 0;
22040d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(10).mu_.Unlock();
22050d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22060d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Lock();
22070d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).a = 0;
22080d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a + 1).mu_.Unlock();
22090d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22100d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22110d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
22120d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22130d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22140d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Lock();
22150d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFooey().a = 0; // \
22160d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
22170d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo().mu_.Unlock();
22180d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22190d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Lock();
22200d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(b).a = 0; // \
22210d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
22220d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo2(a).mu_.Unlock();
22230d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22240d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Lock();
22250d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, c).a = 0;  // \
22260d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
22270d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  bar.getFoo3(a, b).mu_.Unlock();
22280d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22290d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Lock();
22300d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, b).a = 0;  // \
22310d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
22320d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  getBarFoo(bar, a).mu_.Unlock();
22330d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22340d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
22350d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
22360d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
22370d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
22380d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins}
22390d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22400d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22410d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins} // end namespace
22420d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
22430d95dfcc0e07a81596ab7c3e9e86ab663fd4541cDeLesley Hutchins
2244