warn-thread-safety-analysis.cpp revision dd5756c04c98e354b85c4f7eb660ae60c6d341ec
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
769194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin SadowskiMutex UPmu;
770194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski// FIXME: add support for lock expressions involving arrays.
771194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin SadowskiMutex mua[5];
772194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
773f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsint x __attribute__((guarded_by(UPmu = sls_mu)));
774f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsint y __attribute__((guarded_by(mua[0])));
775194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
776194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
777194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid testUnparse() {
778f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  x = 5; // \
779f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
780f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  y = 5; // \
781f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
782194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
783194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
784194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowskivoid testUnparse2() {
785194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  mua[0].Lock(); // \
786f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
787194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski  (&(mua[0]) + 4)->Lock(); // \
788f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning{{cannot resolve lock expression}}
789194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski}
790194418f1db5f5f78bc3e614d1e10a863455d882cCaitlin Sadowski
791988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
792988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
793988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// The following test cases are ported from the gcc thread safety implementation
794988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// They are each wrapped inside a namespace with the test number of the gcc test
795988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//
796988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// FIXME: add all the gcc tests, once this analysis passes them.
797988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//----------------------------------------------------------------------------//
798988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
799988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
800988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Good testcases (no errors)
801988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
802988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
803988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_20 {
804988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
805988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
806988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
807988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int b_ GUARDED_BY(mu1_);
808988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static Mutex mu1_;
809988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  static int a_ GUARDED_BY(mu1_);
810988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
811988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
812988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1;
813988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
814988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Bar::func1()
815988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
816988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res = 5;
817988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
818988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (a_ == 4)
819988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    res = b_;
820988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
821988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
822988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_20
823988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
824988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_22 {
825988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
826988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
827988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
828988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
829988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
830988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
831988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
832988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
833988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
834988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
835988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
836988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
837988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
838988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
839988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
840988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
841988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
842988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
843988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
844988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
845988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Lock();
846988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = b1.a_ + b3->b_;
847988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  *p = i;
848988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.a_ = res + b3->b_;
849988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->b_ = *b1.q;
850988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.mu1_.Unlock();
851988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1.b_ = res;
852988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = res;
853988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
854988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
855988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
856988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_22
857988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
858988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_27_modified {
859988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// test lock annotations applied to function definitions
860988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: applied annotations only to function declarations
861988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
862988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2 ACQUIRED_AFTER(mu1);
863988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
864988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
865988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
866988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
867988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
868988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
869988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
870988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
871988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
872988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
873988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
874988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
875988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint foo(int i) {
876988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
877988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
878988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
879988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
880988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskistatic int bar(int i) {
881988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return i;
882988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
883988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
884988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
885988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
886988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
887988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Lock();
888988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
889988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
890988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo(2);
891988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
892988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar(3);
893988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu1.Unlock();
894988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
895988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_27_modified
896988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
897988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
898988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_38 {
899988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the case where a template member function is annotated with lock
900988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// attributes in a non-template class.
901988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
902988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
903988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func1(int y) LOCKS_EXCLUDED(mu_);
904988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
905988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
906988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
907988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
908988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
909988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
910988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
911988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
912988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
913988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func1(5);
914988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func2(5);
915988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
916988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_38
917988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
918988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_43 {
919988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests lock canonicalization
920988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
921988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
922988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu_;
923988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
924988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
925988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass FooBar {
926988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
927988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo_;
928988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
929988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(foo_->mu_);
930988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
931988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
932988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFooBar *fb;
933988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
934988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
935988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
936988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
937988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Lock();
938988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = fb->GetA();
939988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  fb->foo_->mu_->Unlock();
940988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
941988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_43
942988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
943988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_49 {
944988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for use of lock expression in the annotations
945988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
946988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
947988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex foo_mu_;
948988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
949988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
950988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
951988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
952988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *foo;
953988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
954988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
955988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
956988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Test1() {
957988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Lock();
958988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Lock();
959988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    bar_mu_.Unlock();
960988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    foo->foo_mu_.Unlock();
961988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
962988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
963988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
964988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
965988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar bar;
966988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar.Test1();
967988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
968988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_49
969988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
970988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_61_modified {
971988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Modified to fix the compiler errors
972988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // Test the fix for a bug introduced by the support of pass-by-reference
973988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  // paramters.
974988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo { Foo &operator<< (bool) {return *this;} };
975988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo &getFoo();
976988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bar { Foo &func () {return getFoo();} };
977988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Bas { void operator& (Foo &) {} };
978988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void mumble()
979988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  {
980988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "" << "";
981988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    Bas() & Bar().func() << "";
982988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
983988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_61_modified
984988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
985988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
986988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_65 {
987988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the fix for a bug in the support of allowing reader locks for
988988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// non-const, non-modifying overload functions. (We didn't handle the builtin
989988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// properly.)
990988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskienum MyFlags {
991988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Zero,
992988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  One,
993988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Two,
994988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Three,
995988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Four,
996988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Five,
997988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Six,
998988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Seven,
999988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Eight,
1000988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Nine
1001988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1002988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1003988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags
1004988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|(MyFlags a, MyFlags b)
1005988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1006988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1007988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1008988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1009988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiinline MyFlags&
1010988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskioperator|=(MyFlags& a, MyFlags b)
1011988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1012988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return a = a | b;
1013988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1014988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_65
1015988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1016988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_66_modified {
1017988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Moved annotation to function defn
1018988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1019988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1020988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1021988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1022988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1023988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1024988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1025988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1026988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1027988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1028988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1029988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1030988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i)
1031988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1032988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1033988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1034988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1035988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1036988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1037988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1038988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1039988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Lock();
1040988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Lock();
1041988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Lock();
1042988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1);
1043988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu.Unlock();
1044988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu1->Unlock();
1045988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.mu2->Unlock();
1046988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1047988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_66_modified
1048988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1049988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_68_modified {
1050988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test a fix to a bug in the delayed name binding with nested template
1051988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// instantiation. We use a stack to make sure a name is not resolved to an
1052988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// inner context.
1053988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1054988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1055988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1056988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1057988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1058988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskitemplate <typename T>
1059988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1060988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1061988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void func(T x) {
1062988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Lock();
106323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    count_ = x;
1064988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu_.Unlock();
1065988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1066988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1067988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
106823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T count_ GUARDED_BY(mu_);
1069988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Bar<T> bar_;
1070988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1071988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1072988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1073988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1074988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1075988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo<int> *foo;
1076988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->func(5);
1077988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1078988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_68_modified
1079988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1080988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_30_modified {
1081988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test delay parsing of lock attribute arguments with nested classes.
1082988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: trylocks replaced with exclusive_lock_fun
1083988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint a = 0;
1084988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1085988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1086988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  struct Foo;
1087988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1088988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1089988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1090988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1091988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int func() {
1092988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    MyLock();
1093988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    if (foo == 0) {
1094988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//      return 0;
1095988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//    }
1096988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a = 5;
1097988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu.Unlock();
1098988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    return 1;
1099988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1100988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1101988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class FooBar {
1102988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int x;
1103988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    int y;
1104988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  };
1105988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1106988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1107988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu;
1108988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1109988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1110988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *bar;
1111988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1112988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1113988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1114988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bar->func();
1115988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1116988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_30_modified
1117988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1118988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_47 {
1119988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1120988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// This is a good test case. (i.e. There should be no warning emitted by the
1121988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// compiler.)
1122988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1123988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1124988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1125988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1126988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1127988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1128988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1129988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1130988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1131988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1132988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1133988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1134988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1135988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1136988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1137988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1138988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1139988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
1140988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1();
1141988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1142988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func2();
1143988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1144988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
1145988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1();
1146988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1147988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func2();
1148988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1149988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_47
1150988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1151988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1152988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Tests which produce errors
1153988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski//-----------------------------------------//
1154988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1155988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_13 {
1156988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu1;
1157988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu2;
1158988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1159988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint g GUARDED_BY(mu1);
1160988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint w GUARDED_BY(mu2);
1161988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1162988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1163988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1164988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar() LOCKS_EXCLUDED(mu_, mu1);
1165988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1166988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1167988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1168988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu_);
1169988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1170988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_ ACQUIRED_AFTER(mu1);
1171988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1172988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1173988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::foo()
1174988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1175988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int res;
1176988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 5.2;
1177988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  res = a_ + 5;
1178988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return res;
1179988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1180988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1181988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar()
1182988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1183988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1184988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Lock();
1185988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1186988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = x + 1;
1187988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu_.Unlock();
1188988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  if (x > 5) {
1189988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Lock();
1190988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    g = 2.3;
1191988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu1.Unlock();
1192988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1193988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1194988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1195988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1196988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1197988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo f1, *f2;
1198988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Lock();
119974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1200988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1201988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.foo();
1202988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1203988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f1.mu_.Unlock();
1204988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Lock();
120574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
1206988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  f2->mu_.Unlock();
1207988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Lock();
1208988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  w = 2.5;
1209988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  mu2.Unlock();
1210988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1211988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_13
1212988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1213988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_18_modified {
1214988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: Trylocks removed
1215988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the ability to distnguish between the same lock field of
1216988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// different objects of a class.
1217988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  class Bar {
1218988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1219988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1220988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void MyUnlock() UNLOCK_FUNCTION(mu1_);
1221988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1222988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1223988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1224988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_;
1225988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1226988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1227988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar *b1, *b2;
1228988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1229988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1230988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1231988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyLock();
1232988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->a_ = 5;
123374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
1234988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyLock();
1235988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b2->MyUnlock();
1236988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b1->MyUnlock();
1237988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1238988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_18_modified
1239988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1240988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_21 {
1241988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1242988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// uses in class definitions.
1243988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1244988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1245988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Bar {
1246988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1247988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(mu1_);
1248988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int b_;
1249988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int *q PT_GUARDED_BY(mu);
1250988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1_ ACQUIRED_AFTER(mu);
1251988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1252988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1253988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiBar b1, *b3;
1254988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1255988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1256988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint res GUARDED_BY(mu) = 5;
1257988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1258988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint func(int i)
1259988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1260988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x;
1261988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Lock();
126274558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
126374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
126474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
126574558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
126674558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
126774558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
126874558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1269988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b3->mu1_.Unlock();
127074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
127174558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1272988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return x;
1273988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1274988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_21
1275988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1276988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_35_modified {
1277988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1278988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects.
1279988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1280988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1281988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1282988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1283988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1284988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1285988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1286988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     Foo *new_foo = new Foo;
1287988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1288988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Lock();
1289988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1290988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->Func(new_foo); // There shouldn't be any warning here as the
1291988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski                           // acquired lock is not in child.
1292988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
129374558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski     child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
1294988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski     lock_.Unlock();
1295988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1296988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1297988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1298988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    a_ = y;
1299988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1300988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1301988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1302988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1303988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1304988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1305988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1306988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1307988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1308988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_35_modified
1309988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1310988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_36_modified {
1311988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified to move the annotations to function defns.
1312988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the analyzer's ability to distinguish the lock field of different
1313988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// objects
1314988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1315988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1316988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex lock_;
1317988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int a_ GUARDED_BY(lock_);
1318988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1319988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1320988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1321988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1322988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1323988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1324988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::Func(Foo* child) {
1325988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *new_foo = new Foo;
1326988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1327988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Lock();
1328988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1329988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Lock();
133074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
1331988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->bar(7);
1332988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->a_ = 5;
1333988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  child->lock_.Unlock();
1334988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1335988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  lock_.Unlock();
1336988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1337988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1338988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid Foo::bar(int y) {
1339988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a_ = y;
1340988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1341988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1342988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1343988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *x;
1344988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1345988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1346988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo *child = new Foo;
1347988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  x->Func(child);
1348988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1349988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_36_modified
1350988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1351988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1352988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_42 {
1353988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test support of multiple lock attributes of the same kind on a decl.
1354988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1355988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski private:
1356988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu1, mu2, mu3;
1357988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1358988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int y GUARDED_BY(mu2);
1359988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1360988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1361988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Lock();
1362988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    y = 2;
1363988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    mu2.Unlock();
1364988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1365988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1366988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1367988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1368988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    x = 5;
136974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
137074558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1371988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  }
1372988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1373988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1374988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiFoo *foo;
1375988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1376988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid func()
1377988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1378988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
1379988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
1380988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1381988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_42
1382988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1383988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_46 {
1384988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test the support for annotations on virtual functions.
1385988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Base {
1386988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1387988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1388988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1389988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex mu_;
1390988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1391988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1392988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Child : public Base {
1393988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1394988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1395988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  virtual void func2() LOCKS_EXCLUDED(mu_);
1396988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1397988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1398988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main() {
1399988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Child *c;
1400988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Base *b = c;
1401988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1402988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1403988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Lock();
140474558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1405988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  b->mu_.Unlock();
1406988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1407988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
1408988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Lock();
140974558b4c2f4136b0d89bbaa974df1070593b355aCaitlin Sadowski  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
1410988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  c->mu_.Unlock();
1411988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1412988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_46
1413988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1414988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskinamespace thread_annot_lock_67_modified {
1415988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Modified: attributes on definitions moved to declarations
1416988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// Test annotations on out-of-line definitions of member functions where the
1417988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski// annotations refer to locks that are also data members in the class.
1418988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu;
1419988b5ae14c2157cef36cc5850b294130846c578eCaitlin SadowskiMutex mu3;
1420988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1421988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiclass Foo {
1422988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski public:
1423988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1424988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  int data GUARDED_BY(mu1);
1425988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu1;
1426988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Mutex *mu2;
1427988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski};
1428988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1429988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskiint Foo::method1(int i) {
1430988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  return data + i;
1431988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1432988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1433988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowskivoid main()
1434988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski{
1435988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  Foo a;
1436988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
1437988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1438988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
1439988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1440988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski}
1441988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski} // end namespace thread_annot_lock_67_modified
1442988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
1443988b5ae14c2157cef36cc5850b294130846c578eCaitlin Sadowski
14448121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchinsnamespace substitution_test {
14458121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class MyData  {
14468121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14478121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    Mutex mu;
14488121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14498121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData()    __attribute__((exclusive_lock_function(mu)))   { }
14508121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData()  __attribute__((unlock_function(mu)))           { }
14518121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14528121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void doSomething() __attribute__((exclusive_locks_required(mu)))  { }
14538121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14548121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14558121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14568121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class DataLocker {
14578121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14588121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void lockData  (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { }
14598121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void unlockData(MyData *d) __attribute__((unlock_function(d->mu)))         { }
14608121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14618121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14628121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14638121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  class Foo {
14648121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  public:
14658121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
14668121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14678121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar1(MyData* d) {
14688121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->lockData();
14698121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14708121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      d->unlockData();
14718121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14728121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14738121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar2(MyData* d) {
14748121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14758121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d);
14768121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d);
14778121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d);
14788121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14798121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14808121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar3(MyData* d1, MyData* d2) {
14818121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14822e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      dlr.lockData(d1);   // expected-note {{mutex acquired here}}
14838121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d2); // \
14848121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{unlocking 'mu' that was not locked}}
14852e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    } // expected-warning {{mutex 'mu' is still locked at the end of function}}
14868121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
14878121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    void bar4(MyData* d1, MyData* d2) {
14888121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      DataLocker dlr;
14898121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.lockData(d1);
14908121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      foo(d2); // \
14918121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins        // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
14928121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins      dlr.unlockData(d1);
14938121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins    }
14948121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins  };
14958121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins} // end namespace substituation_test
14968121639910129a2b59aa85fc597e47cacad8b978DeLesley Hutchins
1497e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1498f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1499e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchinsnamespace constructor_destructor_tests {
1500e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  Mutex fooMu;
1501e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  int myVar GUARDED_BY(fooMu);
1502e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1503e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  class Foo {
1504e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  public:
1505e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    Foo()  __attribute__((exclusive_lock_function(fooMu))) { }
1506e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    ~Foo() __attribute__((unlock_function(fooMu))) { }
1507e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  };
1508e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1509e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  void fooTest() {
15106db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins    Foo foo;
1511e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins    myVar = 0;
1512e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins  }
1513e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins}
1514e0eaa8531f8fd9189710aac3b6f3aadb62bb14d1DeLesley Hutchins
1515f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1516f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsnamespace invalid_lock_expression_test {
1517f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1518f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsclass LOCKABLE MyLockable {
1519f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinspublic:
1520f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable() __attribute__((exclusive_lock_function)) { }
15216db51f707e93816364039a2a904d13d3968c7f05DeLesley Hutchins  ~MyLockable() { }
1522f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins};
1523f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1524f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins// create an empty lock expression
1525f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchinsvoid foo() {
1526f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins  MyLockable lock;  // \
1527f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins    // expected-warning {{cannot resolve lock expression}}
1528f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins}
1529f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
1530f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins} // end namespace invalid_lock_expression_test
1531f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
153297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smithnamespace template_member_test {
1533f1ac63702143d84db778d32eb185a77fc97db5f5DeLesley Hutchins
153497f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct S { int n; };
153597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct T {
153697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    Mutex m;
153797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    S *s GUARDED_BY(this->m);
153897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
1539a01c71191c93691e592c030cc48764e52272eea5Richard Smith  Mutex m;
1540a01c71191c93691e592c030cc48764e52272eea5Richard Smith  struct U {
1541a01c71191c93691e592c030cc48764e52272eea5Richard Smith    union {
1542a01c71191c93691e592c030cc48764e52272eea5Richard Smith      int n;
1543a01c71191c93691e592c030cc48764e52272eea5Richard Smith    };
1544a01c71191c93691e592c030cc48764e52272eea5Richard Smith  } *u GUARDED_BY(m);
154597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
154697f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  template<typename U>
154797f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  struct IndirectLock {
154897f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    int DoNaughtyThings(T *t) {
1549a01c71191c93691e592c030cc48764e52272eea5Richard Smith      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
155097f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith      return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
155197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith    }
155297f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith  };
155397f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1554f11e923433b62efb0fbaeb2573e8457f1c4a1b1eRichard Smith  template struct IndirectLock<int>; // expected-note {{here}}
155597f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith
1556601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  struct V {
1557601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(int);
1558601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(double);
1559601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
1560601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    Mutex m;
1561601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V *p GUARDED_BY(this->m);
1562601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1563601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template<typename U> struct W {
1564601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    V v;
1565601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    void f(U u) {
1566601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
1567601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith    }
1568601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  };
1569601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith  template struct W<int>; // expected-note {{here}}
1570601d2ee8dd783503f9d556e1ed3b107abf196a1eRichard Smith
157197f9fe06e7acd55d7d9075a41e33f54855c75eaeRichard Smith}
15721fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15731fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsnamespace test_scoped_lockable {
15741fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15751fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchinsstruct TestScopedLockable {
15761fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu1;
15771fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  Mutex mu2;
15781fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int a __attribute__((guarded_by(mu1)));
15791fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  int b __attribute__((guarded_by(mu2)));
15801fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15811fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  bool getBool();
15821fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15831fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo1() {
15841fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock(&mu1);
15851fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = 5;
15861fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15871fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
15881fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo2() {
15891fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    ReaderMutexLock mulock1(&mu1);
15901fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    if (getBool()) {
15911fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2a(&mu2);
15921fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 1;
15931fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15941fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    else {
15951fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      MutexLock mulock2b(&mu2);
15961fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      b = a + 2;
15971fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    }
15981fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
15991fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16001fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo3() {
16011fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_a(&mu1);
16021fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock_b(&mu1); // \
16031fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins      // expected-warning {{locking 'mu1' that is already locked}}
16041fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }   // expected-warning {{unlocking 'mu1' that was not locked}}
16051fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16061fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  void foo4() {
16071fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    MutexLock mulock1(&mu1), mulock2(&mu2);
16081fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    a = b+1;
16091fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins    b = a+1;
16101fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins  }
16111fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins};
16121fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16131fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins} // end namespace test_scoped_lockable
16141fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
16151fa3c0682a52c45c4ad0be3a82d0c85f26657072DeLesley Hutchins
1616df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsnamespace FunctionAttrTest {
1617df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1618df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsclass Foo {
1619df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinspublic:
1620df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  Mutex mu_;
1621df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  int a GUARDED_BY(mu_);
1622df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};
1623df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1624df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley HutchinsFoo fooObj;
1625df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1626df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1627df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1628df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchinsvoid bar() {
1629df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
1630df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Lock();
1631df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  foo();
1632df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins  fooObj.mu_.Unlock();
1633df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins}
1634df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1635df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins};  // end namespace FunctionAttrTest
1636df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1637df49782c54802ca1a4c1d36d66186aa039f32aecDeLesley Hutchins
1638b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchinsstruct TestTryLock {
1639b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  Mutex mu;
1640b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  int a GUARDED_BY(mu);
1641b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  bool cond;
1642b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1643b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo1() {
1644b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (mu.TryLock()) {
1645b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 1;
1646b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1647b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1648b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1649b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1650b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo2() {
1651b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!mu.TryLock()) return;
1652b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 2;
1653b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1654b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1655b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1656b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo3() {
1657b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1658b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {
1659b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 3;
1660b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1661b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1662b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1663b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1664b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo4() {
1665b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1666b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (!b) return;
1667b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 4;
1668b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1669b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1670b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1671b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo5() {
1672b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (mu.TryLock()) {
1673b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = a + 1;
1674b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1675b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1676b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1677b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1678b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo6() {
1679b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1680b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    b = !b;
1681b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) return;
1682b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    a = 6;
1683b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    mu.Unlock();
1684b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1685b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1686b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo7() {
1687b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b1 = mu.TryLock();
1688b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = !b1;
1689b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b3 = !b2;
1690b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b3) {
1691b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 7;
1692b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1693b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1694b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1695b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1696b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: join points
1697b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo8() {
1698b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b  = mu.TryLock();
1699b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b2 = b;
1700b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (cond)
1701b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = true;
1702b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {    // b should be unknown at this point, becuase of the join point
1703b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1704b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1705b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b2) {   // b2 should be known at this point.
1706b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 8;
1707b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1708b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1709b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1710b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1711b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def-chains: back edges
1712b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo9() {
1713b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1714b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1715b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    for (int i = 0; i < 10; ++i);
1716b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1717b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    if (b) {  // b is still known, because the loop doesn't alter it
1718b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      a = 9;
1719b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      mu.Unlock();
1720b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1721b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1722b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1723b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  // Test use-def chains: back edges
1724b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  void foo10() {
1725b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    bool b = mu.TryLock();
1726b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1727b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    while (cond) {
1728b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      if (b) {   // b should be uknown at this point b/c of the loop
1729b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1730b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      }
1731b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins      b = !b;
1732b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins    }
1733b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins  }
1734b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins};  // end TestTrylock
1735b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
1736b4fa418a72759dfe34add850837965cbc00626e4DeLesley Hutchins
17377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsnamespace TestTemplateAttributeInstantiation {
17387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo1 {
17407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Foo2 {
17467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  int a GUARDED_BY(mu_);
17487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Bar {
17537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expressions in attributes on template functions
17557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
17577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    foo->a = 0;
17587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in attributes on template functions
17617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T>
17627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
17637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass BarT {
17707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 fooBase;
17727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T    fooBaseT;
17737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test non-dependent expression in ordinary method on template class
17757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
17767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBase.a = 0;
17777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in ordinary methods on template class
17807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
17817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent expressions in template method in template class
17857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  template <class T2>
17867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
17877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooBaseT.a = 0;
17887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    fooT->a = 0;
17897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
17907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
17917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
17927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinstemplate <class T>
17937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsclass Cell {
17947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinspublic:
17957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Mutex mu_;
17967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  // Test dependent guarded_by
17977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  T data GUARDED_BY(mu_);
17987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
179923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
18007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  void foo() {
18047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Lock();
18057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    data = 0;
18067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    mu_.Unlock();
18077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  }
18087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};
18097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchinsvoid test() {
18117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Bar b;
18127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  BarT<Foo2> bt;
18137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo1 f1;
18147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Foo2 f2;
18157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Lock();
18177b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Lock();
18187b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Lock();
18197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Lock();
18207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18217b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barND(&f1, &f2);
18227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  b.barD(&f1, &f2);
18237b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barND();
18247b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barD();
18257b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f2);
18267b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f1.mu_.Unlock();
18287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.barTD(&f1);  // \
18297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
18307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBase.mu_.Unlock();
18327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  bt.fooBaseT.mu_.Unlock();
18337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  f2.mu_.Unlock();
18347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  Cell<int> cell;
18367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.data = 0; // \
18377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins    // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
18387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins  cell.foo();
183923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Lock();
184023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.fooEx();
184123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  cell.mu_.Unlock();
184223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins}
184323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
184423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
184523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinstemplate <class T>
184623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsclass CellDelayed {
184723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinspublic:
184823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  // Test dependent guarded_by
184923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  T data GUARDED_BY(mu_);
1850dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static T static_data GUARDED_BY(static_mu_);
185123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
185323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = other->data;
185423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
185523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
185623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  template <class T2>
185723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
185823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    this->data = otherT->data;
185923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
18607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
186123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  void foo() {
186223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Lock();
186323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    data = 0;
186423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins    mu_.Unlock();
186523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  }
186623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
186723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  Mutex mu_;
1868dd5756c04c98e354b85c4f7eb660ae60c6d341ecDeLesley Hutchins  static Mutex static_mu_;
186923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins};
187023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchinsvoid testDelayed() {
187223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld;
187323323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  CellDelayed<int> celld2;
187423323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.foo();
187523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Lock();
187623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Lock();
187723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
187823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooEx(&celld2);
187923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.fooExT(&celld2);
188023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins
188123323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld2.mu_.Unlock();
188223323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins  celld.mu_.Unlock();
18837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins}
18847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins};  // end namespace TestTemplateAttributeInstantiation
18867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
18877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins
1888e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsnamespace FunctionDeclDefTest {
1889e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1890e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsclass Foo {
1891e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinspublic:
1892e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Mutex mu_;
1893e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  int a GUARDED_BY(mu_);
1894e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1895e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1896e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1897e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1898e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
1899e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid Foo::foo1(Foo *f_defined) {
1900e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  f_defined->a = 0;
1901e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
1902e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1903e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchinsvoid test() {
1904e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  Foo myfoo;
1905e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);  // \
1906e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins    // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
1907e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Lock();
1908e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.foo1(&myfoo);
1909e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins  myfoo.mu_.Unlock();
1910e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins}
1911e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins
1912e03b2b3ca9032b18fd1c3d0fca7692e4d2551277DeLesley Hutchins};
19132e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19142e5156274b8051217565b557bfa14c80f7990e9cRichard Smithnamespace GoingNative {
19152e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19162e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  struct __attribute__((lockable)) mutex {
19172e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void lock() __attribute__((exclusive_lock_function));
19182e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    void unlock() __attribute__((unlock_function));
19192e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    // ...
19202e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  };
19212e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool foo();
19222e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  bool bar();
19232e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  mutex m;
19242e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  void test() {
19252e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.lock();
19262e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    while (foo()) {
19272e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.unlock();
19282e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19292e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      if (bar()) {
19302e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        // ...
19312e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        if (foo())
19322e5156274b8051217565b557bfa14c80f7990e9cRichard Smith          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
19332e5156274b8051217565b557bfa14c80f7990e9cRichard Smith        //...
19342e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      }
19352e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      // ...
19362e5156274b8051217565b557bfa14c80f7990e9cRichard Smith      m.lock(); // expected-note {{mutex acquired here}}
19372e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    }
19382e5156274b8051217565b557bfa14c80f7990e9cRichard Smith    m.unlock();
19392e5156274b8051217565b557bfa14c80f7990e9cRichard Smith  }
19402e5156274b8051217565b557bfa14c80f7990e9cRichard Smith
19412e5156274b8051217565b557bfa14c80f7990e9cRichard Smith}
1942c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1943c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1944c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1945c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsnamespace FunctionDefinitionTest {
1946c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1947c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass Foo {
1948c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1949c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo1();
1950c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo2();
1951c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo3(Foo *other);
1952c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1953c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1954c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT1(const T& dummy1);
1955c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1956c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  template<class T>
1957c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
1958c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1959c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1960c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int a GUARDED_BY(mu_);
1961c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1962c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1963c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1964c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsclass FooT {
1965c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinspublic:
1966c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  void foo();
1967c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1968c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Mutex mu_;
1969c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  T a GUARDED_BY(mu_);
1970c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
1971c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1972c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1973c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
1974c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 1;
1975c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1976c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1977c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1978c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 2;
1979c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1980c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1981c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
1982c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  other->a = 3;
1983c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1984c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1985c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1986c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1987c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy1;
1988c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1989c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1990c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins/* TODO -- uncomment with template instantiation of attributes.
1991c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
1992c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid Foo::fooT2(const T& dummy2) {
1993c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = dummy2;
1994c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
1995c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins*/
1996c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
1997c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
1998c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 1;
1999c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2000c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2001c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f);
2002c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2003c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 2;
2004c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2005c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2006c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2007c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid fooF3(Foo *f) {
2008c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  f->a = 3;
2009c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2010c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2011c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinstemplate<class T>
2012c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2013c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  a = 0;
2014c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2015c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2016c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchinsvoid test() {
2017c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  int dummy = 0;
2018c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  Foo myFoo;
2019c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2020c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();        // \
2021c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
2022c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);  // \
2023c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
2024c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);  // \
2025c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
2026c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2027c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2028c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);  // expected warning
2029c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2030c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);  // \
2031c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
2032c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);  // \
2033c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
2034c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);  // \
2035c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
2036c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2037c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Lock();
2038c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo2();
2039c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.foo3(&myFoo);
2040c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.fooT1(dummy);
2041c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2042c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // FIXME: uncomment with template instantiation of attributes patch
2043c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  // myFoo.fooT2(dummy);
2044c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2045c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF1(&myFoo);
2046c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF2(&myFoo);
2047c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  fooF3(&myFoo);
2048c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFoo.mu_.Unlock();
2049c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
2050c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  FooT<int> myFooT;
2051c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins  myFooT.foo();  // \
2052c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins    // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
2053c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins}
2054c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20554bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace FunctionDefinitionTest
20564bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20574bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20584bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsnamespace SelfLockingTest {
20594bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20604bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinsclass LOCKABLE MyLock {
20614bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchinspublic:
20624bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  int foo GUARDED_BY(this);
20634bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20644bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION();
20654bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void unlock() UNLOCK_FUNCTION();
20664bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20674bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomething() {
20684bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->lock();  // allow 'this' as a lock expression
20694bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 0;
20704bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    doSomethingElse();
20714bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    this->unlock();
20724bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
20734bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20744bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
20754bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 1;
20764bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  };
20774bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
20784bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  void test() {
20794bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins    foo = 2;  // \
20804bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
20814bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins  }
2082c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins};
2083c24a2335677f3d1bd2cab1019ac445d650f52123DeLesley Hutchins
20842f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20852f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinsclass LOCKABLE MyLock2 {
20862f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchinspublic:
20872f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  Mutex mu_;
20882f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  int foo GUARDED_BY(this);
20892f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20902f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside lock and unlock functions
20912f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }
20922f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }
20932f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20942f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  // don't check inside constructors and destructors
20952f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  MyLock2()  { foo = 1; }
20962f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins  ~MyLock2() { foo = 0; }
20972f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins};
20982f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
20992f13bec63b0236b169b026b7bc852da51ee029a7DeLesley Hutchins
21004bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins} // end namespace SelfLockingTest
21014bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
21024bda3eca138d39585c9e475ad25aa9ff053f923bDeLesley Hutchins
2103