brintos

brintos / llvm-project-archived public Read only

0
0
Text · 192.2 KiB · 0e91639 Raw
7625 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s4// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s5 6// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s7// FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety %s8 9#include "thread-safety-annotations.h"10 11class LOCKABLE Mutex {12 public:13  void Lock() EXCLUSIVE_LOCK_FUNCTION();14  void ReaderLock() SHARED_LOCK_FUNCTION();15  void Unlock() UNLOCK_FUNCTION();16  void ExclusiveUnlock() EXCLUSIVE_UNLOCK_FUNCTION();17  void ReaderUnlock() SHARED_UNLOCK_FUNCTION();18  bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);19  bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);20  void LockWhen(const int &cond) EXCLUSIVE_LOCK_FUNCTION();21 22  void PromoteShared() SHARED_UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();23  void DemoteExclusive() EXCLUSIVE_UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();24 25  // for negative capabilities26  const Mutex& operator!() const { return *this; }27 28  void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();29  void AssertReaderHeld() ASSERT_SHARED_LOCK();30};31 32class SCOPED_LOCKABLE MutexLock {33 public:34  MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);35  MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu);36  ~MutexLock() UNLOCK_FUNCTION();37};38 39class SCOPED_LOCKABLE ReaderMutexLock {40 public:41  ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu);42  ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu);43  ~ReaderMutexLock() UNLOCK_FUNCTION();44};45 46class SCOPED_LOCKABLE ReleasableMutexLock {47 public:48  ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);49  ~ReleasableMutexLock() UNLOCK_FUNCTION();50 51  void Release() UNLOCK_FUNCTION();52};53 54class SCOPED_LOCKABLE DoubleMutexLock {55public:56  DoubleMutexLock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);57  ~DoubleMutexLock() UNLOCK_FUNCTION();58};59 60template<typename Mu>61class SCOPED_LOCKABLE TemplateMutexLock {62public:63  TemplateMutexLock(Mu *mu) EXCLUSIVE_LOCK_FUNCTION(mu);64  ~TemplateMutexLock() UNLOCK_FUNCTION();65};66 67template<typename... Mus>68class SCOPED_LOCKABLE VariadicMutexLock {69public:70  VariadicMutexLock(Mus *...mus) EXCLUSIVE_LOCK_FUNCTION(mus...);71  ~VariadicMutexLock() UNLOCK_FUNCTION();72};73 74// The universal lock, written "*", allows checking to be selectively turned75// off for a particular piece of code.76void beginNoWarnOnReads()  SHARED_LOCK_FUNCTION("*");77void endNoWarnOnReads()    UNLOCK_FUNCTION("*");78void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");79void endNoWarnOnWrites()   UNLOCK_FUNCTION("*");80 81 82// For testing handling of smart pointers.83template<class T>84class SmartPtr {85public:86  SmartPtr(T* p) : ptr_(p) { }87  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }88  ~SmartPtr();89 90  T* get()        const { return ptr_; }91  T* operator->() const { return ptr_; }92  T& operator*()  const { return *ptr_; }93  T& operator[](int i) const { return ptr_[i]; }94 95private:96  T* ptr_;97};98 99template<typename T, typename U>100U& operator->*(const SmartPtr<T>& ptr, U T::*p) { return ptr->*p; }101 102 103// For testing destructor calls and cleanup.104class MyString {105public:106  MyString(const char* s);107  ~MyString();108};109 110 111// For testing operator overloading112template <class K, class T>113class MyMap {114public:115  T& operator[](const K& k);116};117 118 119// For testing handling of containers.120template <class T>121class MyContainer {122public:123  MyContainer();124 125  typedef T* iterator;126  typedef const T* const_iterator;127 128  T* begin();129  T* end();130 131  const T* cbegin();132  const T* cend();133 134  T&       operator[](int i);135  const T& operator[](int i) const;136 137private:138  T* ptr_;139};140 141 142 143Mutex sls_mu;144 145Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));146int sls_guard_var __attribute__((guarded_var)) = 0;147int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;148 149bool getBool();150 151class MutexWrapper {152public:153   Mutex mu;154   int x __attribute__((guarded_by(mu)));155   void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);156};157 158struct TestingMoreComplexAttributes {159   Mutex lock;160   struct { Mutex lock; } strct;161   union {162       bool a __attribute__((guarded_by(lock)));163       bool b __attribute__((guarded_by(strct.lock)));164       bool *ptr_a __attribute__((pt_guarded_by(lock)));165       bool *ptr_b __attribute__((pt_guarded_by(strct.lock)));166       Mutex lock1 __attribute__((acquired_before(lock))) __attribute__((acquired_before(strct.lock)));167       Mutex lock2 __attribute__((acquired_after(lock))) __attribute__((acquired_after(strct.lock)));168   };169} more_complex_atttributes;170 171void more_complex_attributes() {172    more_complex_atttributes.a = true; // expected-warning{{writing variable 'a' requires holding mutex 'lock' exclusively}}173    more_complex_atttributes.b = true; // expected-warning{{writing variable 'b' requires holding mutex 'strct.lock' exclusively}}174    *more_complex_atttributes.ptr_a = true; // expected-warning{{writing the value pointed to by 'ptr_a' requires holding mutex 'lock' exclusively}}175    *more_complex_atttributes.ptr_b = true; // expected-warning{{writing the value pointed to by 'ptr_b' requires holding mutex 'strct.lock' exclusively}}176 177    more_complex_atttributes.lock.Lock();178    more_complex_atttributes.lock1.Lock(); // expected-warning{{mutex 'lock1' must be acquired before 'lock'}}179    more_complex_atttributes.lock1.Unlock();180    more_complex_atttributes.lock.Unlock();181 182    more_complex_atttributes.lock2.Lock();183    more_complex_atttributes.lock.Lock(); // expected-warning{{mutex 'lock' must be acquired before 'lock2'}}184    more_complex_atttributes.lock.Unlock();185    more_complex_atttributes.lock2.Unlock();186}187 188MutexWrapper sls_mw;189 190void sls_fun_0() {191  sls_mw.mu.Lock();192  sls_mw.x = 5;193  sls_mw.mu.Unlock();194}195 196void sls_fun_2() {197  sls_mu.Lock();198  int x = sls_guard_var;199  sls_mu.Unlock();200}201 202void sls_fun_3() {203  sls_mu.Lock();204  sls_guard_var = 2;205  sls_mu.Unlock();206}207 208void sls_fun_4() {209  sls_mu2.Lock();210  sls_guard_var = 2;211  sls_mu2.Unlock();212}213 214void sls_fun_5() {215  sls_mu.Lock();216  int x = sls_guardby_var;217  sls_mu.Unlock();218}219 220void sls_fun_6() {221  sls_mu.Lock();222  sls_guardby_var = 2;223  sls_mu.Unlock();224}225 226void sls_fun_7() {227  sls_mu.Lock();228  sls_mu2.Lock();229  sls_mu2.Unlock();230  sls_mu.Unlock();231}232 233void sls_fun_8() {234  sls_mu.Lock();235  if (getBool())236    sls_mu.Unlock();237  else238    sls_mu.Unlock();239}240 241void sls_fun_9() {242  if (getBool())243    sls_mu.Lock();244  else245    sls_mu.Lock();246  sls_mu.Unlock();247}248 249void sls_fun_good_6() {250  if (getBool()) {251    sls_mu.Lock();252  } else {253    if (getBool()) {254      getBool(); // EMPTY255    } else {256      getBool(); // EMPTY257    }258    sls_mu.Lock();259  }260  sls_mu.Unlock();261}262 263void sls_fun_good_7() {264  sls_mu.Lock();265  while (getBool()) {266    sls_mu.Unlock();267    if (getBool()) {268      if (getBool()) {269        sls_mu.Lock();270        continue;271      }272    }273    sls_mu.Lock();274  }275  sls_mu.Unlock();276}277 278void sls_fun_good_8() {279  sls_mw.MyLock();280  sls_mw.mu.Unlock();281}282 283void sls_fun_bad_1() {284  sls_mu.Unlock(); // \285    // expected-warning{{releasing mutex 'sls_mu' that was not held}}286}287 288void sls_fun_bad_2() {289  sls_mu.Lock(); // expected-note{{mutex acquired here}}290  sls_mu.Lock(); // \291    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}292  sls_mu.Unlock();293}294 295void sls_fun_bad_3() {296  sls_mu.Lock(); // expected-note {{mutex acquired here}}297} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}298 299void sls_fun_bad_4() {300  if (getBool())301    sls_mu.Lock();  // expected-note{{mutex acquired here}}302  else303    sls_mu2.Lock(); // expected-note{{mutex acquired here}}304} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \305  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}306 307void sls_fun_bad_5() {308  sls_mu.Lock(); // expected-note {{mutex acquired here}}309  if (getBool())310    sls_mu.Unlock();311} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}312 313void sls_fun_bad_6() {314  if (getBool()) {315    sls_mu.Lock(); // expected-note {{mutex acquired here}}316  } else {317    if (getBool()) {318      getBool(); // EMPTY319    } else {320      getBool(); // EMPTY321    }322  }323  sls_mu.Unlock(); // \324    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\325    expected-warning{{releasing mutex 'sls_mu' that was not held}}326}327 328void sls_fun_bad_7() {329  sls_mu.Lock();330  while (getBool()) { // \331        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}332    sls_mu.Unlock();333    if (getBool()) {334      if (getBool()) {335        continue;336      }337    }338    sls_mu.Lock(); // expected-note {{mutex acquired here}}339  }340  sls_mu.Unlock();341}342 343void sls_fun_bad_8() {344  sls_mu.Lock(); // expected-note{{mutex acquired here}}345 346  do {347    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}348  } while (getBool());349}350 351void sls_fun_bad_9() {352  do {353    sls_mu.Lock();  // \354      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \355      // expected-note{{mutex acquired here}}356  } while (getBool());357  sls_mu.Unlock();358}359 360void sls_fun_bad_10() {361  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}362  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}363    sls_mu.Unlock();364  }365} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}366 367void sls_fun_bad_11() {368  while (getBool()) { // \369      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}370    sls_mu.Lock(); // expected-note {{mutex acquired here}}371  }372  sls_mu.Unlock(); // \373    // expected-warning{{releasing mutex 'sls_mu' that was not held}}374}375 376void sls_fun_bad_12() {377  sls_mu.Lock(); // expected-note {{mutex acquired here}}378  while (getBool()) {379    sls_mu.Unlock();380    if (getBool()) {381      if (getBool()) {382        break;383      }384    }385    sls_mu.Lock();386  }387  sls_mu.Unlock(); // \388    expected-warning{{mutex 'sls_mu' is not held on every path through here}} \389    expected-warning{{releasing mutex 'sls_mu' that was not held}}390}391 392//-----------------------------------------//393// Handling lock expressions in attribute args394// -------------------------------------------//395 396Mutex aa_mu;397 398class GlobalLocker {399public:400  void globalLock() EXCLUSIVE_LOCK_FUNCTION(aa_mu);401  void globalUnlock() UNLOCK_FUNCTION(aa_mu);402};403 404GlobalLocker glock;405 406void aa_fun_1() {407  glock.globalLock();408  glock.globalUnlock();409}410 411void aa_fun_bad_1() {412  glock.globalUnlock(); // \413    // expected-warning{{releasing mutex 'aa_mu' that was not held}}414}415 416void aa_fun_bad_2() {417  glock.globalLock(); // expected-note{{mutex acquired here}}418  glock.globalLock(); // \419    // expected-warning{{acquiring mutex 'aa_mu' that is already held}}420  glock.globalUnlock();421}422 423void aa_fun_bad_3() {424  glock.globalLock(); // expected-note{{mutex acquired here}}425} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}426 427//--------------------------------------------------//428// Regression tests for unusual method names429//--------------------------------------------------//430 431Mutex wmu;432 433// Test diagnostics for other method names.434class WeirdMethods {435  // FIXME: can't currently check inside constructors and destructors.436  WeirdMethods() {437    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}438  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}439  ~WeirdMethods() {440    wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}441  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}442  void operator++() {443    wmu.Lock(); // expected-note {{mutex acquired here}}444  } // expected-warning {{mutex 'wmu' is still held at the end of function}}445  operator int*() {446    wmu.Lock(); // expected-note {{mutex acquired here}}447    return 0;448  } // expected-warning {{mutex 'wmu' is still held at the end of function}}449};450 451//-----------------------------------------------//452// Errors for guarded by or guarded var variables453// ----------------------------------------------//454 455int *pgb_gvar __attribute__((pt_guarded_var));456int *pgb_var __attribute__((pt_guarded_by(sls_mu)));457 458class PGBFoo {459 public:460  int x;461  int *pgb_field __attribute__((guarded_by(sls_mu2)))462                 __attribute__((pt_guarded_by(sls_mu)));463  void testFoo() {464    pgb_field = &x; // \465      // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}466    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \467      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}468    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \469      // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}470    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \471      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}472  }473};474 475class GBFoo {476 public:477  int gb_field __attribute__((guarded_by(sls_mu)));478 479  void testFoo() {480    gb_field = 0; // \481      // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}482  }483 484  void testNoAnal() NO_THREAD_SAFETY_ANALYSIS {485    gb_field = 0;486  }487};488 489GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));490 491void gb_fun_0() {492  sls_mu.Lock();493  int x = *pgb_var;494  sls_mu.Unlock();495}496 497void gb_fun_1() {498  sls_mu.Lock();499  *pgb_var = 2;500  sls_mu.Unlock();501}502 503void gb_fun_2() {504  int x;505  pgb_var = &x;506}507 508void gb_fun_3() {509  int *x = pgb_var;510}511 512void gb_bad_0() {513  sls_guard_var = 1; // \514    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}515}516 517void gb_bad_1() {518  int x = sls_guard_var; // \519    // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}520}521 522void gb_bad_2() {523  sls_guardby_var = 1; // \524    // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}525}526 527void gb_bad_3() {528  int x = sls_guardby_var; // \529    // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}530}531 532void gb_bad_4() {533  *pgb_gvar = 1; // \534    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}535}536 537void gb_bad_5() {538  int x = *pgb_gvar; // \539    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}540}541 542void gb_bad_6() {543  *pgb_var = 1; // \544    // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}545}546 547void gb_bad_7() {548  int x = *pgb_var; // \549    // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}550}551 552void gb_bad_8() {553  GBFoo G;554  G.gb_field = 0; // \555    // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}556}557 558void gb_bad_9() {559  sls_guard_var++; // \560    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}561  sls_guard_var--; // \562    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}563  ++sls_guard_var; // \564    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}565  --sls_guard_var;// \566    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}567}568 569//-----------------------------------------------//570// Warnings on variables with late parsed attributes571// ----------------------------------------------//572 573class LateFoo {574public:575  int a __attribute__((guarded_by(mu)));576  int b;577 578  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu) { }579 580  void test() {581    a = 0; // \582      // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}583    b = a; // \584      // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}585    c = 0; // \586      // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}587  }588 589  int c __attribute__((guarded_by(mu)));590 591  Mutex mu;592};593 594class LateBar {595 public:596  int a_ __attribute__((guarded_by(mu1_)));597  int b_;598  int *q __attribute__((pt_guarded_by(mu)));599  Mutex mu1_;600  Mutex mu;601  LateFoo Foo;602  LateFoo Foo2;603  LateFoo *FooPointer;604};605 606LateBar b1, *b3;607 608void late_0() {609  LateFoo FooA;610  LateFoo FooB;611  FooA.mu.Lock();612  FooA.a = 5;613  FooA.mu.Unlock();614}615 616void late_1() {617  LateBar BarA;618  BarA.FooPointer->mu.Lock();619  BarA.FooPointer->a = 2;620  BarA.FooPointer->mu.Unlock();621}622 623void late_bad_0() {624  LateFoo fooA;625  LateFoo fooB;626  fooA.mu.Lock();627  fooB.a = 5; // \628    // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \629    // expected-note{{found near match 'fooA.mu'}}630  fooA.mu.Unlock();631}632 633void late_bad_1() {634  Mutex mu;635  mu.Lock();636  b1.mu1_.Lock();637  int res = b1.a_ + b3->b_;638  b3->b_ = *b1.q; // \639    // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}640  b1.mu1_.Unlock();641  b1.b_ = res;642  mu.Unlock();643}644 645void late_bad_2() {646  LateBar BarA;647  BarA.FooPointer->mu.Lock();648  BarA.Foo.a = 2; // \649    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \650    // expected-note{{found near match 'BarA.FooPointer->mu'}}651  BarA.FooPointer->mu.Unlock();652}653 654void late_bad_3() {655  LateBar BarA;656  BarA.Foo.mu.Lock();657  BarA.FooPointer->a = 2; // \658    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \659    // expected-note{{found near match 'BarA.Foo.mu'}}660  BarA.Foo.mu.Unlock();661}662 663void late_bad_4() {664  LateBar BarA;665  BarA.Foo.mu.Lock();666  BarA.Foo2.a = 2; // \667    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \668    // expected-note{{found near match 'BarA.Foo.mu'}}669  BarA.Foo.mu.Unlock();670}671 672//-----------------------------------------------//673// Extra warnings for shared vs. exclusive locks674// ----------------------------------------------//675 676void shared_fun_0() {677  sls_mu.Lock();678  do {679    sls_mu.Unlock();680    sls_mu.Lock();681  } while (getBool());682  sls_mu.Unlock();683}684 685void shared_fun_1() {686  sls_mu.ReaderLock(); // \687    // expected-note {{the other acquisition of mutex 'sls_mu' is here}}688  do {689    sls_mu.Unlock();690    sls_mu.Lock();  // \691      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}692  } while (getBool());693  sls_mu.Unlock();694}695 696void shared_fun_3() {697  if (getBool())698    sls_mu.Lock();699  else700    sls_mu.Lock();701  *pgb_var = 1;702  sls_mu.Unlock();703}704 705void shared_fun_4() {706  if (getBool())707    sls_mu.ReaderLock();708  else709    sls_mu.ReaderLock();710  int x = sls_guardby_var;711  sls_mu.Unlock();712}713 714void shared_fun_8() {715  if (getBool())716    sls_mu.Lock(); // \717      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}718  else719    sls_mu.ReaderLock(); // \720      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}721  sls_mu.Unlock();722}723 724void shared_fun_9() {725  sls_mu.Lock();726  sls_mu.ExclusiveUnlock();727 728  sls_mu.ReaderLock();729  sls_mu.ReaderUnlock();730}731 732void shared_fun_10() {733  sls_mu.Lock();734  sls_mu.DemoteExclusive();735  sls_mu.ReaderUnlock();736}737 738void shared_fun_11() {739  sls_mu.ReaderLock();740  sls_mu.PromoteShared();741  sls_mu.Unlock();742}743 744void shared_bad_0() {745  sls_mu.Lock();  // \746    // expected-note {{the other acquisition of mutex 'sls_mu' is here}}747  do {748    sls_mu.Unlock();749    sls_mu.ReaderLock();  // \750      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}751  } while (getBool());752  sls_mu.Unlock();753}754 755void shared_bad_1() {756  if (getBool())757    sls_mu.Lock(); // \758      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}759  else760    sls_mu.ReaderLock(); // \761      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}762  *pgb_var = 1;763  sls_mu.Unlock();764}765 766void shared_bad_2() {767  if (getBool())768    sls_mu.ReaderLock(); // \769      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}770  else771    sls_mu.Lock(); // \772      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}773  *pgb_var = 1;774  sls_mu.Unlock();775}776 777void shared_bad_3() {778  sls_mu.Lock();         // expected-note {{mutex acquired here}}779  sls_mu.ReaderUnlock(); // \780    // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}781}782 783void shared_bad_4() {784  sls_mu.ReaderLock();      // expected-note {{mutex acquired here}}785  sls_mu.ExclusiveUnlock(); // \786    // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}787}788 789void shared_bad_5() {790  sls_mu.Lock();          // expected-note {{mutex acquired here}}791  sls_mu.PromoteShared(); // \792    // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}793  sls_mu.ExclusiveUnlock();794}795 796void shared_bad_6() {797  sls_mu.ReaderLock();      // expected-note {{mutex acquired here}}798  sls_mu.DemoteExclusive(); // \799    // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}800  sls_mu.ReaderUnlock();801}802 803// FIXME: Add support for functions (not only methods)804class LRBar {805 public:806  void aa_elr_fun() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);807  void aa_elr_fun_s() SHARED_LOCKS_REQUIRED(aa_mu);808  void le_fun() __attribute__((locks_excluded(sls_mu)));809};810 811class LRFoo {812 public:813  void test() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);814  void testShared() SHARED_LOCKS_REQUIRED(sls_mu2);815};816 817void elr_fun() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);818void elr_fun() {}819 820LRFoo MyLRFoo;821LRBar Bar;822 823void es_fun_0() {824  aa_mu.Lock();825  Bar.aa_elr_fun();826  aa_mu.Unlock();827}828 829void es_fun_1() {830  aa_mu.Lock();831  Bar.aa_elr_fun_s();832  aa_mu.Unlock();833}834 835void es_fun_2() {836  aa_mu.ReaderLock();837  Bar.aa_elr_fun_s();838  aa_mu.Unlock();839}840 841void es_fun_3() {842  sls_mu.Lock();843  MyLRFoo.test();844  sls_mu.Unlock();845}846 847void es_fun_4() {848  sls_mu2.Lock();849  MyLRFoo.testShared();850  sls_mu2.Unlock();851}852 853void es_fun_5() {854  sls_mu2.ReaderLock();855  MyLRFoo.testShared();856  sls_mu2.Unlock();857}858 859void es_fun_6() {860  Bar.le_fun();861}862 863void es_fun_7() {864  sls_mu.Lock();865  elr_fun();866  sls_mu.Unlock();867}868 869void es_fun_8() NO_THREAD_SAFETY_ANALYSIS;870 871void es_fun_8() {872  Bar.aa_elr_fun_s();873}874 875void es_fun_9() SHARED_LOCKS_REQUIRED(aa_mu);876void es_fun_9() {877  Bar.aa_elr_fun_s();878}879 880void es_fun_10() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);881void es_fun_10() {882  Bar.aa_elr_fun_s();883}884 885void es_bad_0() {886  Bar.aa_elr_fun(); // \887    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}888}889 890void es_bad_1() {891  aa_mu.ReaderLock();892  Bar.aa_elr_fun(); // \893    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}894  aa_mu.Unlock();895}896 897void es_bad_2() {898  Bar.aa_elr_fun_s(); // \899    // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}900}901 902void es_bad_3() {903  MyLRFoo.test(); // \904    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}905}906 907void es_bad_4() {908  MyLRFoo.testShared(); // \909    // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}910}911 912void es_bad_5() {913  sls_mu.ReaderLock();914  MyLRFoo.test(); // \915    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}916  sls_mu.Unlock();917}918 919void es_bad_6() {920  sls_mu.Lock();921  Bar.le_fun(); // \922    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}923  sls_mu.Unlock();924}925 926void es_bad_7() {927  sls_mu.ReaderLock();928  Bar.le_fun(); // \929    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}930  sls_mu.Unlock();931}932 933 934//-----------------------------------------------//935// Unparseable lock expressions936// ----------------------------------------------//937 938// FIXME -- derive new tests for unhandled expressions939 940 941//----------------------------------------------------------------------------//942// The following test cases are ported from the gcc thread safety implementation943// They are each wrapped inside a namespace with the test number of the gcc test944//945// FIXME: add all the gcc tests, once this analysis passes them.946//----------------------------------------------------------------------------//947 948//-----------------------------------------//949// Good testcases (no errors)950//-----------------------------------------//951 952namespace thread_annot_lock_20 {953class Bar {954 public:955  static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);956  static int b_ GUARDED_BY(mu1_);957  static Mutex mu1_;958  static int a_ GUARDED_BY(mu1_);959};960 961Bar b1;962 963int Bar::func1()964{965  int res = 5;966 967  if (a_ == 4)968    res = b_;969  return res;970}971} // end namespace thread_annot_lock_20972 973namespace thread_annot_lock_22 {974// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially975// uses in class definitions.976Mutex mu;977 978class Bar {979 public:980  int a_ GUARDED_BY(mu1_);981  int b_;982  int *q PT_GUARDED_BY(mu);983  Mutex mu1_ ACQUIRED_AFTER(mu);984};985 986Bar b1, *b3;987int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);988int res GUARDED_BY(mu) = 5;989 990int func(int i)991{992  int x;993  mu.Lock();994  b1.mu1_.Lock();995  res = b1.a_ + b3->b_;996  *p = i;997  b1.a_ = res + b3->b_;998  b3->b_ = *b1.q;999  b1.mu1_.Unlock();1000  b1.b_ = res;1001  x = res;1002  mu.Unlock();1003  return x;1004}1005} // end namespace thread_annot_lock_221006 1007namespace thread_annot_lock_27_modified {1008// test lock annotations applied to function definitions1009// Modified: applied annotations only to function declarations1010Mutex mu1;1011Mutex mu2 ACQUIRED_AFTER(mu1);1012 1013class Foo {1014 public:1015  int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);1016};1017 1018int Foo::method1(int i) {1019  return i;1020}1021 1022 1023int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);1024int foo(int i) {1025  return i;1026}1027 1028static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);1029static int bar(int i) {1030  return i;1031}1032 1033void main() {1034  Foo a;1035 1036  mu1.Lock();1037  mu2.Lock();1038  a.method1(1);1039  foo(2);1040  mu2.Unlock();1041  bar(3);1042  mu1.Unlock();1043}1044} // end namespace thread_annot_lock_27_modified1045 1046 1047namespace thread_annot_lock_38 {1048// Test the case where a template member function is annotated with lock1049// attributes in a non-template class.1050class Foo {1051 public:1052  void func1(int y) LOCKS_EXCLUDED(mu_);1053  template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);1054 private:1055  Mutex mu_;1056};1057 1058Foo *foo;1059 1060void main()1061{1062  foo->func1(5);1063  foo->func2(5);1064}1065} // end namespace thread_annot_lock_381066 1067namespace thread_annot_lock_43 {1068// Tests lock canonicalization1069class Foo {1070 public:1071  Mutex *mu_;1072};1073 1074class FooBar {1075 public:1076  Foo *foo_;1077  int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }1078  int a_ GUARDED_BY(foo_->mu_);1079};1080 1081FooBar *fb;1082 1083void main()1084{1085  int x;1086  fb->foo_->mu_->Lock();1087  x = fb->GetA();1088  fb->foo_->mu_->Unlock();1089}1090} // end namespace thread_annot_lock_431091 1092namespace thread_annot_lock_49 {1093// Test the support for use of lock expression in the annotations1094class Foo {1095 public:1096  Mutex foo_mu_;1097};1098 1099class Bar {1100 private:1101  Foo *foo;1102  Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);1103 1104 public:1105  void Test1() {1106    foo->foo_mu_.Lock();1107    bar_mu_.Lock();1108    bar_mu_.Unlock();1109    foo->foo_mu_.Unlock();1110  }1111};1112 1113void main() {1114  Bar bar;1115  bar.Test1();1116}1117} // end namespace thread_annot_lock_491118 1119namespace thread_annot_lock_61_modified {1120  // Modified to fix the compiler errors1121  // Test the fix for a bug introduced by the support of pass-by-reference1122  // parameters.1123  struct Foo { Foo &operator<< (bool) {return *this;} };1124  Foo &getFoo();1125  struct Bar { Foo &func () {return getFoo();} };1126  struct Bas { void operator& (Foo &) {} };1127  void mumble()1128  {1129    Bas() & Bar().func() << "" << "";1130    Bas() & Bar().func() << "";1131  }1132} // end namespace thread_annot_lock_61_modified1133 1134 1135namespace thread_annot_lock_65 {1136// Test the fix for a bug in the support of allowing reader locks for1137// non-const, non-modifying overload functions. (We didn't handle the builtin1138// properly.)1139enum MyFlags {1140  Zero,1141  One,1142  Two,1143  Three,1144  Four,1145  Five,1146  Six,1147  Seven,1148  Eight,1149  Nine1150};1151 1152inline MyFlags1153operator|(MyFlags a, MyFlags b)1154{1155  return MyFlags(static_cast<int>(a) | static_cast<int>(b));1156}1157 1158inline MyFlags&1159operator|=(MyFlags& a, MyFlags b)1160{1161    return a = a | b;1162}1163} // end namespace thread_annot_lock_651164 1165namespace thread_annot_lock_66_modified {1166// Modified: Moved annotation to function defn1167// Test annotations on out-of-line definitions of member functions where the1168// annotations refer to locks that are also data members in the class.1169Mutex mu;1170 1171class Foo {1172 public:1173  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);1174  int data GUARDED_BY(mu1);1175  Mutex *mu1;1176  Mutex *mu2;1177};1178 1179int Foo::method1(int i)1180{1181  return data + i;1182}1183 1184void main()1185{1186  Foo a;1187 1188  a.mu2->Lock();1189  a.mu1->Lock();1190  mu.Lock();1191  a.method1(1);1192  mu.Unlock();1193  a.mu1->Unlock();1194  a.mu2->Unlock();1195}1196} // end namespace thread_annot_lock_66_modified1197 1198namespace thread_annot_lock_68_modified {1199// Test a fix to a bug in the delayed name binding with nested template1200// instantiation. We use a stack to make sure a name is not resolved to an1201// inner context.1202template <typename T>1203class Bar {1204  Mutex mu_;1205};1206 1207template <typename T>1208class Foo {1209 public:1210  void func(T x) {1211    mu_.Lock();1212    count_ = x;1213    mu_.Unlock();1214  }1215 1216 private:1217  T count_ GUARDED_BY(mu_);1218  Bar<T> bar_;1219  Mutex mu_;1220};1221 1222void main()1223{1224  Foo<int> *foo;1225  foo->func(5);1226}1227} // end namespace thread_annot_lock_68_modified1228 1229namespace thread_annot_lock_30_modified {1230// Test delay parsing of lock attribute arguments with nested classes.1231// Modified: trylocks replaced with exclusive_lock_fun1232int a = 0;1233 1234class Bar {1235  struct Foo;1236 1237 public:1238  void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);1239 1240  int func() {1241    MyLock();1242//    if (foo == 0) {1243//      return 0;1244//    }1245    a = 5;1246    mu.Unlock();1247    return 1;1248  }1249 1250  class FooBar {1251    int x;1252    int y;1253  };1254 1255 private:1256  Mutex mu;1257};1258 1259Bar *bar;1260 1261void main()1262{1263  bar->func();1264}1265} // end namespace thread_annot_lock_30_modified1266 1267namespace thread_annot_lock_47 {1268// Test the support for annotations on virtual functions.1269// This is a good test case. (i.e. There should be no warning emitted by the1270// compiler.)1271class Base {1272 public:1273  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);1274  virtual void func2() LOCKS_EXCLUDED(mu_);1275  Mutex mu_;1276};1277 1278class Child : public Base {1279 public:1280  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);1281  virtual void func2() LOCKS_EXCLUDED(mu_);1282};1283 1284void main() {1285  Child *c;1286  Base *b = c;1287 1288  b->mu_.Lock();1289  b->func1();1290  b->mu_.Unlock();1291  b->func2();1292 1293  c->mu_.Lock();1294  c->func1();1295  c->mu_.Unlock();1296  c->func2();1297}1298} // end namespace thread_annot_lock_471299 1300//-----------------------------------------//1301// Tests which produce errors1302//-----------------------------------------//1303 1304namespace thread_annot_lock_13 {1305Mutex mu1;1306Mutex mu2;1307 1308int g GUARDED_BY(mu1);1309int w GUARDED_BY(mu2);1310 1311class Foo {1312 public:1313  void bar() LOCKS_EXCLUDED(mu_, mu1);1314  int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);1315 1316 private:1317  int a_ GUARDED_BY(mu_);1318 public:1319  Mutex mu_ ACQUIRED_AFTER(mu1);1320};1321 1322int Foo::foo()1323{1324  int res;1325  w = 5;1326  res = a_ + 5;1327  return res;1328}1329 1330void Foo::bar()1331{1332  int x;1333  mu_.Lock();1334  x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}1335  a_ = x + 1;1336  mu_.Unlock();1337  if (x > 5) {1338    mu1.Lock();1339    g = 2;1340    mu1.Unlock();1341  }1342}1343 1344void main()1345{1346  Foo f1, *f2;1347  f1.mu_.Lock();1348  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}1349  mu2.Lock();1350  f1.foo();1351  mu2.Unlock();1352  f1.mu_.Unlock();1353  f2->mu_.Lock();1354  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}1355  f2->mu_.Unlock();1356  mu2.Lock();1357  w = 2;1358  mu2.Unlock();1359}1360} // end namespace thread_annot_lock_131361 1362namespace thread_annot_lock_18_modified {1363// Modified: Trylocks removed1364// Test the ability to distnguish between the same lock field of1365// different objects of a class.1366  class Bar {1367 public:1368  bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);1369  void MyUnlock() UNLOCK_FUNCTION(mu1_);1370  int a_ GUARDED_BY(mu1_);1371 1372 private:1373  Mutex mu1_;1374};1375 1376Bar *b1, *b2;1377 1378void func()1379{1380  b1->MyLock();1381  b1->a_ = 5;1382  b2->a_ = 3; // \1383    // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \1384    // expected-note {{found near match 'b1->mu1_'}}1385  b2->MyLock();1386  b2->MyUnlock();1387  b1->MyUnlock();1388}1389} // end namespace thread_annot_lock_18_modified1390 1391namespace thread_annot_lock_21 {1392// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially1393// uses in class definitions.1394Mutex mu;1395 1396class Bar {1397 public:1398  int a_ GUARDED_BY(mu1_);1399  int b_;1400  int *q PT_GUARDED_BY(mu);1401  Mutex mu1_ ACQUIRED_AFTER(mu);1402};1403 1404Bar b1, *b3;1405int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);1406 1407int res GUARDED_BY(mu) = 5;1408 1409int func(int i)1410{1411  int x;1412  b3->mu1_.Lock();1413  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \1414    // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \1415    // expected-note {{found near match 'b3->mu1_'}}1416  *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \1417    // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}1418  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \1419    // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \1420    // expected-note {{found near match 'b3->mu1_'}}1421  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}1422  b3->mu1_.Unlock();1423  b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}1424  x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}1425  return x;1426}1427} // end namespace thread_annot_lock_211428 1429namespace thread_annot_lock_35_modified {1430// Test the analyzer's ability to distinguish the lock field of different1431// objects.1432class Foo {1433 private:1434  Mutex lock_;1435  int a_ GUARDED_BY(lock_);1436 1437 public:1438  void Func(Foo* child) LOCKS_EXCLUDED(lock_) {1439     Foo *new_foo = new Foo;1440 1441     lock_.Lock();1442 1443     child->Func(new_foo); // There shouldn't be any warning here as the1444                           // acquired lock is not in child.1445     child->bar(7); // \1446       // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \1447       // expected-note {{found near match 'lock_'}}1448     child->a_ = 5; // \1449       // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \1450       // expected-note {{found near match 'lock_'}}1451     lock_.Unlock();1452  }1453 1454  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {1455    a_ = y;1456  }1457};1458 1459Foo *x;1460 1461void main() {1462  Foo *child = new Foo;1463  x->Func(child);1464}1465} // end namespace thread_annot_lock_35_modified1466 1467namespace thread_annot_lock_36_modified {1468// Modified to move the annotations to function defns.1469// Test the analyzer's ability to distinguish the lock field of different1470// objects1471class Foo {1472 private:1473  Mutex lock_;1474  int a_ GUARDED_BY(lock_);1475 1476 public:1477  void Func(Foo* child) LOCKS_EXCLUDED(lock_);1478  void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);1479};1480 1481void Foo::Func(Foo* child) {1482  Foo *new_foo = new Foo;1483 1484  lock_.Lock();1485 1486  child->lock_.Lock();1487  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}1488  child->bar(7);1489  child->a_ = 5;1490  child->lock_.Unlock();1491 1492  lock_.Unlock();1493}1494 1495void Foo::bar(int y) {1496  a_ = y;1497}1498 1499 1500Foo *x;1501 1502void main() {1503  Foo *child = new Foo;1504  x->Func(child);1505}1506} // end namespace thread_annot_lock_36_modified1507 1508 1509namespace thread_annot_lock_42 {1510// Test support of multiple lock attributes of the same kind on a decl.1511class Foo {1512 private:1513  Mutex mu1, mu2, mu3;1514  int x GUARDED_BY(mu1) GUARDED_BY(mu2);1515  int y GUARDED_BY(mu2);1516 1517  void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {1518    mu2.Lock();1519    y = 2;1520    mu2.Unlock();1521  }1522 1523 public:1524  void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {1525    x = 5;1526    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \1527      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}1528  }1529};1530 1531Foo *foo;1532 1533void func()1534{1535  foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \1536             // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}1537}1538} // end namespace thread_annot_lock_421539 1540namespace thread_annot_lock_46 {1541// Test the support for annotations on virtual functions.1542class Base {1543 public:1544  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);1545  virtual void func2() LOCKS_EXCLUDED(mu_);1546  Mutex mu_;1547};1548 1549class Child : public Base {1550 public:1551  virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);1552  virtual void func2() LOCKS_EXCLUDED(mu_);1553};1554 1555void main() {1556  Child *c;1557  Base *b = c;1558 1559  b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}1560  b->mu_.Lock();1561  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}1562  b->mu_.Unlock();1563 1564  c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}1565  c->mu_.Lock();1566  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}1567  c->mu_.Unlock();1568}1569} // end namespace thread_annot_lock_461570 1571namespace thread_annot_lock_67_modified {1572// Modified: attributes on definitions moved to declarations1573// Test annotations on out-of-line definitions of member functions where the1574// annotations refer to locks that are also data members in the class.1575Mutex mu;1576Mutex mu3;1577 1578class Foo {1579 public:1580  int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);1581  int data GUARDED_BY(mu1);1582  Mutex *mu1;1583  Mutex *mu2;1584};1585 1586int Foo::method1(int i) {1587  return data + i;1588}1589 1590void main()1591{1592  Foo a;1593  a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \1594    // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \1595    // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \1596    // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}1597}1598} // end namespace thread_annot_lock_67_modified1599 1600 1601namespace substitution_test {1602  class MyData  {1603  public:1604    Mutex mu;1605 1606    void lockData()    EXCLUSIVE_LOCK_FUNCTION(mu);1607    void unlockData()  UNLOCK_FUNCTION(mu);1608 1609    void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu)  { }1610    void operator()()  EXCLUSIVE_LOCKS_REQUIRED(mu)  { }1611 1612    MyData operator+(const MyData& other) const SHARED_LOCKS_REQUIRED(mu, other.mu);1613  };1614 1615  MyData operator-(const MyData& a, const MyData& b) SHARED_LOCKS_REQUIRED(a.mu, b.mu);1616 1617  class DataLocker {1618  public:1619    void lockData  (MyData *d) EXCLUSIVE_LOCK_FUNCTION(d->mu);1620    void unlockData(MyData *d) UNLOCK_FUNCTION(d->mu);1621  };1622 1623 1624  class Foo {1625  public:1626    void foo(MyData* d) EXCLUSIVE_LOCKS_REQUIRED(d->mu) { }1627 1628    void subst(MyData& d) {1629      d.doSomething(); // expected-warning {{calling function 'doSomething' requires holding mutex 'd.mu' exclusively}}1630      d();             // expected-warning {{calling function 'operator()' requires holding mutex 'd.mu' exclusively}}1631      d.operator()();  // expected-warning {{calling function 'operator()' requires holding mutex 'd.mu' exclusively}}1632 1633      d.lockData();1634      d.doSomething();1635      d();1636      d.operator()();1637      d.unlockData();1638    }1639 1640    void binop(MyData& a, MyData& b) EXCLUSIVE_LOCKS_REQUIRED(a.mu) {1641      a + b; // expected-warning {{calling function 'operator+' requires holding mutex 'b.mu'}}1642             // expected-note@-1 {{found near match 'a.mu'}}1643      b + a; // expected-warning {{calling function 'operator+' requires holding mutex 'b.mu'}}1644             // expected-note@-1 {{found near match 'a.mu'}}1645      a - b; // expected-warning {{calling function 'operator-' requires holding mutex 'b.mu'}}1646             // expected-note@-1 {{found near match 'a.mu'}}1647    }1648 1649    void bar1(MyData* d) {1650      d->lockData();1651      foo(d);1652      d->unlockData();1653    }1654 1655    void bar2(MyData* d) {1656      DataLocker dlr;1657      dlr.lockData(d);1658      foo(d);1659      dlr.unlockData(d);1660    }1661 1662    void bar3(MyData* d1, MyData* d2) {1663      DataLocker dlr;1664      dlr.lockData(d1);   // expected-note {{mutex acquired here}}1665      dlr.unlockData(d2); // \1666        // expected-warning {{releasing mutex 'd2->mu' that was not held}}1667    } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}1668 1669    void bar4(MyData* d1, MyData* d2) {1670      DataLocker dlr;1671      dlr.lockData(d1);1672      foo(d2); // \1673        // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \1674        // expected-note {{found near match 'd1->mu'}}1675      dlr.unlockData(d1);1676    }1677  };1678 1679  // Automatic object destructor calls don't appear as expressions in the CFG,1680  // so we have to handle them separately whenever substitutions are required.1681  struct DestructorRequires {1682    Mutex mu;1683    ~DestructorRequires() EXCLUSIVE_LOCKS_REQUIRED(mu);1684  };1685 1686  void destructorRequires() {1687    DestructorRequires rd;1688    rd.mu.AssertHeld();1689  }1690 1691  struct DestructorExcludes {1692    Mutex mu;1693    ~DestructorExcludes() LOCKS_EXCLUDED(mu);1694  };1695 1696  void destructorExcludes() {1697    DestructorExcludes ed;1698    ed.mu.Lock(); // expected-note {{mutex acquired here}}1699  } // expected-warning {{cannot call function '~DestructorExcludes' while mutex 'ed.mu' is held}}1700    // expected-warning@-1 {{mutex 'ed.mu' is still held at the end of function}}1701 1702} // end namespace substituation_test1703 1704 1705 1706namespace constructor_destructor_tests {1707  Mutex fooMu;1708  int myVar GUARDED_BY(fooMu);1709 1710  class Foo {1711  public:1712    Foo()  EXCLUSIVE_LOCK_FUNCTION(fooMu) { }1713    ~Foo() UNLOCK_FUNCTION(fooMu) { }1714  };1715 1716  void fooTest() {1717    Foo foo;1718    myVar = 0;1719  }1720}1721 1722 1723namespace template_member_test {1724 1725  struct S { int n; };1726  struct T {1727    Mutex m;1728    S *s GUARDED_BY(this->m);1729  };1730  Mutex m;1731  struct U {1732    union {1733      int n;1734    };1735  } *u GUARDED_BY(m);1736 1737  template<typename U>1738  struct IndirectLock {1739    int DoNaughtyThings(T *t) {1740      u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}1741      return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}1742    }1743  };1744 1745  template struct IndirectLock<int>; // expected-note {{here}}1746 1747  struct V {1748    void f(int);1749    void f(double);1750 1751    Mutex m;1752    V *p GUARDED_BY(this->m);1753  };1754  template<typename U> struct W {1755    V v;1756    void f(U u) {1757      v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}1758    }1759  };1760  template struct W<int>; // expected-note {{here}}1761 1762}1763 1764namespace test_scoped_lockable {1765 1766struct TestScopedLockable {1767  Mutex mu1;1768  Mutex mu2;1769  int a __attribute__((guarded_by(mu1)));1770  int b __attribute__((guarded_by(mu2)));1771 1772  bool getBool();1773 1774  bool lock2Bool(MutexLock);1775 1776  void foo1() {1777    MutexLock mulock(&mu1);1778    a = 5;1779  }1780 1781#ifdef __cpp_guaranteed_copy_elision1782  void const_lock() {1783    const MutexLock mulock = MutexLock(&mu1);1784    a = 5;1785  }1786#endif1787 1788  void temporary() {1789    MutexLock{&mu1}, a = 5;1790  }1791 1792  void temporary_cfg(int x) {1793    // test the case where a pair of temporary Ctor and Dtor is in different CFG blocks1794    lock2Bool(MutexLock{&mu1}) || x;1795    MutexLock{&mu1};  // no-warn1796  }1797 1798  void lifetime_extension() {1799    const MutexLock &mulock = MutexLock(&mu1);1800    a = 5;1801  }1802 1803  void foo2() {1804    ReaderMutexLock mulock1(&mu1);1805    if (getBool()) {1806      MutexLock mulock2a(&mu2);1807      b = a + 1;1808    }1809    else {1810      MutexLock mulock2b(&mu2);1811      b = a + 2;1812    }1813  }1814 1815  void foo3() {1816    MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}1817    MutexLock mulock_b(&mu1); // \1818      // expected-warning {{acquiring mutex 'mu1' that is already held}}1819  }1820 1821  void temporary_double_lock() {1822    MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}1823    MutexLock{&mu1};          // \1824      // expected-warning {{acquiring mutex 'mu1' that is already held}}1825  }1826 1827  void foo4() {1828    MutexLock mulock1(&mu1), mulock2(&mu2);1829    a = b+1;1830    b = a+1;1831  }1832 1833  void foo5() {1834    DoubleMutexLock mulock(&mu1, &mu2);1835    a = b + 1;1836    b = a + 1;1837  }1838 1839  void foo6() {1840    TemplateMutexLock<Mutex> mulock1(&mu1), mulock2(&mu2);1841    a = b + 1;1842    b = a + 1;1843  }1844 1845  void foo7() {1846    VariadicMutexLock<Mutex, Mutex> mulock(&mu1, &mu2);1847    a = b + 1;1848    b = a + 1;1849  }1850};1851 1852} // end namespace test_scoped_lockable1853 1854 1855namespace FunctionAttrTest {1856 1857class Foo {1858public:1859  Mutex mu_;1860  int a GUARDED_BY(mu_);1861};1862 1863Foo fooObj;1864 1865void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);1866 1867void bar() {1868  foo();  // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}1869  fooObj.mu_.Lock();1870  foo();1871  fooObj.mu_.Unlock();1872}1873 1874};  // end namespace FunctionAttrTest1875 1876 1877namespace TryLockTest {1878 1879struct TestTryLock {1880  Mutex mu;1881  int a GUARDED_BY(mu);1882  bool cond;1883 1884  void foo1() {1885    if (mu.TryLock()) {1886      a = 1;1887      mu.Unlock();1888    }1889  }1890 1891  void foo2() {1892    if (!mu.TryLock()) return;1893    a = 2;1894    mu.Unlock();1895  }1896 1897  void foo2_builtin_expect() {1898    if (__builtin_expect(!mu.TryLock(), false))1899      return;1900    a = 2;1901    mu.Unlock();1902  }1903 1904  void foo3() {1905    bool b = mu.TryLock();1906    if (b) {1907      a = 3;1908      mu.Unlock();1909    }1910  }1911 1912  void foo3_builtin_expect() {1913    bool b = mu.TryLock();1914    if (__builtin_expect(b, true)) {1915      a = 3;1916      mu.Unlock();1917    }1918  }1919 1920  void foo4() {1921    bool b = mu.TryLock();1922    if (!b) return;1923    a = 4;1924    mu.Unlock();1925  }1926 1927  void foo5() {1928    while (mu.TryLock()) {1929      a = a + 1;1930      mu.Unlock();1931    }1932  }1933 1934  void foo6() {1935    bool b = mu.TryLock();1936    b = !b;1937    if (b) return;1938    a = 6;1939    mu.Unlock();1940  }1941 1942  void foo7() {1943    bool b1 = mu.TryLock();1944    bool b2 = !b1;1945    bool b3 = !b2;1946    if (b3) {1947      a = 7;1948      mu.Unlock();1949    }1950  }1951 1952  // Test use-def chains: join points1953  void foo8() {1954    bool b  = mu.TryLock();1955    bool b2 = b;1956    if (cond)1957      b = true;1958    if (b) {    // b should be unknown at this point, because of the join point1959      a = 8;    // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}1960    }1961    if (b2) {   // b2 should be known at this point.1962      a = 8;1963      mu.Unlock();1964    }1965  }1966 1967  // Test use-def-chains: back edges1968  void foo9() {1969    bool b = mu.TryLock();1970 1971    for (int i = 0; i < 10; ++i);1972 1973    if (b) {  // b is still known, because the loop doesn't alter it1974      a = 9;1975      mu.Unlock();1976    }1977  }1978 1979  // Test use-def chains: back edges1980  void foo10() {1981    bool b = mu.TryLock();1982 1983    while (cond) {1984      if (b) {   // b should be unknown at this point b/c of the loop1985        a = 10;  // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}1986      }1987      b = !b;1988    }1989  }1990 1991  // Test merge of exclusive trylock1992  void foo11() {1993   if (cond) {1994     if (!mu.TryLock())1995       return;1996   }1997   else {1998     mu.Lock();1999   }2000   a = 10;2001   mu.Unlock();2002  }2003 2004  // Test merge of shared trylock2005  void foo12() {2006   if (cond) {2007     if (!mu.ReaderTryLock())2008       return;2009   }2010   else {2011     mu.ReaderLock();2012   }2013   int i = a;2014   mu.Unlock();2015  }2016 2017  // Test with conditional operator2018  void foo13() {2019    if (mu.TryLock() ? 1 : 0)2020      mu.Unlock();2021  }2022 2023  void foo14() {2024    if (mu.TryLock() ? 0 : 1)2025      return;2026    mu.Unlock();2027  }2028 2029  void foo15() {2030    if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}}2031      mu.Unlock();            // expected-warning{{releasing mutex 'mu' that was not held}}2032  }                           // expected-warning{{mutex 'mu' is not held on every path through here}}2033};  // end TestTrylock2034 2035} // end namespace TrylockTest2036 2037 2038namespace TestTemplateAttributeInstantiation {2039 2040class Foo1 {2041public:2042  Mutex mu_;2043  int a GUARDED_BY(mu_);2044};2045 2046class Foo2 {2047public:2048  int a GUARDED_BY(mu_);2049  Mutex mu_;2050};2051 2052 2053class Bar {2054public:2055  // Test non-dependent expressions in attributes on template functions2056  template <class T>2057  void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {2058    foo->a = 0;2059  }2060 2061  // Test dependent expressions in attributes on template functions2062  template <class T>2063  void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {2064    fooT->a = 0;2065  }2066};2067 2068 2069template <class T>2070class BarT {2071public:2072  Foo1 fooBase;2073  T    fooBaseT;2074 2075  // Test non-dependent expression in ordinary method on template class2076  void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {2077    fooBase.a = 0;2078  }2079 2080  // Test dependent expressions in ordinary methods on template class2081  void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {2082    fooBaseT.a = 0;2083  }2084 2085  // Test dependent expressions in template method in template class2086  template <class T2>2087  void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {2088    fooBaseT.a = 0;2089    fooT->a = 0;2090  }2091};2092 2093template <class T>2094class Cell {2095public:2096  Mutex mu_;2097  // Test dependent guarded_by2098  T data GUARDED_BY(mu_);2099 2100  void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {2101    data = 0;2102  }2103 2104  void foo() {2105    mu_.Lock();2106    data = 0;2107    mu_.Unlock();2108  }2109};2110 2111void test() {2112  Bar b;2113  BarT<Foo2> bt;2114  Foo1 f1;2115  Foo2 f2;2116 2117  f1.mu_.Lock();2118  f2.mu_.Lock();2119  bt.fooBase.mu_.Lock();2120  bt.fooBaseT.mu_.Lock();2121 2122  b.barND(&f1, &f2);2123  b.barD(&f1, &f2);2124  bt.barND();2125  bt.barD();2126  bt.barTD(&f2);2127 2128  f1.mu_.Unlock();2129  bt.barTD(&f1);  // \2130    // expected-warning {{calling function 'barTD<TestTemplateAttributeInstantiation::Foo1>' requires holding mutex 'f1.mu_' exclusively}} \2131    // expected-note {{found near match 'bt.fooBase.mu_'}}2132 2133  bt.fooBase.mu_.Unlock();2134  bt.fooBaseT.mu_.Unlock();2135  f2.mu_.Unlock();2136 2137  Cell<int> cell;2138  cell.data = 0; // \2139    // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}2140  cell.foo();2141  cell.mu_.Lock();2142  cell.fooEx();2143  cell.mu_.Unlock();2144}2145 2146 2147template <class T>2148class CellDelayed {2149public:2150  // Test dependent guarded_by2151  T data GUARDED_BY(mu_);2152  static T static_data GUARDED_BY(static_mu_);2153 2154  void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {2155    this->data = other->data;2156  }2157 2158  template <class T2>2159  void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {2160    this->data = otherT->data;2161  }2162 2163  void foo() {2164    mu_.Lock();2165    data = 0;2166    mu_.Unlock();2167  }2168 2169  Mutex mu_;2170  static Mutex static_mu_;2171};2172 2173void testDelayed() {2174  CellDelayed<int> celld;2175  CellDelayed<int> celld2;2176  celld.foo();2177  celld.mu_.Lock();2178  celld2.mu_.Lock();2179 2180  celld.fooEx(&celld2);2181  celld.fooExT(&celld2);2182 2183  celld2.mu_.Unlock();2184  celld.mu_.Unlock();2185}2186 2187};  // end namespace TestTemplateAttributeInstantiation2188 2189 2190namespace FunctionDeclDefTest {2191 2192class Foo {2193public:2194  Mutex mu_;2195  int a GUARDED_BY(mu_);2196 2197  virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);2198};2199 2200// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_2201void Foo::foo1(Foo *f_defined) {2202  f_defined->a = 0;2203};2204 2205void test() {2206  Foo myfoo;2207  myfoo.foo1(&myfoo);  // \2208    // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}2209  myfoo.mu_.Lock();2210  myfoo.foo1(&myfoo);2211  myfoo.mu_.Unlock();2212}2213 2214};2215 2216namespace GoingNative {2217 2218  struct LOCKABLE mutex {2219    void lock() EXCLUSIVE_LOCK_FUNCTION();2220    void unlock() UNLOCK_FUNCTION();2221    // ...2222  };2223  bool foo();2224  bool bar();2225  mutex m;2226  void test() {2227    m.lock();2228    while (foo()) { // expected-warning {{expecting mutex 'm' to be held at start of each loop}}2229      m.unlock();2230      // ...2231      if (bar()) {2232        // ...2233        if (foo())2234          continue;2235        //...2236      }2237      // ...2238      m.lock(); // expected-note {{mutex acquired here}}2239    }2240    m.unlock();2241  }2242 2243}2244 2245 2246 2247namespace FunctionDefinitionTest {2248 2249class Foo {2250public:2251  void foo1();2252  void foo2();2253  void foo3(Foo *other);2254 2255  template<class T>2256  void fooT1(const T& dummy1);2257 2258  template<class T>2259  void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);2260 2261  Mutex mu_;2262  int a GUARDED_BY(mu_);2263};2264 2265template<class T>2266class FooT {2267public:2268  void foo();2269 2270  Mutex mu_;2271  T a GUARDED_BY(mu_);2272};2273 2274 2275void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {2276  a = 1;2277}2278 2279void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {2280  a = 2;2281}2282 2283void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {2284  other->a = 3;2285}2286 2287template<class T>2288void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {2289  a = dummy1;2290}2291 2292/* TODO -- uncomment with template instantiation of attributes.2293template<class T>2294void Foo::fooT2(const T& dummy2) {2295  a = dummy2;2296}2297*/2298 2299void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {2300  f->a = 1;2301}2302 2303void fooF2(Foo *f);2304void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {2305  f->a = 2;2306}2307 2308void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);2309void fooF3(Foo *f) {2310  f->a = 3;2311}2312 2313template<class T>2314void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {2315  a = 0;2316}2317 2318void test() {2319  int dummy = 0;2320  Foo myFoo;2321 2322  myFoo.foo2();        // \2323    // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}2324  myFoo.foo3(&myFoo);  // \2325    // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}2326  myFoo.fooT1(dummy);  // \2327    // expected-warning {{calling function 'fooT1<int>' requires holding mutex 'myFoo.mu_' exclusively}}2328 2329  myFoo.fooT2(dummy);  // \2330    // expected-warning {{calling function 'fooT2<int>' requires holding mutex 'myFoo.mu_' exclusively}}2331 2332  fooF1(&myFoo);  // \2333    // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}2334  fooF2(&myFoo);  // \2335    // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}2336  fooF3(&myFoo);  // \2337    // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}2338 2339  myFoo.mu_.Lock();2340  myFoo.foo2();2341  myFoo.foo3(&myFoo);2342  myFoo.fooT1(dummy);2343 2344  myFoo.fooT2(dummy);2345 2346  fooF1(&myFoo);2347  fooF2(&myFoo);2348  fooF3(&myFoo);2349  myFoo.mu_.Unlock();2350 2351  FooT<int> myFooT;2352  myFooT.foo();  // \2353    // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}2354}2355 2356} // end namespace FunctionDefinitionTest2357 2358 2359namespace SelfLockingTest {2360 2361class LOCKABLE MyLock {2362public:2363  int foo GUARDED_BY(this);2364 2365  void lock()   EXCLUSIVE_LOCK_FUNCTION();2366  void unlock() UNLOCK_FUNCTION();2367 2368  void doSomething() {2369    this->lock();  // allow 'this' as a lock expression2370    foo = 0;2371    doSomethingElse();2372    this->unlock();2373  }2374 2375  void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {2376    foo = 1;2377  };2378 2379  void test() {2380    foo = 2;  // \2381      // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}2382  }2383};2384 2385 2386class LOCKABLE MyLock2 {2387public:2388  Mutex mu_;2389  int foo GUARDED_BY(this);2390 2391  // don't check inside lock and unlock functions2392  void lock()   EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock();   }2393  void unlock() UNLOCK_FUNCTION()         { mu_.Unlock(); }2394 2395  // don't check inside constructors and destructors2396  MyLock2()  { foo = 1; }2397  ~MyLock2() { foo = 0; }2398};2399 2400 2401} // end namespace SelfLockingTest2402 2403 2404namespace InvalidNonstatic {2405 2406// Forward decl here causes bogus "invalid use of non-static data member"2407// on reference to mutex_ in guarded_by attribute.2408class Foo;2409 2410class Foo {2411  Mutex* mutex_;2412 2413  int foo __attribute__((guarded_by(mutex_)));2414};2415 2416}  // end namespace InvalidNonStatic2417 2418 2419namespace NoReturnTest {2420 2421bool condition();2422void fatal() __attribute__((noreturn));2423 2424Mutex mu_;2425 2426void test1() {2427  MutexLock lock(&mu_);2428  if (condition()) {2429    fatal();2430    return;2431  }2432}2433 2434} // end namespace NoReturnTest2435 2436 2437namespace TestMultiDecl {2438 2439class Foo {2440public:2441  int GUARDED_BY(mu_) a;2442  int GUARDED_BY(mu_) b, c;2443 2444  void foo() {2445    a = 0; // \2446      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}2447    b = 0; // \2448      // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}2449    c = 0; // \2450      // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}2451  }2452 2453private:2454  Mutex mu_;2455};2456 2457} // end namespace TestMultiDecl2458 2459 2460namespace WarnNoDecl {2461 2462class Foo {2463  void foo(int a);  __attribute__(( // \2464    // expected-warning {{declaration does not declare anything}}2465    exclusive_locks_required(a))); // \2466    // expected-warning {{attribute exclusive_locks_required ignored}}2467 2468};2469 2470} // end namespace WarnNoDecl2471 2472 2473 2474namespace MoreLockExpressions {2475 2476class Foo {2477public:2478  Mutex mu_;2479  int a GUARDED_BY(mu_);2480};2481 2482class Bar {2483public:2484  int b;2485  Foo* f;2486 2487  Foo& getFoo()              { return *f; }2488  Foo& getFoo2(int c)        { return *f; }2489  Foo& getFoo3(int c, int d) { return *f; }2490 2491  Foo& getFooey() { return *f; }2492};2493 2494Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }2495 2496void test() {2497  Foo foo;2498  Foo *fooArray;2499  Foo &(*fooFuncPtr)();2500  Bar bar;2501  int a;2502  int b;2503  int c;2504 2505  bar.getFoo().mu_.Lock();2506  bar.getFoo().a = 0;2507  bar.getFoo().mu_.Unlock();2508 2509  (bar.getFoo().mu_).Lock();   // test parenthesis2510  bar.getFoo().a = 0;2511  (bar.getFoo().mu_).Unlock();2512 2513  bar.getFoo2(a).mu_.Lock();2514  bar.getFoo2(a).a = 0;2515  bar.getFoo2(a).mu_.Unlock();2516 2517  bar.getFoo3(a, b).mu_.Lock();2518  bar.getFoo3(a, b).a = 0;2519  bar.getFoo3(a, b).mu_.Unlock();2520 2521  getBarFoo(bar, a).mu_.Lock();2522  getBarFoo(bar, a).a = 0;2523  getBarFoo(bar, a).mu_.Unlock();2524 2525  bar.getFoo2(10).mu_.Lock();2526  bar.getFoo2(10).a = 0;2527  bar.getFoo2(10).mu_.Unlock();2528 2529  bar.getFoo2(a + 1).mu_.Lock();2530  bar.getFoo2(a + 1).a = 0;2531  bar.getFoo2(a + 1).mu_.Unlock();2532 2533  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();2534  (a > 0 ? fooArray[1] : fooArray[b]).a = 0;2535  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();2536 2537  fooFuncPtr().mu_.Lock();2538  fooFuncPtr().a = 0;2539  fooFuncPtr().mu_.Unlock();2540}2541 2542 2543void test2() {2544  Foo *fooArray;2545  Bar bar;2546  int a;2547  int b;2548  int c;2549 2550  bar.getFoo().mu_.Lock();2551  bar.getFooey().a = 0; // \2552    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \2553    // expected-note {{found near match 'bar.getFoo().mu_'}}2554  bar.getFoo().mu_.Unlock();2555 2556  bar.getFoo2(a).mu_.Lock();2557  bar.getFoo2(b).a = 0; // \2558    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \2559    // expected-note {{found near match 'bar.getFoo2(a).mu_'}}2560  bar.getFoo2(a).mu_.Unlock();2561 2562  bar.getFoo3(a, b).mu_.Lock();2563  bar.getFoo3(a, c).a = 0;  // \2564    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \2565    // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}2566  bar.getFoo3(a, b).mu_.Unlock();2567 2568  getBarFoo(bar, a).mu_.Lock();2569  getBarFoo(bar, b).a = 0;  // \2570    // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \2571    // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}2572  getBarFoo(bar, a).mu_.Unlock();2573 2574  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();2575  (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \2576    // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \2577    // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}2578  (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();2579}2580 2581 2582} // end namespace MoreLockExpressions2583 2584 2585namespace TrylockJoinPoint {2586 2587class Foo {2588  Mutex mu;2589  bool c;2590 2591  void foo() {2592    if (c) {2593      if (!mu.TryLock())2594        return;2595    } else {2596      mu.Lock();2597    }2598    mu.Unlock();2599  }2600};2601 2602} // end namespace TrylockJoinPoint2603 2604 2605namespace LockReturned {2606 2607class Foo {2608public:2609  int a             GUARDED_BY(mu_);2610  void foo()        EXCLUSIVE_LOCKS_REQUIRED(mu_);2611  void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);2612 2613  static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);2614 2615  Mutex* getMu() LOCK_RETURNED(mu_);2616 2617  Mutex mu_;2618 2619  static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);2620};2621 2622 2623// Calls getMu() directly to lock and unlock2624void test1(Foo* f1, Foo* f2) {2625  f1->a = 0;       // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}2626  f1->foo();       // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}2627 2628  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \2629                   // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}2630  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}2631 2632  f1->getMu()->Lock();2633 2634  f1->a = 0;2635  f1->foo();2636  f1->foo2(f2); // \2637    // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \2638    // expected-note {{found near match 'f1->mu_'}}2639 2640  Foo::getMu(f2)->Lock();2641  f1->foo2(f2);2642  Foo::getMu(f2)->Unlock();2643 2644  Foo::sfoo(f1);2645 2646  f1->getMu()->Unlock();2647}2648 2649 2650Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));2651 2652class Bar : public Foo {2653public:2654  int  b            GUARDED_BY(getMu());2655  void bar()        EXCLUSIVE_LOCKS_REQUIRED(getMu());2656  void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());2657 2658  static void sbar(Bar* g)  EXCLUSIVE_LOCKS_REQUIRED(g->getMu());2659  static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));2660};2661 2662 2663 2664// Use getMu() within other attributes.2665// This requires at lest levels of substitution, more in the case of2666void test2(Bar* b1, Bar* b2) {2667  b1->b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}2668  b1->bar();       // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}2669  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \2670                   // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}2671  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}2672  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}2673 2674  b1->getMu()->Lock();2675 2676  b1->b = 0;2677  b1->bar();2678  b1->bar2(b2);  // \2679    // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \2680    // // expected-note {{found near match 'b1->mu_'}}2681 2682  b2->getMu()->Lock();2683  b1->bar2(b2);2684 2685  b2->getMu()->Unlock();2686 2687  Bar::sbar(b1);2688  Bar::sbar2(b1);2689 2690  b1->getMu()->Unlock();2691}2692 2693 2694// Lock the mutex directly, but use attributes that call getMu()2695// Also lock the mutex using getFooMu, which calls a lock_returned function.2696void test3(Bar* b1, Bar* b2) {2697  b1->mu_.Lock();2698  b1->b = 0;2699  b1->bar();2700 2701  getFooMu(b2)->Lock();2702  b1->bar2(b2);2703  getFooMu(b2)->Unlock();2704 2705  Bar::sbar(b1);2706  Bar::sbar2(b1);2707 2708  b1->mu_.Unlock();2709}2710 2711} // end namespace LockReturned2712 2713 2714namespace ReleasableScopedLock {2715 2716class Foo {2717  Mutex mu_;2718  bool c;2719  int a GUARDED_BY(mu_);2720 2721  void test1();2722  void test2();2723  void test3();2724  void test4();2725  void test5();2726  void test6();2727};2728 2729 2730void Foo::test1() {2731  ReleasableMutexLock rlock(&mu_);2732  rlock.Release();2733}2734 2735void Foo::test2() {2736  ReleasableMutexLock rlock(&mu_);2737  if (c) {            // test join point -- held/not held during release2738    rlock.Release();2739  }2740  // No warning on join point because the lock will be released by the scope object anyway.2741}2742 2743void Foo::test3() {2744  ReleasableMutexLock rlock(&mu_);2745  a = 0;2746  rlock.Release();2747  a = 1;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}2748}2749 2750void Foo::test4() {2751  ReleasableMutexLock rlock(&mu_);2752  rlock.Release();  // expected-note{{mutex released here}}2753  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}2754}2755 2756void Foo::test5() {2757  ReleasableMutexLock rlock(&mu_);2758  if (c) {2759    rlock.Release();2760  }2761  // No warning on join point because the lock will be released by the scope object anyway.2762  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}2763}2764 2765void Foo::test6() {2766  ReleasableMutexLock rlock(&mu_);2767  do {2768    if (c) {2769      rlock.Release();2770      break;2771    }2772  } while (c);2773  // No warning on join point because the lock will be released by the scope object anyway2774  a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}2775}2776 2777 2778} // end namespace ReleasableScopedLock2779 2780 2781namespace RelockableScopedLock {2782 2783class DeferTraits {};2784 2785class SCOPED_LOCKABLE RelockableExclusiveMutexLock {2786public:2787  RelockableExclusiveMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);2788  RelockableExclusiveMutexLock(Mutex *mu, DeferTraits) LOCKS_EXCLUDED(mu);2789  ~RelockableExclusiveMutexLock() EXCLUSIVE_UNLOCK_FUNCTION();2790 2791  void Lock() EXCLUSIVE_LOCK_FUNCTION();2792  void Unlock() UNLOCK_FUNCTION();2793};2794 2795struct SharedTraits {};2796struct ExclusiveTraits {};2797 2798class SCOPED_LOCKABLE RelockableMutexLock {2799public:2800  RelockableMutexLock(Mutex *mu, DeferTraits) LOCKS_EXCLUDED(mu);2801  RelockableMutexLock(Mutex *mu, SharedTraits) SHARED_LOCK_FUNCTION(mu);2802  RelockableMutexLock(Mutex *mu, ExclusiveTraits) EXCLUSIVE_LOCK_FUNCTION(mu);2803  ~RelockableMutexLock() UNLOCK_FUNCTION();2804 2805  void Lock() EXCLUSIVE_LOCK_FUNCTION();2806  void Unlock() UNLOCK_FUNCTION();2807 2808  void ReaderLock() SHARED_LOCK_FUNCTION();2809  void ReaderUnlock() UNLOCK_FUNCTION();2810 2811  void PromoteShared() UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();2812  void DemoteExclusive() UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();2813};2814 2815Mutex mu;2816int x GUARDED_BY(mu);2817bool b;2818 2819void print(int);2820 2821void relock() {2822  RelockableExclusiveMutexLock scope(&mu);2823  x = 2;2824  scope.Unlock();2825 2826  x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2827 2828  scope.Lock();2829  x = 4;2830}2831 2832void deferLock() {2833  RelockableExclusiveMutexLock scope(&mu, DeferTraits{});2834  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2835  scope.Lock();2836  x = 3;2837}2838 2839void relockExclusive() {2840  RelockableMutexLock scope(&mu, SharedTraits{});2841  print(x);2842  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2843  scope.ReaderUnlock();2844 2845  print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}2846 2847  scope.Lock();2848  print(x);2849  x = 4;2850 2851  scope.DemoteExclusive();2852  print(x);2853  x = 5; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2854}2855 2856void relockShared() {2857  RelockableMutexLock scope(&mu, ExclusiveTraits{});2858  print(x);2859  x = 2;2860  scope.Unlock();2861 2862  print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}2863 2864  scope.ReaderLock();2865  print(x);2866  x = 4; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2867 2868  scope.PromoteShared();2869  print(x);2870  x = 5;2871}2872 2873void deferLockShared() {2874  RelockableMutexLock scope(&mu, DeferTraits{});2875  print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}2876  scope.ReaderLock();2877  print(x);2878  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2879}2880 2881void doubleUnlock() {2882  RelockableExclusiveMutexLock scope(&mu);2883  scope.Unlock(); // expected-note{{mutex released here}}2884  scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}2885}2886 2887void doubleLock1() {2888  RelockableExclusiveMutexLock scope(&mu); // expected-note{{mutex acquired here}}2889  scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}2890}2891 2892void doubleLock2() {2893  RelockableExclusiveMutexLock scope(&mu);2894  scope.Unlock();2895  scope.Lock(); // expected-note{{mutex acquired here}}2896  scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}2897}2898 2899void lockJoin() {2900  RelockableMutexLock scope(&mu, DeferTraits{});2901  if (b)2902    scope.Lock();2903  // No warning on join point because the lock will be released by the scope object anyway.2904  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2905}2906 2907void unlockJoin() {2908  RelockableMutexLock scope(&mu, DeferTraits{});2909  scope.Lock();2910  if (b)2911    scope.Unlock();2912  // No warning on join point because the lock will be released by the scope object anyway.2913  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2914}2915 2916void loopAcquire() {2917  RelockableMutexLock scope(&mu, DeferTraits{});2918  for (unsigned i = 1; i < 10; ++i)2919    scope.Lock(); // We could catch this double lock with negative capabilities.2920}2921 2922void loopRelease() {2923  RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{mutex acquired here}}2924  // We have to warn on this join point despite the lock being managed ...2925  for (unsigned i = 1; i < 10; ++i) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}2926    x = 1; // ... because we might miss that this doesn't always happen under lock.2927    if (i == 5)2928      scope.Unlock();2929  }2930}2931 2932void loopPromote() {2933  RelockableMutexLock scope(&mu, SharedTraits{});2934  for (unsigned i = 1; i < 10; ++i) {2935    x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2936    if (i == 5)2937      scope.PromoteShared();2938  }2939}2940 2941void loopDemote() {2942  RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{the other acquisition of mutex 'mu' is here}}2943  // We have to warn on this join point despite the lock being managed ...2944  for (unsigned i = 1; i < 10; ++i) {2945    x = 1; // ... because we might miss that this doesn't always happen under exclusive lock.2946    if (i == 5)2947      scope.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}2948  }2949}2950 2951void loopAcquireContinue() {2952  RelockableMutexLock scope(&mu, DeferTraits{});2953  for (unsigned i = 1; i < 10; ++i) {2954    x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2955    if (i == 5) {2956      scope.Lock();2957      continue;2958    }2959  }2960}2961 2962void loopReleaseContinue() {2963  RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{mutex acquired here}}2964  // We have to warn on this join point despite the lock being managed ...2965  for (unsigned i = 1; i < 10; ++i) { // expected-warning {{expecting mutex 'mu' to be held at start of each loop}}2966    x = 1; // ... because we might miss that this doesn't always happen under lock.2967    if (i == 5) {2968      scope.Unlock();2969      continue;2970    }2971  }2972}2973 2974void loopPromoteContinue() {2975  RelockableMutexLock scope(&mu, SharedTraits{});2976  for (unsigned i = 1; i < 10; ++i) {2977    x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}2978    if (i == 5) {2979      scope.PromoteShared();2980      continue;2981    }2982  }2983}2984 2985void loopDemoteContinue() {2986  RelockableMutexLock scope(&mu, ExclusiveTraits{}); // expected-note {{the other acquisition of mutex 'mu' is here}}2987  // We have to warn on this join point despite the lock being managed ...2988  for (unsigned i = 1; i < 10; ++i) {2989    x = 1; // ... because we might miss that this doesn't always happen under exclusive lock.2990    if (i == 5) {2991      scope.DemoteExclusive(); // expected-warning {{mutex 'mu' is acquired exclusively and shared in the same scope}}2992      continue;2993    }2994  }2995}2996 2997void exclusiveSharedJoin() {2998  RelockableMutexLock scope(&mu, DeferTraits{});2999  if (b)3000    scope.Lock();3001  else3002    scope.ReaderLock();3003  // No warning on join point because the lock will be released by the scope object anyway.3004  print(x);3005  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3006}3007 3008void sharedExclusiveJoin() {3009  RelockableMutexLock scope(&mu, DeferTraits{});3010  if (b)3011    scope.ReaderLock();3012  else3013    scope.Lock();3014  // No warning on join point because the lock will be released by the scope object anyway.3015  print(x);3016  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3017}3018 3019void assertJoin() {3020  RelockableMutexLock scope(&mu, DeferTraits{});3021  if (b)3022    scope.Lock();3023  else3024    mu.AssertHeld();3025  x = 2;3026}3027 3028void assertSharedJoin() {3029  RelockableMutexLock scope(&mu, DeferTraits{});3030  if (b)3031    scope.ReaderLock();3032  else3033    mu.AssertReaderHeld();3034  print(x);3035  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3036}3037 3038void assertStrongerJoin() {3039  RelockableMutexLock scope(&mu, DeferTraits{});3040  if (b)3041    scope.ReaderLock();3042  else3043    mu.AssertHeld();3044  print(x);3045  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3046}3047 3048void assertWeakerJoin() {3049  RelockableMutexLock scope(&mu, DeferTraits{});3050  if (b)3051    scope.Lock();3052  else3053    mu.AssertReaderHeld();3054  print(x);3055  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3056}3057 3058void directUnlock() {3059  RelockableExclusiveMutexLock scope(&mu);3060  mu.Unlock();3061  // Debatable that there is no warning. Currently we don't track in the scoped3062  // object whether it is active, but just check if the contained locks can be3063  // reacquired. Here they can, because mu has been unlocked manually.3064  scope.Lock();3065}3066 3067void directRelock() {3068  RelockableExclusiveMutexLock scope(&mu);3069  scope.Unlock();3070  mu.Lock();3071  // Similarly debatable that there is no warning.3072  scope.Unlock();3073}3074 3075// Doesn't make a lot of sense, just making sure there is no crash.3076void destructLock() {3077  RelockableExclusiveMutexLock scope(&mu);3078  scope.~RelockableExclusiveMutexLock();3079  scope.Lock(); // Should be UB, so we don't really care.3080}3081 3082class SCOPED_LOCKABLE MemberLock {3083public:3084  MemberLock() EXCLUSIVE_LOCK_FUNCTION(mutex);3085  ~MemberLock() UNLOCK_FUNCTION(mutex);3086  void Lock() EXCLUSIVE_LOCK_FUNCTION(mutex);3087  Mutex mutex;3088};3089 3090void relockShared2() {3091  MemberLock lock; // expected-note{{mutex acquired here}}3092  lock.Lock(); // expected-warning {{acquiring mutex 'lock.mutex' that is already held}}3093}3094 3095class SCOPED_LOCKABLE WeirdScope {3096private:3097  Mutex *other;3098 3099public:3100  WeirdScope(Mutex *mutex) EXCLUSIVE_LOCK_FUNCTION(mutex);3101  void unlock() EXCLUSIVE_UNLOCK_FUNCTION() EXCLUSIVE_UNLOCK_FUNCTION(other);3102  void lock() EXCLUSIVE_LOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION(other);3103  ~WeirdScope() EXCLUSIVE_UNLOCK_FUNCTION();3104 3105  void requireOther() EXCLUSIVE_LOCKS_REQUIRED(other);3106};3107 3108void relockWeird() {3109  WeirdScope scope(&mu);3110  x = 1;3111  scope.unlock(); // expected-warning {{releasing mutex 'scope.other' that was not held}}3112  x = 2; // \3113    // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3114  scope.requireOther(); // \3115    // expected-warning {{calling function 'requireOther' requires holding mutex 'scope.other' exclusively}}3116  scope.lock(); // expected-note {{mutex acquired here}}3117  x = 3;3118  scope.requireOther();3119} // expected-warning {{mutex 'scope.other' is still held at the end of function}}3120 3121} // end namespace RelockableScopedLock3122 3123 3124namespace ScopedUnlock {3125 3126class SCOPED_LOCKABLE MutexUnlock {3127public:3128  MutexUnlock(Mutex *mu) EXCLUSIVE_UNLOCK_FUNCTION(mu);3129  ~MutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();3130 3131  void Lock() EXCLUSIVE_UNLOCK_FUNCTION();3132  void Unlock() EXCLUSIVE_LOCK_FUNCTION();3133};3134 3135class SCOPED_LOCKABLE ReaderMutexUnlock {3136public:3137  ReaderMutexUnlock(Mutex *mu) SHARED_UNLOCK_FUNCTION(mu);3138  ~ReaderMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();3139 3140  void Lock() EXCLUSIVE_UNLOCK_FUNCTION();3141  void Unlock() EXCLUSIVE_LOCK_FUNCTION();3142};3143 3144template<typename... Mus>3145class SCOPED_LOCKABLE VariadicMutexUnlock {3146public:3147  VariadicMutexUnlock(Mus *...mus) EXCLUSIVE_UNLOCK_FUNCTION(mus...);3148  ~VariadicMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();3149 3150  void Lock() EXCLUSIVE_UNLOCK_FUNCTION();3151  void Unlock() EXCLUSIVE_LOCK_FUNCTION();3152};3153 3154Mutex mu;3155int x GUARDED_BY(mu);3156bool c;3157void print(int);3158 3159void simple() EXCLUSIVE_LOCKS_REQUIRED(mu) {3160  x = 1;3161  MutexUnlock scope(&mu);3162  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3163}3164 3165void simpleShared() SHARED_LOCKS_REQUIRED(mu) {3166  print(x);3167  ReaderMutexUnlock scope(&mu);3168  print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}3169}3170 3171void innerUnlock() {3172  MutexLock outer(&mu);3173  if (x == 0) {3174    MutexUnlock inner(&mu);3175    x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3176  }3177  x = 2;3178}3179 3180void innerUnlockShared() {3181  ReaderMutexLock outer(&mu);3182  if (x == 0) {3183    ReaderMutexUnlock inner(&mu);3184    print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}3185  }3186  print(x);3187}3188 3189void manual() EXCLUSIVE_LOCKS_REQUIRED(mu) {3190  MutexUnlock scope(&mu);3191  scope.Lock();3192  x = 2;3193  scope.Unlock();3194  x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3195}3196 3197void join() EXCLUSIVE_LOCKS_REQUIRED(mu) {3198  MutexUnlock scope(&mu);3199  if (c)3200    scope.Lock();3201  // No warning on join point because the lock will be released by the scope object anyway.3202  scope.Lock();3203}3204 3205void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu) {3206  MutexUnlock scope(&mu);3207  scope.Lock(); // expected-note{{mutex acquired here}}3208  scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}3209}3210 3211void doubleUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {3212  MutexUnlock scope(&mu); // expected-note{{mutex released here}}3213  scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}3214}3215 3216Mutex mu2;3217int y GUARDED_BY(mu2);3218 3219void variadic() EXCLUSIVE_LOCKS_REQUIRED(mu, mu2) {3220  VariadicMutexUnlock<Mutex, Mutex> scope(&mu, &mu2);3221  x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3222  y = 3; // expected-warning {{writing variable 'y' requires holding mutex 'mu2' exclusively}}3223  scope.Lock();3224  x = y = 4;3225}3226 3227class SCOPED_LOCKABLE MutexLockUnlock {3228public:3229  MutexLockUnlock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_UNLOCK_FUNCTION(mu1) EXCLUSIVE_LOCK_FUNCTION(mu2);3230  ~MutexLockUnlock() EXCLUSIVE_UNLOCK_FUNCTION();3231 3232  void Release() EXCLUSIVE_UNLOCK_FUNCTION();3233  void Acquire() EXCLUSIVE_LOCK_FUNCTION();3234};3235 3236Mutex other;3237void fn() EXCLUSIVE_LOCKS_REQUIRED(other);3238 3239void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {3240  MutexLockUnlock scope(&mu, &other);3241  fn();3242  x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}3243}3244 3245} // end namespace ScopedUnlock3246 3247namespace PassingScope {3248 3249class SCOPED_LOCKABLE RelockableScope {3250public:3251  RelockableScope(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);3252  void Release() UNLOCK_FUNCTION();3253  void Acquire() EXCLUSIVE_LOCK_FUNCTION();3254  ~RelockableScope() EXCLUSIVE_UNLOCK_FUNCTION();3255};3256 3257class SCOPED_LOCKABLE ReaderRelockableScope {3258public:3259  ReaderRelockableScope(Mutex *mu) SHARED_LOCK_FUNCTION(mu);3260  void Release() UNLOCK_FUNCTION();3261  void Acquire() SHARED_LOCK_FUNCTION();3262  ~ReaderRelockableScope() UNLOCK_FUNCTION();3263};3264 3265Mutex mu;3266Mutex mu1;3267Mutex mu2;3268int x GUARDED_BY(mu);3269int y GUARDED_BY(mu) GUARDED_BY(mu2);3270void print(int);3271 3272// Analysis inside the function with annotated parameters3273 3274void sharedRequired(ReleasableMutexLock& scope SHARED_LOCKS_REQUIRED(mu)) {3275  print(x); // OK.3276}3277 3278void sharedAcquire(ReaderRelockableScope& scope SHARED_LOCK_FUNCTION(mu)) {3279  scope.Acquire();3280  print(x);3281}3282 3283void sharedRelease(RelockableScope& scope SHARED_UNLOCK_FUNCTION(mu)) {3284  print(x);3285  scope.Release();3286  print(x); // expected-warning{{reading variable 'x' requires holding mutex 'mu'}}3287}3288 3289void requiredLock(ReleasableMutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu)) {3290  x = 1; // OK.3291}3292 3293void reacquireRequiredLock(RelockableScope& scope EXCLUSIVE_LOCKS_REQUIRED(mu)) {3294  scope.Release();3295  scope.Acquire();3296  x = 2; // OK.3297}3298 3299void releaseSingleMutex(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu)) {3300  x = 1; // OK.3301  scope.Release();3302  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3303}3304 3305void releaseMultipleMutexes(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu, mu2)) {3306  y = 1; // OK.3307  scope.Release();3308  y = 2; // expected-warning{{writing variable 'y' requires holding mutex 'mu' exclusively}}3309         // expected-warning@-1{{writing variable 'y' requires holding mutex 'mu2' exclusively}}3310}3311 3312void acquireLock(RelockableScope& scope EXCLUSIVE_LOCK_FUNCTION(mu)) {3313  x = 1; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3314  scope.Acquire();3315  x = 2; // OK.3316}3317 3318void acquireMultipleLocks(RelockableScope& scope EXCLUSIVE_LOCK_FUNCTION(mu, mu2)) {3319  y = 1; // expected-warning{{writing variable 'y' requires holding mutex 'mu' exclusively}}3320         // expected-warning@-1{{writing variable 'y' requires holding mutex 'mu2' exclusively}}3321  scope.Acquire();3322  y = 2;  // OK.3323}3324 3325void excludedLock(ReleasableMutexLock& scope LOCKS_EXCLUDED(mu)) {3326  x = 1; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3327}3328 3329void acquireAndReleaseExcludedLocks(RelockableScope& scope LOCKS_EXCLUDED(mu)) {3330  scope.Acquire();3331  scope.Release();3332}3333 3334// expected-note@+1{{mutex acquired here}}3335void unreleasedMutex(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu)) {3336  x = 1; // OK.3337} // expected-warning{{mutex 'mu' is still held at the end of function}}3338 3339// expected-note@+1{{mutex acquired here}}3340void acquireAlreadyHeldMutex(RelockableScope& scope EXCLUSIVE_UNLOCK_FUNCTION(mu)) {3341  scope.Acquire(); // expected-warning{{acquiring mutex 'mu' that is already held}}3342  scope.Release();3343}3344 3345void reacquireMutex(RelockableScope& scope EXCLUSIVE_UNLOCK_FUNCTION(mu)) {3346  scope.Release();3347  scope.Acquire(); // expected-note{{mutex acquired here}}3348  x = 2; // OK.3349} // expected-warning{{mutex 'mu' is still held at the end of function}}3350 3351// expected-note@+1{{mutex acquired here}}3352void requireSingleMutex(ReleasableMutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu)) {3353  x = 1; // OK.3354  scope.Release();3355  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3356} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3357 3358// expected-note@+1 2{{mutex acquired here}}3359void requireMultipleMutexes(ReleasableMutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu, mu2)) {3360  y = 1; // OK.3361  scope.Release();3362  y = 2; // expected-warning{{writing variable 'y' requires holding mutex 'mu' exclusively}}3363         // expected-warning@-1{{writing variable 'y' requires holding mutex 'mu2' exclusively}}3364} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3365  // expected-warning@-1{{expecting mutex 'mu2' to be held at the end of function}}3366 3367// expected-note@+1{{mutex acquired here}}3368void acquireAlreadyHeldLock(RelockableScope& scope EXCLUSIVE_LOCKS_REQUIRED(mu)) {3369  scope.Acquire(); // expected-warning{{acquiring mutex 'mu' that is already held}}3370}3371 3372// expected-note@+1 {{mutex acquired here}}3373void releaseWithoutHoldingLock(ReleasableMutexLock& scope EXCLUSIVE_LOCK_FUNCTION(mu)) {3374  scope.Release(); // expected-warning{{releasing mutex 'mu' that was not held}}3375} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3376 3377// expected-note@+1 {{mutex acquired here}}3378void endWithReleasedMutex(RelockableScope& scope EXCLUSIVE_LOCK_FUNCTION(mu)) {3379  scope.Acquire();3380  scope.Release();3381} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3382 3383void acquireExcludedLock(RelockableScope& scope LOCKS_EXCLUDED(mu)) {3384  x = 1; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3385  scope.Acquire(); // expected-note {{mutex acquired here}}3386  x = 2; // OK.3387} // expected-warning{{mutex 'mu' is still held at the end of function}}3388 3389void acquireMultipleExcludedLocks(RelockableScope& scope LOCKS_EXCLUDED(mu, mu2)) {3390  y = 1; // expected-warning{{writing variable 'y' requires holding mutex 'mu' exclusively}}3391         // expected-warning@-1{{writing variable 'y' requires holding mutex 'mu2' exclusively}}3392  scope.Acquire(); // expected-note 2{{mutex acquired here}}3393  y = 2; // OK.3394} // expected-warning{{mutex 'mu' is still held at the end of function}}3395  // expected-warning@-1{{mutex 'mu2' is still held at the end of function}}3396 3397void reacquireExcludedLocks(RelockableScope& scope LOCKS_EXCLUDED(mu)) {3398  scope.Release(); // expected-warning{{releasing mutex 'mu' that was not held}}3399  scope.Acquire(); // expected-note {{mutex acquired here}}3400  x = 2; // OK.3401} // expected-warning{{mutex 'mu' is still held at the end of function}}3402 3403// expected-note@+1{{mutex acquired here}}3404void sharedRequired2(ReleasableMutexLock& scope SHARED_LOCKS_REQUIRED(mu)) {3405  print(x); // OK.3406  scope.Release();3407  print(x); // expected-warning{{reading variable 'x' requires holding mutex 'mu'}}3408} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3409 3410// expected-note@+1{{mutex acquired here}}3411void sharedAcquire2(RelockableScope& scope SHARED_LOCK_FUNCTION(mu)) {3412  print(x); // expected-warning{{reading variable 'x' requires holding mutex 'mu'}}3413  scope.Release(); // expected-warning{{releasing mutex 'mu' that was not held}}3414} // expected-warning{{expecting mutex 'mu' to be held at the end of function}}3415 3416// expected-note@+1 2{{mutex acquired here}}3417void sharedRelease2(RelockableScope& scope SHARED_UNLOCK_FUNCTION(mu)) {3418  scope.Acquire(); //expected-warning{{acquiring mutex 'mu' that is already held}}3419} //expected-warning{{mutex 'mu' is still held at the end of function}}3420 3421// Handling the call of the function with annotated parameters3422 3423// expected-note@+1{{see attribute on parameter here}}3424void release(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu));3425// expected-note@+1{{see attribute on parameter here}}3426void release_DoubleMutexLock(DoubleMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu));3427// expected-note@+1 2{{see attribute on parameter here}}3428void release_two(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu, mu2));3429// expected-note@+1{{see attribute on parameter here}}3430void release_double(DoubleMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu, mu2));3431void require(ReleasableMutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu));3432void acquire(RelockableScope& scope EXCLUSIVE_LOCK_FUNCTION(mu));3433void exclude(RelockableScope& scope LOCKS_EXCLUDED(mu));3434 3435void release_shared(ReaderRelockableScope& scope SHARED_UNLOCK_FUNCTION(mu));3436void require_shared(ReleasableMutexLock& scope SHARED_LOCKS_REQUIRED(mu));3437void acquire_shared(ReaderRelockableScope& scope SHARED_LOCK_FUNCTION(mu));3438 3439void unlockCall() {3440  ReleasableMutexLock scope(&mu);3441  x = 1; // OK.3442  release(scope);3443  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3444}3445 3446void unlockSharedCall() {3447  ReaderRelockableScope scope(&mu);3448  print(x); // OK.3449  release_shared(scope);3450  print(x); // expected-warning{{reading variable 'x' requires holding mutex 'mu'}}3451}3452 3453void requireCall() {3454  ReleasableMutexLock scope(&mu);3455  x = 1; // OK.3456  require(scope);3457  x = 2; // Ok.3458}3459 3460void requireSharedCall() {3461  ReleasableMutexLock scope(&mu);3462  print(x); // OK.3463  require_shared(scope);3464  print(x); // Ok.3465}3466 3467void acquireCall() {3468  RelockableScope scope(&mu);3469  scope.Release();3470  acquire(scope);3471  x = 2; // Ok.3472}3473 3474void acquireSharedCall() {3475  ReaderRelockableScope scope(&mu);3476  scope.Release();3477  acquire_shared(scope);3478  print(x); // Ok.3479}3480 3481void writeAfterExcludeCall() {3482  RelockableScope scope(&mu);3483  scope.Release();3484  exclude(scope);3485  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3486}3487 3488void unlockCallAfterExplicitRelease() {3489  ReleasableMutexLock scope(&mu);3490  x = 1; // OK.3491  scope.Release(); // expected-note{{mutex released here}}3492  release(scope); // expected-warning{{releasing mutex 'mu' that was not held}}3493  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3494}3495 3496void unmatchedMutexes() {3497  ReleasableMutexLock scope(&mu2);3498  release(scope); // expected-warning{{mutex managed by 'scope' is 'mu2' instead of 'mu'}}3499                  // expected-warning@-1{{releasing mutex 'mu' that was not held}}3500}3501 3502void wrongOrder() {3503  DoubleMutexLock scope(&mu2, &mu);3504  release_double(scope); // expected-warning{{mutex managed by 'scope' is 'mu2' instead of 'mu'}}3505}3506 3507void differentNumberOfMutexes() {3508  ReleasableMutexLock scope(&mu);3509  release_two(scope); // expected-warning{{mutex 'mu2' not managed by 'scope'}}3510                      // expected-warning@-1{{releasing mutex 'mu2' that was not held}}3511}3512 3513void differentNumberOfMutexes2() {3514  ReleasableMutexLock scope(&mu2);3515  release_two(scope); // expected-warning{{mutex managed by 'scope' is 'mu2' instead of 'mu'}}3516                      // expected-warning@-1{{releasing mutex 'mu' that was not held}}3517}3518 3519void differentNumberOfMutexes3() {3520  DoubleMutexLock scope(&mu, &mu2);3521  release_DoubleMutexLock(scope); // expected-warning{{did not expect mutex 'mu2' to be managed by 'scope'}}3522}3523 3524void releaseDefault(ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(mu), int = 0);3525 3526void unlockFunctionDefault() {3527  ReleasableMutexLock scope(&mu);3528  x = 1; // OK.3529  releaseDefault(scope);3530  x = 2; // expected-warning{{writing variable 'x' requires holding mutex 'mu' exclusively}}3531}3532 3533void requireCallWithReleasedLock() {3534  ReleasableMutexLock scope(&mu);3535  scope.Release();3536  require(scope);  // expected-warning{{calling function 'require' requires holding mutex 'mu' exclusively}}3537}3538 3539void acquireCallWithAlreadyHeldLock() {3540  RelockableScope scope(&mu); // expected-note{{mutex acquired here}}3541  acquire(scope); // expected-warning{{acquiring mutex 'mu' that is already held}}3542  x = 1;3543}3544 3545void excludeCallWithAlreadyHeldLock() {3546  RelockableScope scope(&mu);3547  exclude(scope); // expected-warning{{cannot call function 'exclude' while mutex 'mu' is held}}3548  x = 2; // OK.3549}3550 3551void requireConst(const ReleasableMutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu));3552void requireConstCall() {3553  requireConst(ReleasableMutexLock(&mu));3554}3555 3556void passScopeUndeclared(ReleasableMutexLock &scope) {3557  release(scope); // expected-warning{{calling function 'release' requires holding mutex 'scope' exclusively}}3558                  // expected-warning@-1{{releasing mutex 'mu' that was not held}}3559}3560 3561class SCOPED_LOCKABLE ScopedWithoutLock {3562public:3563  ScopedWithoutLock();3564 3565  ~ScopedWithoutLock() EXCLUSIVE_UNLOCK_FUNCTION();3566};3567 3568void require(ScopedWithoutLock &scope EXCLUSIVE_LOCKS_REQUIRED(mu));3569 3570void constructWithoutLock() {3571  ScopedWithoutLock scope;3572  require(scope); // expected-warning{{calling function 'require' requires holding mutex 'mu' exclusively}}3573                  // expected-warning@-1{{calling function 'require' requires holding mutex 'scope' exclusively}}3574} // expected-warning {{releasing mutex 'scope' that was not held}}3575 3576void requireConst(const ScopedWithoutLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu));3577 3578void requireCallWithReleasedLock2() {3579  requireConst(ScopedWithoutLock());3580  // expected-warning@-1{{calling function 'requireConst' requires holding mutex '#undefined' exclusively}}3581  // expected-warning@-2{{calling function 'requireConst' requires holding mutex 'mu' exclusively}}3582}3583 3584void requireDecl(RelockableScope &scope EXCLUSIVE_LOCKS_REQUIRED(mu));3585void requireDecl(RelockableScope &scope) {3586  scope.Release();3587  scope.Acquire();3588}3589 3590struct foo3591{3592  Mutex mu;3593  // expected-note@+1{{see attribute on parameter here}}3594  void require(RelockableScope &scope EXCLUSIVE_LOCKS_REQUIRED(mu));3595  void callRequire(){3596    RelockableScope scope(&mu);3597    // TODO: False positive due to incorrect parsing of parameter attribute arguments.3598    require(scope);3599    // expected-warning@-1{{calling function 'require' requires holding mutex 'mu' exclusively}}3600    // expected-warning@-2{{mutex managed by 'scope' is 'mu' instead of 'mu'}}3601  }3602};3603 3604struct ObjectWithMutex {3605  Mutex mu;3606  int x GUARDED_BY(mu);3607};3608void releaseMember(ObjectWithMutex& object, ReleasableMutexLock& scope EXCLUSIVE_UNLOCK_FUNCTION(object.mu)) {3609  object.x = 1;3610  scope.Release();3611}3612void releaseMemberCall() {3613  ObjectWithMutex obj;3614  ReleasableMutexLock lock(&obj.mu);3615  releaseMember(obj, lock);3616}3617 3618} // end namespace PassingScope3619 3620namespace TrylockFunctionTest {3621 3622class Foo {3623public:3624  Mutex mu1_;3625  Mutex mu2_;3626  bool c;3627 3628  bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);3629};3630 3631bool Foo::lockBoth() {3632  if (!mu1_.TryLock())3633    return false;3634 3635  mu2_.Lock();3636  if (!c) {3637    mu1_.Unlock();3638    mu2_.Unlock();3639    return false;3640  }3641 3642  return true;3643}3644 3645 3646}  // end namespace TrylockFunctionTest3647 3648 3649 3650namespace DoubleLockBug {3651 3652class Foo {3653public:3654  Mutex mu_;3655  int a GUARDED_BY(mu_);3656 3657  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);3658  int  foo2() SHARED_LOCKS_REQUIRED(mu_);3659};3660 3661 3662void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {3663  a = 0;3664}3665 3666int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {3667  return a;3668}3669 3670}3671 3672 3673 3674namespace UnlockBug {3675 3676class Foo {3677public:3678  Mutex mutex_;3679 3680  void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}3681    mutex_.Unlock();3682  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}3683 3684 3685  void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}3686    mutex_.Unlock();3687  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}3688};3689 3690} // end namespace UnlockBug3691 3692 3693 3694namespace FoolishScopedLockableBug {3695 3696class SCOPED_LOCKABLE WTF_ScopedLockable {3697public:3698  WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);3699 3700  // have to call release() manually;3701  ~WTF_ScopedLockable();3702 3703  void release() UNLOCK_FUNCTION();3704};3705 3706 3707class Foo {3708  Mutex mu_;3709  int a GUARDED_BY(mu_);3710  bool c;3711 3712  void doSomething();3713 3714  void test1() {3715    WTF_ScopedLockable wtf(&mu_);3716    wtf.release();3717  }3718 3719  void test2() {3720    WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}3721  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}3722 3723  void test3() {3724    if (c) {3725      WTF_ScopedLockable wtf(&mu_);3726      wtf.release();3727    }3728  }3729 3730  void test4() {3731    if (c) {3732      doSomething();3733    }3734    else {3735      WTF_ScopedLockable wtf(&mu_);3736      wtf.release();3737    }3738  }3739 3740  void test5() {3741    if (c) {3742      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}3743    }3744  } // expected-warning {{mutex 'mu_' is not held on every path through here}}3745 3746  void test6() {3747    if (c) {3748      doSomething();3749    }3750    else {3751      WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}3752    }3753  } // expected-warning {{mutex 'mu_' is not held on every path through here}}3754};3755 3756 3757} // end namespace FoolishScopedLockableBug3758 3759 3760 3761namespace TemporaryCleanupExpr {3762 3763class Foo {3764  int a GUARDED_BY(getMutexPtr().get());3765 3766  SmartPtr<Mutex> getMutexPtr();3767 3768  void test();3769};3770 3771 3772void Foo::test() {3773  {3774    ReaderMutexLock lock(getMutexPtr().get());3775    int b = a;3776  }3777  int b = a;  // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}3778}3779 3780#ifdef __cpp_guaranteed_copy_elision3781 3782void guaranteed_copy_elision() {3783  MutexLock lock = MutexLock{&sls_mu};3784  sls_guard_var = 0;3785}3786 3787void guaranteed_copy_elision_const() {3788  const MutexLock lock = MutexLock{&sls_mu};3789  sls_guard_var = 0;3790}3791 3792#endif3793 3794} // end namespace TemporaryCleanupExpr3795 3796 3797 3798namespace SmartPointerTests {3799 3800class Foo {3801public:3802  SmartPtr<Mutex> mu_;3803  int a GUARDED_BY(mu_);3804  int b GUARDED_BY(mu_.get());3805  int c GUARDED_BY(*mu_);3806 3807  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);3808  void Unlock() UNLOCK_FUNCTION(mu_);3809 3810  void test0();3811  void test1();3812  void test2();3813  void test3();3814  void test4();3815  void test5();3816  void test6();3817  void test7();3818  void test8();3819};3820 3821void Foo::test0() {3822  a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}3823  b = 0;  // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}3824  c = 0;  // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}3825}3826 3827void Foo::test1() {3828  mu_->Lock();3829  a = 0;3830  b = 0;3831  c = 0;3832  mu_->Unlock();3833}3834 3835void Foo::test2() {3836  (*mu_).Lock();3837  a = 0;3838  b = 0;3839  c = 0;3840  (*mu_).Unlock();3841}3842 3843 3844void Foo::test3() {3845  mu_.get()->Lock();3846  a = 0;3847  b = 0;3848  c = 0;3849  mu_.get()->Unlock();3850}3851 3852 3853void Foo::test4() {3854  MutexLock lock(mu_.get());3855  a = 0;3856  b = 0;3857  c = 0;3858}3859 3860 3861void Foo::test5() {3862  MutexLock lock(&(*mu_));3863  a = 0;3864  b = 0;3865  c = 0;3866}3867 3868 3869void Foo::test6() {3870  Lock();3871  a = 0;3872  b = 0;3873  c = 0;3874  Unlock();3875}3876 3877 3878void Foo::test7() {3879  {3880    Lock();3881    mu_->Unlock();3882  }3883  {3884    mu_->Lock();3885    Unlock();3886  }3887  {3888    mu_.get()->Lock();3889    mu_->Unlock();3890  }3891  {3892    mu_->Lock();3893    mu_.get()->Unlock();3894  }3895  {3896    mu_.get()->Lock();3897    (*mu_).Unlock();3898  }3899  {3900    (*mu_).Lock();3901    mu_->Unlock();3902  }3903}3904 3905 3906void Foo::test8() {3907  mu_->Lock();          // expected-note 2 {{mutex acquired here}}3908  mu_.get()->Lock();    // expected-warning {{acquiring mutex 'mu_' that is already held}}3909  (*mu_).Lock();        // expected-warning {{acquiring mutex 'mu_' that is already held}}3910  mu_.get()->Unlock();  // expected-note {{mutex released here}}3911  Unlock();             // expected-warning {{releasing mutex 'mu_' that was not held}}3912}3913 3914 3915class Bar {3916  SmartPtr<Foo> foo;3917 3918  void test0();3919  void test1();3920  void test2();3921  void test3();3922};3923 3924 3925void Bar::test0() {3926  foo->a = 0;         // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}3927  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}3928  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}3929}3930 3931 3932void Bar::test1() {3933  foo->mu_->Lock();3934  foo->a = 0;3935  (*foo).b = 0;3936  foo.get()->c = 0;3937  foo->mu_->Unlock();3938}3939 3940 3941void Bar::test2() {3942  (*foo).mu_->Lock();3943  foo->a = 0;3944  (*foo).b = 0;3945  foo.get()->c = 0;3946  foo.get()->mu_->Unlock();3947}3948 3949 3950void Bar::test3() {3951  MutexLock lock(foo->mu_.get());3952  foo->a = 0;3953  (*foo).b = 0;3954  foo.get()->c = 0;3955}3956 3957}  // end namespace SmartPointerTests3958 3959 3960 3961namespace DuplicateAttributeTest {3962 3963class LOCKABLE Foo {3964public:3965  Mutex mu1_;3966  Mutex mu2_;3967  Mutex mu3_;3968  int a GUARDED_BY(mu1_);3969  int b GUARDED_BY(mu2_);3970  int c GUARDED_BY(mu3_);3971 3972  void lock()   EXCLUSIVE_LOCK_FUNCTION();3973  void unlock() UNLOCK_FUNCTION();3974 3975  void lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_);3976  void slock1() SHARED_LOCK_FUNCTION(mu1_);3977  void lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);3978  void locklots()3979    EXCLUSIVE_LOCK_FUNCTION(mu1_)3980    EXCLUSIVE_LOCK_FUNCTION(mu2_)3981    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);3982 3983  void unlock1() UNLOCK_FUNCTION(mu1_);3984  void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);3985  void unlocklots()3986    UNLOCK_FUNCTION(mu1_)3987    UNLOCK_FUNCTION(mu2_)3988    UNLOCK_FUNCTION(mu1_, mu2_, mu3_);3989};3990 3991 3992void Foo::lock()   EXCLUSIVE_LOCK_FUNCTION() { }3993void Foo::unlock() UNLOCK_FUNCTION()         { }3994 3995void Foo::lock1()  EXCLUSIVE_LOCK_FUNCTION(mu1_) {3996  mu1_.Lock();3997}3998 3999void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {4000  mu1_.ReaderLock();4001}4002 4003void Foo::lock3()  EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {4004  mu1_.Lock();4005  mu2_.Lock();4006  mu3_.Lock();4007}4008 4009void Foo::locklots()4010    EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)4011    EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {4012  mu1_.Lock();4013  mu2_.Lock();4014  mu3_.Lock();4015}4016 4017void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {4018  mu1_.Unlock();4019}4020 4021void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {4022  mu1_.Unlock();4023  mu2_.Unlock();4024  mu3_.Unlock();4025}4026 4027void Foo::unlocklots()4028    UNLOCK_FUNCTION(mu1_, mu2_)4029    UNLOCK_FUNCTION(mu2_, mu3_) {4030  mu1_.Unlock();4031  mu2_.Unlock();4032  mu3_.Unlock();4033}4034 4035 4036void test0() {4037  Foo foo;4038  foo.lock();4039  foo.unlock();4040 4041  foo.lock();     // expected-note{{mutex acquired here}}4042  foo.lock();     // expected-warning {{acquiring mutex 'foo' that is already held}}4043  foo.unlock();   // expected-note{{mutex released here}}4044  foo.unlock();   // expected-warning {{releasing mutex 'foo' that was not held}}4045}4046 4047 4048void test1() {4049  Foo foo;4050  foo.lock1();4051  foo.a = 0;4052  foo.unlock1();4053 4054  foo.lock1();    // expected-note{{mutex acquired here}}4055  foo.lock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}4056  foo.a = 0;4057  foo.unlock1();  // expected-note{{mutex released here}}4058  foo.unlock1();  // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}4059}4060 4061 4062int test2() {4063  Foo foo;4064  foo.slock1();4065  int d1 = foo.a;4066  foo.unlock1();4067 4068  foo.slock1();    // expected-note{{mutex acquired here}}4069  foo.slock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}4070  int d2 = foo.a;4071  foo.unlock1();   // expected-note{{mutex released here}}4072  foo.unlock1();   // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}4073  return d1 + d2;4074}4075 4076 4077void test3() {4078  Foo foo;4079  foo.lock3();4080  foo.a = 0;4081  foo.b = 0;4082  foo.c = 0;4083  foo.unlock3();4084 4085  foo.lock3(); // expected-note 3 {{mutex acquired here}}4086  foo.lock3(); // \4087    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \4088    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \4089    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}4090  foo.a = 0;4091  foo.b = 0;4092  foo.c = 0;4093  foo.unlock3(); // expected-note 3 {{mutex released here}}4094  foo.unlock3(); // \4095    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \4096    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \4097    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}4098}4099 4100 4101void testlots() {4102  Foo foo;4103  foo.locklots();4104  foo.a = 0;4105  foo.b = 0;4106  foo.c = 0;4107  foo.unlocklots();4108 4109  foo.locklots(); // expected-note 3 {{mutex acquired here}}4110  foo.locklots(); // \4111    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \4112    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \4113    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}4114  foo.a = 0;4115  foo.b = 0;4116  foo.c = 0;4117  foo.unlocklots(); // expected-note 3 {{mutex released here}}4118  foo.unlocklots(); // \4119    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \4120    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \4121    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}4122}4123 4124}  // end namespace DuplicateAttributeTest4125 4126 4127 4128namespace TryLockEqTest {4129 4130class Foo {4131  Mutex mu_;4132  int a GUARDED_BY(mu_);4133  bool c;4134 4135  int    tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);4136  Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);4137  void unlock() UNLOCK_FUNCTION(mu_);4138 4139  void test1();4140  void test2();4141};4142 4143 4144void Foo::test1() {4145  if (tryLockMutexP() == 0) {4146    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4147    return;4148  }4149  a = 0;4150  unlock();4151 4152  if (tryLockMutexP() != 0) {4153    a = 0;4154    unlock();4155  }4156 4157  if (0 != tryLockMutexP()) {4158    a = 0;4159    unlock();4160  }4161 4162  if (!(tryLockMutexP() == 0)) {4163    a = 0;4164    unlock();4165  }4166 4167  if (tryLockMutexI() == 0) {4168    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4169    return;4170  }4171  a = 0;4172  unlock();4173 4174  if (0 == tryLockMutexI()) {4175    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4176    return;4177  }4178  a = 0;4179  unlock();4180 4181  if (tryLockMutexI() == 1) {4182    a = 0;4183    unlock();4184  }4185 4186  if (mu_.TryLock() == false) {4187    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4188    return;4189  }4190  a = 0;4191  unlock();4192 4193  if (mu_.TryLock() == true) {4194    a = 0;4195    unlock();4196  }4197  else {4198    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4199  }4200 4201#if __has_feature(cxx_nullptr)4202  if (tryLockMutexP() == nullptr) {4203    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4204    return;4205  }4206  a = 0;4207  unlock();4208#endif4209}4210 4211} // end namespace TryLockEqTest4212 4213 4214namespace ExistentialPatternMatching {4215 4216class Graph {4217public:4218  Mutex mu_;4219};4220 4221void LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);4222void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);4223 4224class Node {4225public:4226  int a GUARDED_BY(&Graph::mu_);4227 4228  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {4229    a = 0;4230  }4231  void foo2() LOCKS_EXCLUDED(&Graph::mu_);4232};4233 4234void test() {4235  Graph g1;4236  Graph g2;4237  Node n1;4238 4239  n1.a = 0;   // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}4240  n1.foo();   // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}4241  n1.foo2();4242 4243  g1.mu_.Lock();4244  n1.a = 0;4245  n1.foo();4246  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}4247  g1.mu_.Unlock();4248 4249  g2.mu_.Lock();4250  n1.a = 0;4251  n1.foo();4252  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}4253  g2.mu_.Unlock();4254 4255  LockAllGraphs();4256  n1.a = 0;4257  n1.foo();4258  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}4259  UnlockAllGraphs();4260 4261  LockAllGraphs();4262  g1.mu_.Unlock();4263 4264  LockAllGraphs();4265  g2.mu_.Unlock();4266 4267  LockAllGraphs(); // expected-note{{mutex acquired here}}4268  g1.mu_.Lock();  // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}4269  g1.mu_.Unlock();4270}4271 4272} // end namespace ExistentialPatternMatching4273 4274 4275namespace StringIgnoreTest {4276 4277class Foo {4278public:4279  Mutex mu_;4280  void lock()   EXCLUSIVE_LOCK_FUNCTION("");4281  void unlock() UNLOCK_FUNCTION("");4282  void goober() EXCLUSIVE_LOCKS_REQUIRED("");4283  void roober() SHARED_LOCKS_REQUIRED("");4284};4285 4286 4287class Bar : public Foo {4288public:4289  void bar(Foo* f) {4290    f->unlock();4291    f->goober();4292    f->roober();4293    f->lock();4294  };4295};4296 4297} // end namespace StringIgnoreTest4298 4299 4300namespace LockReturnedScopeFix {4301 4302class Base {4303protected:4304  struct Inner;4305  bool c;4306 4307  const Mutex& getLock(const Inner* i);4308 4309  void lockInner  (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));4310  void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));4311  void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));4312 4313  void bar(Inner* i);4314};4315 4316 4317struct Base::Inner {4318  Mutex lock_;4319  void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);4320};4321 4322 4323const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {4324  return i->lock_;4325}4326 4327 4328void Base::foo(Inner* i) {4329  i->doSomething();4330}4331 4332void Base::bar(Inner* i) {4333  if (c) {4334    i->lock_.Lock();4335    unlockInner(i);4336  }4337  else {4338    lockInner(i);4339    i->lock_.Unlock();4340  }4341}4342 4343} // end namespace LockReturnedScopeFix4344 4345 4346namespace TrylockWithCleanups {4347 4348struct Foo {4349  Mutex mu_;4350  int a GUARDED_BY(mu_);4351};4352 4353Foo* GetAndLockFoo(const MyString& s)4354    EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);4355 4356static void test() {4357  Foo* lt = GetAndLockFoo("foo");4358  if (!lt) return;4359  int a = lt->a;4360  lt->mu_.Unlock();4361}4362 4363}  // end namespace TrylockWithCleanups4364 4365 4366namespace UniversalLock {4367 4368class Foo {4369  Mutex mu_;4370  bool c;4371 4372  int a        GUARDED_BY(mu_);4373  void r_foo() SHARED_LOCKS_REQUIRED(mu_);4374  void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);4375 4376  void test1() {4377    int b;4378 4379    beginNoWarnOnReads();4380    b = a;4381    r_foo();4382    endNoWarnOnReads();4383 4384    beginNoWarnOnWrites();4385    a = 0;4386    w_foo();4387    endNoWarnOnWrites();4388  }4389 4390  // don't warn on joins with universal lock4391  void test2() {4392    if (c) {4393      beginNoWarnOnWrites();4394    }4395    a = 0; // \4396      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}4397    endNoWarnOnWrites(); // \4398      // expected-warning {{releasing wildcard '*' that was not held}}4399  }4400 4401 4402  // make sure the universal lock joins properly4403  void test3() {4404    if (c) {4405      mu_.Lock();4406      beginNoWarnOnWrites();4407    }4408    else {4409      beginNoWarnOnWrites();4410      mu_.Lock();4411    }4412    a = 0;4413    endNoWarnOnWrites();4414    mu_.Unlock();4415  }4416 4417 4418  // combine universal lock with other locks4419  void test4() {4420    beginNoWarnOnWrites();4421    mu_.Lock();4422    mu_.Unlock();4423    endNoWarnOnWrites();4424 4425    mu_.Lock();4426    beginNoWarnOnWrites();4427    endNoWarnOnWrites();4428    mu_.Unlock();4429 4430    mu_.Lock();4431    beginNoWarnOnWrites();4432    mu_.Unlock();4433    endNoWarnOnWrites();4434  }4435};4436 4437}  // end namespace UniversalLock4438 4439 4440namespace TemplateLockReturned {4441 4442template<class T>4443class BaseT {4444public:4445  virtual void baseMethod() = 0;4446  Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }4447 4448  Mutex mutex_;4449  int a GUARDED_BY(mutex_);4450};4451 4452 4453class Derived : public BaseT<int> {4454public:4455  void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {4456    a = 0;4457  }4458};4459 4460}  // end namespace TemplateLockReturned4461 4462 4463namespace ExprMatchingBugFix {4464 4465class Foo {4466public:4467  Mutex mu_;4468};4469 4470 4471class Bar {4472public:4473  bool c;4474  Foo* foo;4475  Bar(Foo* f) : foo(f) { }4476 4477  struct Nested {4478    Foo* foo;4479    Nested(Foo* f) : foo(f) { }4480 4481    void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);4482  };4483 4484  void test();4485};4486 4487 4488void Bar::test() {4489  foo->mu_.Lock();4490  if (c) {4491    Nested *n = new Nested(foo);4492    n->unlockFoo();4493  }4494  else {4495    foo->mu_.Unlock();4496  }4497}4498 4499}; // end namespace ExprMatchingBugfix4500 4501 4502namespace ComplexNameTest {4503 4504class Foo {4505public:4506  static Mutex mu_;4507 4508  Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_)  { }4509  ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }4510 4511  int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }4512};4513 4514class Bar {4515public:4516  static Mutex mu_;4517 4518  Bar()  LOCKS_EXCLUDED(mu_) { }4519  ~Bar() LOCKS_EXCLUDED(mu_) { }4520 4521  int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }4522};4523 4524 4525void test1() {4526  Foo f;           // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}4527  int a = f[0];    // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}4528}                  // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}4529 4530 4531void test2() {4532  Bar::mu_.Lock();4533  {4534    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}4535    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}4536  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}4537  Bar::mu_.Unlock();4538}4539 4540};  // end namespace ComplexNameTest4541 4542 4543namespace UnreachableExitTest {4544 4545class FemmeFatale {4546public:4547  FemmeFatale();4548  ~FemmeFatale() __attribute__((noreturn));4549};4550 4551void exitNow() __attribute__((noreturn));4552void exitDestruct(const MyString& ms) __attribute__((noreturn));4553 4554Mutex fatalmu_;4555 4556void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {4557  exitNow();4558}4559 4560void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {4561  FemmeFatale femme;4562}4563 4564bool c;4565 4566void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {4567  if (c) {4568    exitNow();4569  }4570  else {4571    FemmeFatale femme;4572  }4573}4574 4575void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {4576  exitDestruct("foo");4577}4578 4579}   // end namespace UnreachableExitTest4580 4581 4582namespace VirtualMethodCanonicalizationTest {4583 4584class Base {4585public:4586  virtual Mutex* getMutex() = 0;4587};4588 4589class Base2 : public Base {4590public:4591  Mutex* getMutex();4592};4593 4594class Base3 : public Base2 {4595public:4596  Mutex* getMutex();4597};4598 4599class Derived : public Base3 {4600public:4601  Mutex* getMutex();  // overrides Base::getMutex()4602};4603 4604void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }4605 4606void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {4607  baseFun(d);4608}4609 4610}  // end namespace VirtualMethodCanonicalizationTest4611 4612 4613namespace TemplateFunctionParamRemapTest {4614 4615template <class T>4616struct Cell {4617  T dummy_;4618  Mutex* mu_;4619};4620 4621class Foo {4622public:4623  template <class T>4624  void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);4625 4626  void test();4627};4628 4629template<class T>4630void Foo::elr(Cell<T>* c1) { }4631 4632void Foo::test() {4633  Cell<int> cell;4634  elr(&cell); // \4635    // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}4636}4637 4638 4639template<class T>4640void globalELR(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);4641 4642template<class T>4643void globalELR(Cell<T>* c1) { }4644 4645void globalTest() {4646  Cell<int> cell;4647  globalELR(&cell); // \4648    // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}4649}4650 4651 4652template<class T>4653void globalELR2(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);4654 4655// second declaration4656template<class T>4657void globalELR2(Cell<T>* c2);4658 4659template<class T>4660void globalELR2(Cell<T>* c3) { }4661 4662// re-declaration after definition4663template<class T>4664void globalELR2(Cell<T>* c4);4665 4666void globalTest2() {4667  Cell<int> cell;4668  globalELR2(&cell); // \4669    // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}4670}4671 4672 4673template<class T>4674class FooT {4675public:4676  void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);4677};4678 4679template<class T>4680void FooT<T>::elr(Cell<T>* c1) { }4681 4682void testFooT() {4683  Cell<int> cell;4684  FooT<int> foo;4685  foo.elr(&cell); // \4686    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}4687}4688 4689}  // end namespace TemplateFunctionParamRemapTest4690 4691 4692namespace SelfConstructorTest {4693 4694class SelfLock {4695public:4696  SelfLock()  EXCLUSIVE_LOCK_FUNCTION(mu_);4697  ~SelfLock() UNLOCK_FUNCTION(mu_);4698 4699  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);4700 4701  Mutex mu_;4702};4703 4704class LOCKABLE SelfLock2 {4705public:4706  SelfLock2()  EXCLUSIVE_LOCK_FUNCTION();4707  ~SelfLock2() UNLOCK_FUNCTION();4708 4709  void foo() EXCLUSIVE_LOCKS_REQUIRED(this);4710};4711 4712class SelfLockDeferred {4713public:4714  SelfLockDeferred() LOCKS_EXCLUDED(mu_);4715  ~SelfLockDeferred() UNLOCK_FUNCTION(mu_);4716 4717  Mutex mu_;4718};4719 4720class LOCKABLE SelfLockDeferred2 {4721public:4722  SelfLockDeferred2() LOCKS_EXCLUDED(this);4723  ~SelfLockDeferred2() UNLOCK_FUNCTION();4724};4725 4726 4727void test() {4728  SelfLock s;4729  s.foo();4730}4731 4732void test2() {4733  SelfLock2 s2;4734  s2.foo();4735}4736 4737void testDeferredTemporary() {4738  SelfLockDeferred(); // expected-warning {{releasing mutex '<temporary>.mu_' that was not held}}4739}4740 4741void testDeferredTemporary2() {4742  SelfLockDeferred2(); // expected-warning {{releasing mutex '<temporary>' that was not held}}4743}4744 4745}  // end namespace SelfConstructorTest4746 4747 4748namespace MultipleAttributeTest {4749 4750class Foo {4751  Mutex mu1_;4752  Mutex mu2_;4753  int  a GUARDED_BY(mu1_);4754  int  b GUARDED_BY(mu2_);4755  int  c GUARDED_BY(mu1_)    GUARDED_BY(mu2_);4756  int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);4757 4758  void foo1()          EXCLUSIVE_LOCKS_REQUIRED(mu1_)4759                       EXCLUSIVE_LOCKS_REQUIRED(mu2_);4760  void foo2()          SHARED_LOCKS_REQUIRED(mu1_)4761                       SHARED_LOCKS_REQUIRED(mu2_);4762  void foo3()          LOCKS_EXCLUDED(mu1_)4763                       LOCKS_EXCLUDED(mu2_);4764  void lock()          EXCLUSIVE_LOCK_FUNCTION(mu1_)4765                       EXCLUSIVE_LOCK_FUNCTION(mu2_);4766  void readerlock()    SHARED_LOCK_FUNCTION(mu1_)4767                       SHARED_LOCK_FUNCTION(mu2_);4768  void unlock()        UNLOCK_FUNCTION(mu1_)4769                       UNLOCK_FUNCTION(mu2_);4770  bool trylock()       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)4771                       EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);4772  bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)4773                       SHARED_TRYLOCK_FUNCTION(true, mu2_);4774  void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)4775                    ASSERT_EXCLUSIVE_LOCK(mu2_);4776 4777  void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);4778 4779  void assertShared() ASSERT_SHARED_LOCK(mu1_)4780                      ASSERT_SHARED_LOCK(mu2_);4781 4782  void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);4783 4784  void test();4785  void testAssert();4786  void testAssertShared();4787};4788 4789 4790void Foo::foo1() {4791  a = 1;4792  b = 2;4793}4794 4795void Foo::foo2() {4796  int result = a + b;4797}4798 4799void Foo::foo3() { }4800void Foo::lock() { mu1_.Lock();  mu2_.Lock(); }4801void Foo::readerlock() { mu1_.ReaderLock();  mu2_.ReaderLock(); }4802void Foo::unlock() { mu1_.Unlock();  mu2_.Unlock(); }4803bool Foo::trylock()       { return true; }4804bool Foo::readertrylock() { return true; }4805 4806 4807void Foo::test() {4808  mu1_.Lock();4809  foo1();             // expected-warning {{}}4810  c = 0;              // expected-warning {{}}4811  *d = 0;             // expected-warning {{}}4812  mu1_.Unlock();4813 4814  mu1_.ReaderLock();4815  foo2();             // expected-warning {{}}4816  int x = c;          // expected-warning {{}}4817  int y = *d;         // expected-warning {{}}4818  mu1_.Unlock();4819 4820  mu2_.Lock();4821  foo3();             // expected-warning {{}}4822  mu2_.Unlock();4823 4824  lock();4825  a = 0;4826  b = 0;4827  unlock();4828 4829  readerlock();4830  int z = a + b;4831  unlock();4832 4833  if (trylock()) {4834    a = 0;4835    b = 0;4836    unlock();4837  }4838 4839  if (readertrylock()) {4840    int zz = a + b;4841    unlock();4842  }4843}4844 4845// Force duplication of attributes4846void Foo::assertBoth() { }4847void Foo::alsoAssertBoth() { }4848void Foo::assertShared() { }4849void Foo::alsoAssertShared() { }4850 4851void Foo::testAssert() {4852  {4853    assertBoth();4854    a = 0;4855    b = 0;4856  }4857  {4858    alsoAssertBoth();4859    a = 0;4860    b = 0;4861  }4862}4863 4864void Foo::testAssertShared() {4865  {4866    assertShared();4867    int zz = a + b;4868  }4869 4870  {4871    alsoAssertShared();4872    int zz = a + b;4873  }4874}4875 4876 4877}  // end namespace MultipleAttributeTest4878 4879 4880namespace GuardedNonPrimitiveTypeTest {4881 4882 4883class Data {4884public:4885  Data(int i) : dat(i) { }4886 4887  int  getValue() const { return dat; }4888  void setValue(int i)  { dat = i; }4889 4890  int  operator[](int i) const { return dat; }4891  int& operator[](int i)       { return dat; }4892 4893  void operator()() { }4894 4895  Data& operator+=(int);4896  Data& operator-=(int);4897  Data& operator*=(int);4898  Data& operator/=(int);4899  Data& operator%=(int);4900  Data& operator^=(int);4901  Data& operator&=(int);4902  Data& operator|=(int);4903  Data& operator<<=(int);4904  Data& operator>>=(int);4905  Data& operator++();4906  Data& operator++(int);4907  Data& operator--();4908  Data& operator--(int);4909 4910private:4911  int dat;4912};4913 4914class DataWithAddrOf : public Data {4915public:4916  const Data* operator&();4917  const Data* operator&() const;4918};4919 4920class DataCell {4921public:4922  DataCell(const Data& d) : dat(d) { }4923 4924private:4925  Data dat;4926};4927 4928 4929void showData(const Data* d);4930void showDataCell(const DataCell& dc);4931 4932 4933class Foo {4934public:4935  // method call tests4936  void test() {4937    data_.setValue(0);         // FIXME -- should be writing \4938      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}4939    int a = data_.getValue();  // \4940      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}4941 4942    datap1_->setValue(0);      // FIXME -- should be writing \4943      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}4944    a = datap1_->getValue();   // \4945      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}4946 4947    datap2_->setValue(0);      // FIXME -- should be writing \4948      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4949    a = datap2_->getValue();   // \4950      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4951 4952    (*datap2_).setValue(0);    // FIXME -- should be writing \4953      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4954    a = (*datap2_).getValue(); // \4955      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4956 4957    mu_.Lock();4958    data_.setValue(1);4959    datap1_->setValue(1);4960    datap2_->setValue(1);4961    mu_.Unlock();4962 4963    mu_.ReaderLock();4964    a = data_.getValue();4965    datap1_->setValue(0);  // reads datap1_, writes *datap1_4966    a = datap1_->getValue();4967    a = datap2_->getValue();4968    mu_.Unlock();4969  }4970 4971  // operator tests4972  void test2() {4973    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4974    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \4975                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}4976    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \4977                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}4978    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \4979                          // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}4980    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \4981                          // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4982    data_ += 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4983    data_ -= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4984    data_ *= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4985    data_ /= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4986    data_ %= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4987    data_ ^= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4988    data_ &= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4989    data_ |= 1;           // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4990    data_ <<= 1;          // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4991    data_ >>= 1;          // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4992    ++data_;              // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4993    data_++;              // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4994    --data_;              // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4995    data_--;              // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}4996 4997    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}4998    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}4999 5000    data_();              // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}5001 5002    // Calls operator&, and does not take the address.5003    (void)&data_ao_;      // expected-warning {{reading variable 'data_ao_' requires holding mutex 'mu_'}}5004    (void)__builtin_addressof(data_ao_); // expected-warning {{passing variable 'data_ao_' by reference requires holding mutex 'mu_'}}5005    showData(&data_ao_);  // expected-warning {{reading variable 'data_ao_' requires holding mutex 'mu_'}}5006  }5007 5008  // const operator tests5009  void test3() const {5010    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}5011 5012    //FIXME5013    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}5014    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}5015 5016    int a = data_[0];       // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}5017 5018    (void)&data_ao_;      // expected-warning {{reading variable 'data_ao_' requires holding mutex 'mu_'}}5019    showData(&data_ao_);  // expected-warning {{reading variable 'data_ao_' requires holding mutex 'mu_'}}5020  }5021 5022private:5023  Mutex mu_;5024  Data  data_   GUARDED_BY(mu_);5025  Data* datap1_ GUARDED_BY(mu_);5026  Data* datap2_ PT_GUARDED_BY(mu_);5027  DataWithAddrOf data_ao_ GUARDED_BY(mu_);5028};5029 5030}  // end namespace GuardedNonPrimitiveTypeTest5031 5032 5033namespace GuardedNonPrimitive_MemberAccess {5034 5035class Cell {5036public:5037  Cell(int i);5038 5039  void cellMethod();5040 5041  int a;5042};5043 5044 5045class Foo {5046public:5047  int   a;5048  Cell  c  GUARDED_BY(cell_mu_);5049  Cell* cp PT_GUARDED_BY(cell_mu_);5050 5051  void myMethod();5052 5053  Mutex cell_mu_;5054};5055 5056 5057class Bar {5058private:5059  Mutex mu_;5060  Foo  foo  GUARDED_BY(mu_);5061  Foo* foop PT_GUARDED_BY(mu_);5062 5063  void test() {5064    foo.myMethod();      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}5065 5066    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}5067    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}5068 5069    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}5070    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}5071 5072    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}5073    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}5074 5075    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \5076                         // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}5077    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \5078                         // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}5079 5080    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \5081                           // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}5082    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \5083                           // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}5084 5085    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \5086                             // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}5087    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \5088                             // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}5089  };5090};5091 5092}  // namespace GuardedNonPrimitive_MemberAccess5093 5094 5095namespace TestThrowExpr {5096 5097class Foo {5098  Mutex mu_;5099 5100  bool hasError();5101 5102  void test() {5103    mu_.Lock();5104    if (hasError()) {5105      throw "ugly";5106    }5107    mu_.Unlock();5108  }5109};5110 5111}  // end namespace TestThrowExpr5112 5113 5114namespace UnevaluatedContextTest {5115 5116// parse attribute expressions in an unevaluated context.5117 5118static inline Mutex* getMutex1();5119static inline Mutex* getMutex2();5120 5121void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());5122 5123void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());5124 5125}  // end namespace UnevaluatedContextTest5126 5127 5128namespace LockUnlockFunctionTest {5129 5130// Check built-in lock functions5131class LOCKABLE MyLockable  {5132public:5133  void lock()       EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }5134  void readerLock() SHARED_LOCK_FUNCTION()    { mu_.ReaderLock(); }5135  void unlock()     UNLOCK_FUNCTION()         { mu_.Unlock(); }5136 5137private:5138  Mutex mu_;5139};5140 5141 5142class Foo {5143public:5144  // Correct lock/unlock functions5145  void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {5146    mu_.Lock();5147  }5148 5149  void readerLock() SHARED_LOCK_FUNCTION(mu_) {5150    mu_.ReaderLock();5151  }5152 5153  void unlock() UNLOCK_FUNCTION(mu_) {5154    mu_.Unlock();5155  }5156 5157  void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_) {5158    mu_.Unlock();5159  }5160 5161  void unlockShared() SHARED_UNLOCK_FUNCTION(mu_) {5162    mu_.ReaderUnlock();5163  }5164 5165  // Check failure to lock.5166  void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}5167    mu2_.Lock();5168    mu2_.Unlock();5169  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}5170 5171  void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}5172    mu2_.Lock();5173    mu2_.Unlock();5174  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}5175 5176  void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}5177    mu2_.Lock();5178    mu2_.Unlock();5179  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}5180 5181  // Check locking the wrong thing.5182  void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}5183    mu2_.Lock();            // expected-note {{mutex acquired here}}5184  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \5185    // expected-warning {{mutex 'mu2_' is still held at the end of function}}5186 5187 5188  void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}5189    mu2_.ReaderLock();      // expected-note {{mutex acquired here}}5190  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \5191    // expected-warning {{mutex 'mu2_' is still held at the end of function}}5192 5193 5194  void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}5195    mu2_.Unlock();  // expected-warning {{releasing mutex 'mu2_' that was not held}}5196  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}5197 5198private:5199  Mutex mu_;5200  Mutex mu2_;5201};5202 5203}  // end namespace LockUnlockFunctionTest5204 5205 5206namespace AssertHeldTest {5207 5208class Foo {5209public:5210  int c;5211  int a GUARDED_BY(mu_);5212  Mutex mu_;5213 5214  void test1() {5215    mu_.AssertHeld();5216    int b = a;5217    a = 0;5218  }5219 5220  void test2() {5221    mu_.AssertReaderHeld();5222    int b = a;5223    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}5224  }5225 5226  void test3() {5227    if (c) {5228      mu_.AssertHeld();5229    }5230    else {5231      mu_.AssertHeld();5232    }5233    int b = a;5234    a = 0;5235  }5236 5237  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {5238    mu_.AssertHeld();5239    int b = a;5240    a = 0;5241  }5242 5243  void test5() UNLOCK_FUNCTION(mu_) {5244    mu_.AssertHeld();5245    mu_.Unlock();5246  }5247 5248  void test6() {5249    mu_.AssertHeld();5250    mu_.Unlock(); // should this be a warning?5251  }5252 5253  void test7() {5254    if (c) {5255      mu_.AssertHeld();5256    }5257    else {5258      mu_.Lock();5259    }5260    int b = a;5261    a = 0;5262    mu_.Unlock();5263  }5264 5265  void test8() {5266    if (c) {5267      mu_.Lock();5268    }5269    else {5270      mu_.AssertHeld();5271    }5272    // FIXME: should warn, because it's unclear whether we need to release or not.5273    int b = a;5274    a = 0;5275    mu_.Unlock(); // should this be a warning?5276  }5277 5278  void test9() {5279    if (c) {5280      mu_.AssertHeld();5281    }5282    else {5283      mu_.Lock();  // expected-note {{mutex acquired here}}5284    }5285  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}5286 5287  void test10() {5288    if (c) {5289      mu_.Lock();  // expected-note {{mutex acquired here}}5290    }5291    else {5292      mu_.AssertHeld();5293    }5294  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}5295 5296  void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);5297 5298  void test11() {5299    assertMu();5300    int b = a;5301    a = 0;5302  }5303 5304  void test12() {5305    if (c)5306      mu_.ReaderLock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}5307    else5308      mu_.AssertHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}5309    // FIXME: should instead warn because it's unclear whether we need to release or not.5310    int b = a;5311    a = 0;5312    mu_.Unlock();5313  }5314 5315  void test13() {5316    if (c)5317      mu_.Lock(); // expected-warning {{mutex 'mu_' is acquired exclusively and shared in the same scope}}5318    else5319      mu_.AssertReaderHeld(); // expected-note {{the other acquisition of mutex 'mu_' is here}}5320    // FIXME: should instead warn because it's unclear whether we need to release or not.5321    int b = a;5322    a = 0;5323    mu_.Unlock();5324  }5325};5326 5327}  // end namespace AssertHeldTest5328 5329 5330namespace LogicalConditionalTryLock {5331 5332class Foo {5333public:5334  Mutex mu;5335  int a GUARDED_BY(mu);5336  bool c;5337 5338  bool newc();5339 5340  void test1() {5341    if (c && mu.TryLock()) {5342      a = 0;5343      mu.Unlock();5344    }5345  }5346 5347  void test2() {5348    bool b = mu.TryLock();5349    if (c && b) {5350      a = 0;5351      mu.Unlock();5352    }5353  }5354 5355  void test3() {5356    if (c || !mu.TryLock())5357      return;5358    a = 0;5359    mu.Unlock();5360  }5361 5362  void test4() {5363    while (c && mu.TryLock()) {5364      a = 0;5365      c = newc();5366      mu.Unlock();5367    }5368  }5369 5370  void test5() {5371    while (c) {5372      if (newc() || !mu.TryLock())5373        break;5374      a = 0;5375      mu.Unlock();5376    }5377  }5378 5379  void test6() {5380    mu.Lock();5381    do {5382      a = 0;5383      mu.Unlock();5384    } while (newc() && mu.TryLock());5385  }5386 5387  void test7() {5388    for (bool b = mu.TryLock(); c && b;) {5389      a = 0;5390      mu.Unlock();5391    }5392  }5393 5394  void test8() {5395    if (c && newc() && mu.TryLock()) {5396      a = 0;5397      mu.Unlock();5398    }5399  }5400 5401  void test9() {5402    if (!(c && newc() && mu.TryLock()))5403      return;5404    a = 0;5405    mu.Unlock();5406  }5407 5408  void test10() {5409    if (!(c || !mu.TryLock())) {5410      a = 0;5411      mu.Unlock();5412    }5413  }5414};5415 5416}  // end namespace LogicalConditionalTryLock5417 5418 5419 5420namespace PtGuardedByTest {5421 5422void doSomething();5423 5424class Cell {5425  public:5426  int a;5427};5428 5429 5430// This mainly duplicates earlier tests, but just to make sure...5431class PtGuardedByCorrectnessTest {5432  Mutex  mu1;5433  Mutex  mu2;5434  int*   a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);5435  Cell*  c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);5436  int    sa[10] GUARDED_BY(mu1);5437  Cell   sc[10] GUARDED_BY(mu1);5438 5439  static constexpr int Cell::*pa = &Cell::a;5440 5441  void test1() {5442    mu1.Lock();5443    if (a == 0) doSomething();  // OK, we don't dereference.5444    a = 0;5445    c = 0;5446    if (sa[0] == 42) doSomething();5447    sa[0] = 57;5448    if (sc[0].a == 42) doSomething();5449    sc[0].a = 57;5450    mu1.Unlock();5451  }5452 5453  void test2() {5454    mu1.ReaderLock();5455    if (*a == 0) doSomething();      // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}5456    *a = 0;                          // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}5457 5458    if (c->a == 0) doSomething();    // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}5459    c->a = 0;                        // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}5460    c->*pa = 0;                      // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}5461 5462    if ((*c).a == 0) doSomething();  // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}5463    (*c).a = 0;                      // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}5464    (*c).*pa = 0;                    // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}5465 5466    if (a[0] == 42) doSomething();     // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}5467    a[0] = 57;                         // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}5468    if (c[0].a == 42) doSomething();   // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}5469    c[0].a = 57;                       // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}5470    mu1.Unlock();5471  }5472 5473  void test3() {5474    mu2.Lock();5475    if (*a == 0) doSomething();      // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}5476    *a = 0;                          // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}5477 5478    if (c->a == 0) doSomething();    // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5479    c->a = 0;                        // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5480 5481    if ((*c).a == 0) doSomething();  // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5482    (*c).a = 0;                      // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5483 5484    if (a[0] == 42) doSomething();     // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}5485    a[0] = 57;                         // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}5486    if (c[0].a == 42) doSomething();   // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5487    c[0].a = 57;                       // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}5488    mu2.Unlock();5489  }5490 5491  void test4() {  // Literal arrays5492    if (sa[0] == 42) doSomething();     // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}5493    sa[0] = 57;                         // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}5494    if (sc[0].a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}5495    sc[0].a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}5496    sc[0].*pa = 57;                     // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}5497 5498    if (*sa == 42) doSomething();       // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}5499    *sa = 57;                           // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}5500    if ((*sc).a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}5501    (*sc).a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}5502    if (sc->a == 42) doSomething();     // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}5503    sc->a = 57;                         // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}5504  }5505 5506  void test5() {5507    mu1.ReaderLock();    // OK -- correct use.5508    mu2.Lock();5509    if (*a == 0) doSomething();5510    *a = 0;5511 5512    if (c->a == 0) doSomething();5513    c->a = 0;5514 5515    if ((*c).a == 0) doSomething();5516    (*c).a = 0;5517    mu2.Unlock();5518    mu1.Unlock();5519  }5520};5521 5522 5523class SmartPtr_PtGuardedBy_Test {5524  Mutex mu1;5525  Mutex mu2;5526  SmartPtr<int>  sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);5527  SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);5528 5529  static constexpr int Cell::*pa = &Cell::a;5530 5531  void test1() {5532    mu1.ReaderLock();5533    mu2.Lock();5534 5535    sp.get();5536    if (*sp == 0) doSomething();5537    *sp = 0;5538    sq->a = 0;5539    sq->*pa = 0;5540 5541    if (sp[0] == 0) doSomething();5542    sp[0] = 0;5543 5544    mu2.Unlock();5545    mu1.Unlock();5546  }5547 5548  void test2() {5549    mu2.Lock();5550 5551    sp.get();                      // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}5552    if (*sp == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}5553    *sp = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}5554    sq->a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}5555    sq->*pa = 0;                   // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}5556 5557    if (sp[0] == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}5558    sp[0] = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}5559    if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}5560    sq[0].a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}5561 5562    mu2.Unlock();5563  }5564 5565  void test3() {5566    mu1.Lock();5567 5568    sp.get();5569    if (*sp == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}5570    *sp = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}5571    sq->a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}5572    sq->*pa = 0;                   // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}5573 5574    if (sp[0] == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}5575    sp[0] = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}5576    if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}5577    sq[0].a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}5578 5579    mu1.Unlock();5580  }5581};5582 5583}  // end namespace PtGuardedByTest5584 5585 5586namespace NonMemberCalleeICETest {5587 5588class A {5589  void Run() {5590  (RunHelper)();  // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}5591 }5592 5593 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M);5594 Mutex M;5595};5596 5597}  // end namespace NonMemberCalleeICETest5598 5599 5600namespace pt_guard_attribute_type {5601  int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}5602  int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}5603 5604  void test() {5605    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}5606    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}5607 5608    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to}}5609    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to}}5610  }5611}  // end namespace pt_guard_attribute_type5612 5613 5614namespace ThreadAttributesOnLambdas {5615 5616class Foo {5617  Mutex mu_;5618 5619  void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);5620 5621  void test() {5622    auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {5623      LockedFunction();5624    };5625 5626    auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {5627      LockedFunction();5628    };5629 5630    auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {5631      mu_.Lock();5632    };5633 5634    func1();  // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}5635    func1.operator()();  // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}5636    func2();5637    func2.operator()();5638    func3();5639    mu_.Unlock();5640    func3.operator()();5641    mu_.Unlock();5642  }5643};5644 5645}  // end namespace ThreadAttributesOnLambdas5646 5647 5648 5649namespace AttributeExpressionCornerCases {5650 5651class Foo {5652  int a GUARDED_BY(getMu());5653 5654  Mutex* getMu()   LOCK_RETURNED("");5655  Mutex* getUniv() LOCK_RETURNED("*");5656 5657  void test1() {5658    a = 0;5659  }5660 5661  void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {5662    a = 0;5663  }5664 5665  void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);5666 5667  void test3() {5668    foo(nullptr);5669  }5670};5671 5672 5673class MapTest {5674  struct MuCell { Mutex* mu; };5675 5676  MyMap<MyString, Mutex*> map;5677  MyMap<MyString, MuCell> mapCell;5678 5679  int a GUARDED_BY(map["foo"]);5680  int b GUARDED_BY(mapCell["foo"].mu);5681 5682  void test() {5683    map["foo"]->Lock();5684    a = 0;5685    map["foo"]->Unlock();5686  }5687 5688  void test2() {5689    mapCell["foo"].mu->Lock();5690    b = 0;5691    mapCell["foo"].mu->Unlock();5692  }5693};5694 5695 5696class PreciseSmartPtr {5697  SmartPtr<Mutex> mu;5698  int val GUARDED_BY(mu);5699 5700  static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {5701    a.mu->Lock();5702    bool result = (a.val == b.val);   // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \5703                                      // expected-note {{found near match 'a.mu'}}5704    a.mu->Unlock();5705    return result;5706  }5707};5708 5709 5710class SmartRedeclare {5711  SmartPtr<Mutex> mu;5712  int val GUARDED_BY(mu);5713 5714  void test()  EXCLUSIVE_LOCKS_REQUIRED(mu);5715  void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());5716  void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());5717};5718 5719 5720void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {5721  val = 0;5722}5723 5724void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {5725  val = 0;5726}5727 5728void SmartRedeclare::test3() {5729  val = 0;5730}5731 5732 5733namespace CustomMutex {5734 5735 5736class LOCKABLE BaseMutex { };5737class DerivedMutex : public BaseMutex { };5738 5739void customLock(const BaseMutex *m)   EXCLUSIVE_LOCK_FUNCTION(m);5740void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);5741 5742static struct DerivedMutex custMu;5743 5744static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }5745 5746void customTest() {5747  customLock(reinterpret_cast<BaseMutex*>(&custMu));  // ignore casts5748  doSomethingRequiringLock();5749  customUnlock(reinterpret_cast<BaseMutex*>(&custMu));5750}5751 5752} // end namespace CustomMutex5753 5754} // end AttributeExpressionCornerCases5755 5756 5757namespace ScopedLockReturnedInvalid {5758 5759class Opaque;5760 5761Mutex* getMutex(Opaque* o) LOCK_RETURNED("");5762 5763void test(Opaque* o) {5764  MutexLock lock(getMutex(o));5765}5766 5767}  // end namespace ScopedLockReturnedInvalid5768 5769 5770namespace NegativeRequirements {5771 5772class Bar {5773  Mutex mu;5774  int a GUARDED_BY(mu);5775 5776public:5777  void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {5778    mu.Lock();5779    a = 0;5780    mu.Unlock();5781  }5782};5783 5784 5785class Foo {5786  Mutex mu;5787  int a GUARDED_BY(mu);5788 5789public:5790  void foo() {5791    mu.Lock();    // warning?  needs !mu?5792    baz();        // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}5793    bar();5794    mu.Unlock();5795  }5796 5797  void bar() {5798    bar2();       // expected-warning {{calling function 'bar2' requires negative capability '!mu'}}5799  }5800 5801  void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {5802    baz();5803  }5804 5805  void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {5806    mu.Lock();5807    a = 0;5808    mu.Unlock();5809  }5810 5811  void test() {5812    Bar b;5813    b.baz();     // no warning -- in different class.5814  }5815};5816 5817}   // end namespace NegativeRequirements5818 5819 5820namespace NegativeThreadRoles {5821 5822typedef int __attribute__((capability("role"))) ThreadRole;5823 5824void acquire(ThreadRole R) EXCLUSIVE_LOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}5825void release(ThreadRole R) UNLOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}5826 5827ThreadRole FlightControl, Logger;5828 5829extern void enque_log_msg(const char *msg);5830void log_msg(const char *msg) {5831  enque_log_msg(msg);5832}5833 5834void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}5835void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}5836 5837void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {5838  dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while role 'FlightControl' is held}} */5839  dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */5840}5841 5842void spawn_fake_flight_control_thread(void) {5843  acquire(FlightControl);5844  flight_control_entry();5845  release(FlightControl);5846}5847 5848extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));5849void logger_entry(void) __attribute__((requires_capability(Logger)))5850                        __attribute__((requires_capability(!FlightControl))) {5851  const char *msg;5852 5853  while ((msg = deque_log_msg())) {5854    dispatch_log(msg);5855  }5856}5857 5858void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl))) {5859  acquire(Logger);5860  logger_entry();5861  release(Logger);5862}5863 5864int main(void) __attribute__((requires_capability(!FlightControl))) {5865  spawn_fake_flight_control_thread();5866  spawn_fake_logger_thread();5867 5868  for (;;)5869    ; /* Pretend to dispatch things. */5870 5871  return 0;5872}5873 5874} // end namespace NegativeThreadRoles5875 5876 5877namespace AssertSharedExclusive {5878 5879void doSomething();5880 5881class Foo {5882  Mutex mu;5883  int a GUARDED_BY(mu);5884 5885  void test() SHARED_LOCKS_REQUIRED(mu) {5886    mu.AssertHeld();5887    if (a > 0)5888      doSomething();5889  }5890};5891 5892} // end namespace AssertSharedExclusive5893 5894 5895namespace RangeBasedForAndReferences {5896 5897class Foo {5898  struct MyStruct {5899    int a;5900  };5901 5902  Mutex mu;5903  int a GUARDED_BY(mu);5904  MyContainer<int>  cntr  GUARDED_BY(mu);5905  MyStruct s GUARDED_BY(mu);5906  int arr[10] GUARDED_BY(mu);5907 5908  void nonref_test() {5909    int b = a;             // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}5910    b = 0;                 // no warning5911  }5912 5913  void auto_test() {5914    auto b = a;            // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}5915    b = 0;                 // no warning5916    auto &c = a;           // no warning5917    c = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}5918  }5919 5920  void ref_test() {5921    int &b = a;5922    int &c = b;5923    int &d = c;5924    b = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}5925    c = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}5926    d = 0;                 // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}5927 5928    MyStruct &rs = s;5929    rs.a = 0;              // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}5930 5931    int (&rarr)[10] = arr;5932    rarr[2] = 0;           // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}5933  }5934 5935  void ptr_test() {5936    int *b = &a;5937    *b = 0;                // no expected warning yet5938  }5939 5940  void for_test() {5941    int total = 0;5942    for (int i : cntr) {   // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}5943      total += i;5944    }5945  }5946};5947 5948 5949} // end namespace RangeBasedForAndReferences5950 5951 5952 5953namespace PassByRefTest {5954 5955class Foo {5956public:5957  Foo() : a(0), b(0) { }5958 5959  int a;5960  int b;5961 5962  void operator+(const Foo& f);5963 5964  void operator[](const Foo& g);5965 5966  void operator()();5967};5968 5969template<class T>5970T&& mymove(T& f);5971 5972 5973// test top-level functions5974void copy(Foo f);5975void write1(Foo& f);5976void write2(int a, Foo& f);5977void write3(Foo* f);5978void write4(Foo** f);5979void read1(const Foo& f);5980void read2(int a, const Foo& f);5981void read3(const Foo* f);5982void read4(Foo* const* f);5983void destroy(Foo&& f);5984 5985void operator/(const Foo& f, const Foo& g);5986void operator*(const Foo& f, const Foo& g);5987 5988// Test constructors.5989struct FooRead {5990  FooRead(const Foo &);5991};5992struct FooWrite {5993  FooWrite(Foo &);5994};5995 5996// Test variadic functions5997template<typename... T>5998void copyVariadic(T...) {}5999template<typename... T>6000void writeVariadic(T&...) {}6001template<typename... T>6002void readVariadic(const T&...) {}6003 6004void copyVariadicC(int, ...);6005 6006class Bar {6007public:6008  Mutex mu;6009  Foo           foo   GUARDED_BY(mu);6010  Foo           foo2  GUARDED_BY(mu);6011  Foo*          foop  PT_GUARDED_BY(mu);6012  Foo*          foop2 GUARDED_BY(mu);6013  SmartPtr<Foo> foosp PT_GUARDED_BY(mu);6014 6015  // test methods.6016  void mwrite1(Foo& f);6017  void mwrite2(int a, Foo& f);6018  void mwrite3(Foo* f);6019  void mread1(const Foo& f);6020  void mread2(int a, const Foo& f);6021  void mread3(const Foo* f);6022 6023  // static methods6024  static void smwrite1(Foo& f);6025  static void smwrite2(int a, Foo& f);6026  static void smwrite3(Foo* f);6027  static void smread1(const Foo& f);6028  static void smread2(int a, const Foo& f);6029  static void smread3(const Foo* f);6030 6031  void operator<<(const Foo& f);6032 6033  void test1() {6034    copy(foo);             // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6035    write1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6036    write2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6037    read1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6038    read2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6039    destroy(mymove(foo));  // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6040 6041    copyVariadic(foo);     // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6042    readVariadic(foo);     // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6043    writeVariadic(foo);    // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6044    copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6045 6046    FooRead reader(foo);   // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6047    FooWrite writer(foo);  // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6048 6049    mwrite1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6050    mwrite2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6051    mread1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6052    mread2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6053 6054    smwrite1(foo);           // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6055    smwrite2(10, foo);       // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6056    smread1(foo);            // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6057    smread2(10, foo);        // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6058 6059    foo + foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \6060                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}6061    foo / foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \6062                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}6063    foo * foo2;              // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \6064                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}6065    foo[foo2];               // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \6066                             // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}6067    foo();                   // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6068    (*this) << foo;          // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}6069 6070    copy(*foop);             // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}6071    write1(*foop);           // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}6072    write2(10, *foop);       // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}6073    read1(*foop);            // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}6074    read2(10, *foop);        // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}6075    destroy(mymove(*foop));  // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}6076 6077    copy(*foosp);             // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6078    write1(*foosp);           // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6079    write2(10, *foosp);       // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6080    read1(*foosp);            // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6081    read2(10, *foosp);        // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6082    destroy(mymove(*foosp));  // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}6083 6084    // TODO -- these require better smart pointer handling.6085    copy(*foosp.get());6086    write1(*foosp.get());6087    write2(10, *foosp.get());6088    read1(*foosp.get());6089    read2(10, *foosp.get());6090    destroy(mymove(*foosp.get()));6091  }6092 6093  void test_pass_pointer() {6094    (void)&foo;               // no warning6095    (void)foop;               // no warning6096 6097    write3(&foo);             // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6098    write3(foop);             // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6099    write3(&*foop);           // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6100    write4((Foo **)&foo);     // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6101    write4(&foop);            // no warning6102    read3(&foo);              // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6103    read3(foop);              // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6104    read3(&*foop);            // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6105    read4((Foo **)&foo);      // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6106    read4(&foop);             // no warning6107    mwrite3(&foo);            // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6108    mwrite3(foop);            // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6109    mwrite3(&*foop);          // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6110    mread3(&foo);             // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6111    mread3(foop);             // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6112    mread3(&*foop);           // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6113    smwrite3(&foo);           // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6114    smwrite3(foop);           // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6115    smwrite3(&*foop);         // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6116    smread3(&foo);            // expected-warning {{passing pointer to variable 'foo' requires holding mutex 'mu'}}6117    smread3(foop);            // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6118    smread3(&*foop);          // expected-warning {{passing pointer 'foop' requires holding mutex 'mu'}}6119 6120    write3(foop2);            // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6121    write3(&*foop2);          // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6122    write4(&foop2);           // expected-warning {{passing pointer to variable 'foop2' requires holding mutex 'mu'}}6123    read3(foop2);             // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6124    read3(&*foop2);           // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6125    read4(&foop2);            // expected-warning {{passing pointer to variable 'foop2' requires holding mutex 'mu'}}6126    mwrite3(foop2);           // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6127    mwrite3(&*foop2);         // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6128    mread3(foop2);            // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6129    mread3(&*foop2);          // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6130    smwrite3(foop2);          // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6131    smwrite3(&*foop2);        // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6132    smread3(foop2);           // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6133    smread3(&*foop2);         // expected-warning {{reading variable 'foop2' requires holding mutex 'mu'}}6134 6135    mu.Lock();6136    write3(&foo);6137    write3(foop);6138    write3(&*foop);6139    write3(foop2);6140    write4(&foop2);6141    read3(&foo);6142    read3(foop);6143    read3(&*foop);6144    read3(foop2);6145    read4(&foop2);6146    mwrite3(&foo);6147    mwrite3(foop);6148    mwrite3(&*foop);6149    mwrite3(foop2);6150    mread3(&foo);6151    mread3(foop);6152    mread3(&*foop);6153    mread3(foop2);6154    smwrite3(&foo);6155    smwrite3(foop);6156    smwrite3(&*foop);6157    smwrite3(foop2);6158    smread3(&foo);6159    smread3(foop);6160    smread3(&*foop);6161    smread3(foop2);6162    mu.Unlock();6163 6164    mu.ReaderLock();6165    write3(&foo);6166    write3(foop);6167    write3(&*foop);6168    write3(foop2);6169    write4(&foop2);6170    read3(&foo);6171    read3(foop);6172    read3(&*foop);6173    read3(foop2);6174    read4(&foop2);6175    mwrite3(&foo);6176    mwrite3(foop);6177    mwrite3(&*foop);6178    mwrite3(foop2);6179    mread3(&foo);6180    mread3(foop);6181    mread3(&*foop);6182    mread3(foop2);6183    smwrite3(&foo);6184    smwrite3(foop);6185    smwrite3(&*foop);6186    smwrite3(foop2);6187    smread3(&foo);6188    smread3(foop);6189    smread3(&*foop);6190    smread3(foop2);6191    mu.ReaderUnlock();6192  }6193};6194 6195class Return {6196  Mutex mu;6197  Foo foo GUARDED_BY(mu);6198  Foo* foo_ptr PT_GUARDED_BY(mu);6199  Foo foo_depr GUARDED_VAR;          // test deprecated attribute6200  Foo* foo_ptr_depr PT_GUARDED_VAR;  // test deprecated attribute6201 6202  Foo returns_value_locked() {6203    MutexLock lock(&mu);6204    return foo;6205  }6206 6207  Foo returns_value_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {6208    return foo;6209  }6210 6211  Foo returns_value_releases_lock_after_return() UNLOCK_FUNCTION(mu) {6212    MutexLock lock(&mu, true);6213    return foo;6214  }6215 6216  Foo returns_value_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu) {6217    mu.Lock();6218    return foo;6219  }6220  6221  Foo returns_value_not_locked() {6222    return foo;               // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6223  }6224  6225  Foo returns_value_releases_lock_before_return() UNLOCK_FUNCTION(mu) {6226    mu.Unlock();6227    return foo;               // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}6228  }6229 6230  Foo &returns_ref_not_locked() {6231    return foo;               // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}6232  }6233 6234  Foo &returns_ref_locked() {6235    MutexLock lock(&mu);6236    return foo;               // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu'}}6237  }6238 6239  Foo &returns_ref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6240    return foo;               // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}6241  }6242 6243  Foo &returns_ref_exclusive_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {6244    return foo;6245  }6246 6247  Foo &returns_ref_releases_lock_after_return() UNLOCK_FUNCTION(mu) {6248    MutexLock lock(&mu, true);6249    return foo;               // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}6250  }6251 6252  Foo& returns_ref_releases_lock_before_return() UNLOCK_FUNCTION(mu) {6253    mu.Unlock();6254    return foo;               // // expected-warning {{returning variable 'foo' by reference requires holding mutex 'mu' exclusively}}6255  }6256  6257  Foo &returns_ref_aquires_lock() EXCLUSIVE_LOCK_FUNCTION(mu) {6258    mu.Lock();6259    return foo;6260  }6261  6262  const Foo &returns_constref_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6263    return foo;6264  }6265 6266  Foo *returns_ptr_exclusive_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {6267    return &foo;6268  }6269 6270  Foo *returns_pt_ptr_exclusive_locks_required() EXCLUSIVE_LOCKS_REQUIRED(mu) {6271    return foo_ptr;6272  }6273 6274  Foo *returns_ptr_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6275    return &foo;              // expected-warning {{returning pointer to variable 'foo' requires holding mutex 'mu' exclusively}}6276  }6277 6278  Foo *returns_pt_ptr_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6279    return foo_ptr;           // expected-warning {{returning pointer 'foo_ptr' requires holding mutex 'mu' exclusively}}6280  }6281 6282  const Foo *returns_constptr_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6283    return &foo;6284  }6285 6286  const Foo *returns_pt_constptr_shared_locks_required() SHARED_LOCKS_REQUIRED(mu) {6287    return foo_ptr;6288  }6289  6290  Foo *returns_ptr() {6291    return &foo;              // expected-warning {{returning pointer to variable 'foo' requires holding mutex 'mu' exclusively}}6292  }6293 6294  Foo *returns_pt_ptr() {6295    return foo_ptr;           // expected-warning {{returning pointer 'foo_ptr' requires holding mutex 'mu' exclusively}}6296  }6297 6298  Foo &returns_ref2() {6299    return *foo_ptr;          // expected-warning {{returning the value that 'foo_ptr' points to by reference requires holding mutex 'mu' exclusively}}6300  }6301 6302  Foo *returns_ptr_deprecated() {6303    return &foo_depr;          // expected-warning {{writing variable 'foo_depr' requires holding any mutex exclusively}}6304  }6305 6306  Foo *returns_pt_ptr_deprecated() {6307    return foo_ptr_depr;       // expected-warning {{writing the value pointed to by 'foo_ptr_depr' requires holding any mutex exclusively}}6308  }6309 6310  Foo &returns_ref_deprecated() {6311    return *foo_ptr_depr;      // expected-warning {{writing the value pointed to by 'foo_ptr_depr' requires holding any mutex exclusively}}6312  }6313 6314  // FIXME: Basic alias analysis would help catch cases like below.6315  Foo *returns_ptr_alias() {6316    mu.Lock();6317    Foo *ret = &foo;6318    mu.Unlock();6319    return ret; // no warning (false negative)6320  }6321 6322  Foo *returns_pt_ptr_alias() {6323    mu.Lock();6324    Foo *ret = foo_ptr;6325    mu.Unlock();6326    return ret; // no warning (false negative)6327  }6328 6329  Foo &returns_ref2_alias() {6330    mu.Lock();6331    Foo *ret = foo_ptr;6332    mu.Unlock();6333    return *ret; // no warning (false negative)6334  }6335};6336 6337 6338}  // end namespace PassByRefTest6339 6340 6341namespace AcquiredBeforeAfterText {6342 6343class Foo {6344  Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);6345  Mutex mu2;6346  Mutex mu3;6347 6348  void test1() {6349    mu1.Lock();6350    mu2.Lock();6351    mu3.Lock();6352 6353    mu3.Unlock();6354    mu2.Unlock();6355    mu1.Unlock();6356  }6357 6358  void test2() {6359    mu2.Lock();6360    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}6361    mu1.Unlock();6362    mu2.Unlock();6363  }6364 6365  void test3() {6366    mu3.Lock();6367    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}6368    mu1.Unlock();6369    mu3.Unlock();6370  }6371 6372  void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {6373    mu2.Lock();6374    mu2.Unlock();6375  }6376 6377  void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {6378    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}6379    mu1.Unlock();6380  }6381 6382  void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {6383    mu1.AssertHeld();6384  }6385 6386  void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }6387 6388  void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }6389};6390 6391 6392class Foo2 {6393  Mutex mu1;6394  Mutex mu2 ACQUIRED_AFTER(mu1);6395  Mutex mu3 ACQUIRED_AFTER(mu1);6396 6397  void test1() {6398    mu1.Lock();6399    mu2.Lock();6400    mu3.Lock();6401 6402    mu3.Unlock();6403    mu2.Unlock();6404    mu1.Unlock();6405  }6406 6407  void test2() {6408    mu2.Lock();6409    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}6410    mu1.Unlock();6411    mu2.Unlock();6412  }6413 6414  void test3() {6415    mu3.Lock();6416    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}6417    mu1.Unlock();6418    mu3.Unlock();6419  }6420};6421 6422 6423class Foo3 {6424  Mutex mu1 ACQUIRED_BEFORE(mu2);6425  Mutex mu2;6426  Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);6427  Mutex mu4;6428 6429  void test1() {6430    mu1.Lock();6431    mu2.Lock();6432    mu3.Lock();6433    mu4.Lock();6434 6435    mu4.Unlock();6436    mu3.Unlock();6437    mu2.Unlock();6438    mu1.Unlock();6439  }6440 6441  void test2() {6442    mu4.Lock();6443    mu2.Lock();     // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}6444 6445    mu2.Unlock();6446    mu4.Unlock();6447  }6448 6449  void test3() {6450    mu4.Lock();6451    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}6452 6453    mu1.Unlock();6454    mu4.Unlock();6455  }6456 6457  void test4() {6458    mu3.Lock();6459    mu1.Lock();     // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}6460 6461    mu1.Unlock();6462    mu3.Unlock();6463  }6464};6465 6466 6467// Test transitive DAG traversal with AFTER6468class Foo4 {6469  Mutex mu1;6470  Mutex mu2 ACQUIRED_AFTER(mu1);6471  Mutex mu3 ACQUIRED_AFTER(mu1);6472  Mutex mu4 ACQUIRED_AFTER(mu2, mu3);6473  Mutex mu5 ACQUIRED_AFTER(mu4);6474  Mutex mu6 ACQUIRED_AFTER(mu4);6475  Mutex mu7 ACQUIRED_AFTER(mu5, mu6);6476  Mutex mu8 ACQUIRED_AFTER(mu7);6477 6478  void test() {6479    mu8.Lock();6480    mu1.Lock();    // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}6481    mu1.Unlock();6482    mu8.Unlock();6483  }6484};6485 6486 6487// Test transitive DAG traversal with BEFORE6488class Foo5 {6489  Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);6490  Mutex mu2 ACQUIRED_BEFORE(mu4);6491  Mutex mu3 ACQUIRED_BEFORE(mu4);6492  Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);6493  Mutex mu5 ACQUIRED_BEFORE(mu7);6494  Mutex mu6 ACQUIRED_BEFORE(mu7);6495  Mutex mu7 ACQUIRED_BEFORE(mu8);6496  Mutex mu8;6497 6498  void test() {6499    mu8.Lock();6500    mu1.Lock();  // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}6501    mu1.Unlock();6502    mu8.Unlock();6503  }6504};6505 6506 6507class Foo6 {6508  Mutex mu1 ACQUIRED_AFTER(mu3);     // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu1'}}6509  Mutex mu2 ACQUIRED_AFTER(mu1);     // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu2'}}6510  Mutex mu3 ACQUIRED_AFTER(mu2);     // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu3'}}6511 6512  Mutex mu_b ACQUIRED_BEFORE(mu_b);  // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_b'}}6513  Mutex mu_a ACQUIRED_AFTER(mu_a);   // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_a'}}6514 6515  void test0() {6516    mu_a.Lock();6517    mu_b.Lock();6518    mu_b.Unlock();6519    mu_a.Unlock();6520  }6521 6522  void test1a() {6523    mu1.Lock();6524    mu1.Unlock();6525  }6526 6527  void test1b() {6528    mu1.Lock();6529    mu_a.Lock();6530    mu_b.Lock();6531    mu_b.Unlock();6532    mu_a.Unlock();6533    mu1.Unlock();6534  }6535 6536  void test() {6537    mu2.Lock();6538    mu2.Unlock();6539  }6540 6541  void test3() {6542    mu3.Lock();6543    mu3.Unlock();6544  }6545};6546 6547}  // end namespace AcquiredBeforeAfterTest6548 6549 6550namespace ScopedAdoptTest {6551 6552class Foo {6553  Mutex mu;6554  int a GUARDED_BY(mu);6555  int b;6556 6557  void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {6558    MutexLock slock(&mu, true);6559    a = 0;6560  }6561 6562  void test2() SHARED_UNLOCK_FUNCTION(mu) {6563    ReaderMutexLock slock(&mu, true);6564    b = a;6565  }6566 6567  void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) {  // expected-note {{mutex acquired here}}6568    MutexLock slock(&mu, true);6569    a = 0;6570  }  // expected-warning {{expecting mutex 'mu' to be held at the end of function}}6571 6572  void test4() SHARED_LOCKS_REQUIRED(mu) {     // expected-note {{mutex acquired here}}6573    ReaderMutexLock slock(&mu, true);6574    b = a;6575  }  // expected-warning {{expecting mutex 'mu' to be held at the end of function}}6576 6577};6578 6579}  // end namespace ScopedAdoptTest6580 6581 6582namespace TestReferenceNoThreadSafetyAnalysis {6583 6584#define TS_UNCHECKED_READ(x) ts_unchecked_read(x)6585 6586// Takes a reference to a guarded data member, and returns an unguarded6587// reference.6588template <class T>6589inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {6590  return v;6591}6592 6593template <class T>6594inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {6595  return v;6596}6597 6598 6599class Foo {6600public:6601  Foo(): a(0) { }6602 6603  int a;6604};6605 6606 6607class Bar {6608public:6609  Bar() : a(0) { }6610 6611  Mutex mu;6612  int a   GUARDED_BY(mu);6613  Foo foo GUARDED_BY(mu);6614};6615 6616 6617void test() {6618  Bar bar;6619  const Bar cbar;6620 6621  int a = TS_UNCHECKED_READ(bar.a);       // nowarn6622  TS_UNCHECKED_READ(bar.a) = 1;           // nowarn6623 6624  int b = TS_UNCHECKED_READ(bar.foo).a;   // nowarn6625  TS_UNCHECKED_READ(bar.foo).a = 1;       // nowarn6626 6627  int c = TS_UNCHECKED_READ(cbar.a);      // nowarn6628}6629 6630#undef TS_UNCHECKED_READ6631 6632}  // end namespace TestReferenceNoThreadSafetyAnalysis6633 6634 6635namespace GlobalAcquiredBeforeAfterTest {6636 6637Mutex mu1;6638Mutex mu2 ACQUIRED_AFTER(mu1);6639 6640void test3() {6641  mu2.Lock();6642  mu1.Lock();  // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}6643  mu1.Unlock();6644  mu2.Unlock();6645}6646 6647}  // end namespace  GlobalAcquiredBeforeAfterTest6648 6649 6650namespace LifetimeExtensionText {6651 6652struct Holder {6653  virtual ~Holder() throw() {}6654  int i = 0;6655};6656 6657void test() {6658  // Should not crash.6659  const auto &value = Holder().i;6660}6661 6662} // end namespace LifetimeExtensionTest6663 6664 6665namespace LockableUnions {6666 6667union LOCKABLE MutexUnion {6668  int a;6669  char* b;6670 6671  void Lock()   EXCLUSIVE_LOCK_FUNCTION();6672  void Unlock() UNLOCK_FUNCTION();6673};6674 6675MutexUnion muun2;6676MutexUnion muun1 ACQUIRED_BEFORE(muun2);6677 6678void test() {6679  muun2.Lock();6680  muun1.Lock();  // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}6681  muun1.Unlock();6682  muun2.Unlock();6683}6684 6685}  // end namespace LockableUnions6686 6687// This used to crash.6688class acquired_before_empty_str {6689  void WaitUntilSpaceAvailable() {6690    lock_.ReaderLock(); // expected-note {{acquired here}}6691  } // expected-warning {{mutex 'lock_' is still held at the end of function}}6692  Mutex lock_ ACQUIRED_BEFORE("");6693};6694 6695namespace PR34800 {6696struct A {6697  operator int() const;6698};6699struct B {6700  bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}6701  int h;6702};6703struct C {6704  B *operator[](int);6705};6706C c;6707void f() { c[A()]->g(); }6708} // namespace PR348006709 6710#ifdef __cpp_guaranteed_copy_elision6711 6712namespace ReturnScopedLockable {6713 6714class Object {6715public:6716  MutexLock lock() EXCLUSIVE_LOCK_FUNCTION(mutex) {6717    return MutexLock(&mutex);6718  }6719 6720  ReaderMutexLock lockShared() SHARED_LOCK_FUNCTION(mutex) {6721    return ReaderMutexLock(&mutex);6722  }6723 6724  MutexLock adopt() EXCLUSIVE_LOCKS_REQUIRED(mutex) {6725    return MutexLock(&mutex, true);6726  }6727 6728  ReaderMutexLock adoptShared() SHARED_LOCKS_REQUIRED(mutex) {6729    return ReaderMutexLock(&mutex, true);6730  }6731 6732  int x GUARDED_BY(mutex);6733  void needsLock() EXCLUSIVE_LOCKS_REQUIRED(mutex);6734 6735  void testInside() {6736    MutexLock scope = lock();6737    x = 1;6738    needsLock();6739  }6740 6741  Mutex mutex;6742};6743 6744Object obj;6745 6746void testLock() {6747  MutexLock scope = obj.lock();6748  obj.x = 1;6749  obj.needsLock();6750}6751 6752int testSharedLock() {6753  ReaderMutexLock scope = obj.lockShared();6754  obj.x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'obj.mutex' exclusively}}6755  return obj.x;6756}6757 6758void testAdopt() {6759  obj.mutex.Lock();6760  MutexLock scope = obj.adopt();6761  obj.x = 1;6762}6763 6764int testAdoptShared() {6765  obj.mutex.Lock();6766  ReaderMutexLock scope = obj.adoptShared();6767  obj.x = 1;6768  return obj.x;6769}6770 6771} // namespace ReturnScopedLockable6772 6773#endif // __cpp_guaranteed_copy_elision6774 6775namespace PR38640 {6776void f() {6777  // Self-referencing assignment previously caused an infinite loop when thread6778  // safety analysis was enabled.6779  int &i = i; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}}6780}6781} // namespace PR386406782 6783namespace Derived_Smart_Pointer {6784template <class T>6785class SmartPtr_Derived : public SmartPtr<T> {};6786 6787class Foo {6788public:6789  SmartPtr_Derived<Mutex> mu_;6790  int a GUARDED_BY(mu_);6791  int b GUARDED_BY(mu_.get());6792  int c GUARDED_BY(*mu_);6793 6794  void Lock()   EXCLUSIVE_LOCK_FUNCTION(mu_);6795  void Unlock() UNLOCK_FUNCTION(mu_);6796 6797  void test0() {6798    a = 1;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}6799    b = 1;  // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}6800    c = 1;  // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}6801  }6802 6803  void test1() {6804    Lock();6805    a = 1;6806    b = 1;6807    c = 1;6808    Unlock();6809  }6810};6811 6812class Bar {6813  SmartPtr_Derived<Foo> foo;6814 6815  void test0() {6816    foo->a = 1;        // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}6817    (*foo).b = 1;      // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}6818    foo.get()->c = 1;  // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}6819  }6820 6821  void test1() {6822    foo->Lock();6823    foo->a = 1;6824    foo->Unlock();6825 6826    foo->mu_->Lock();6827    foo->b = 1;6828    foo->mu_->Unlock();6829 6830    MutexLock lock(foo->mu_.get());6831    foo->c = 1;6832  }6833};6834 6835class PointerGuard {6836  Mutex mu1;6837  Mutex mu2;6838  SmartPtr_Derived<int> i GUARDED_BY(mu1) PT_GUARDED_BY(mu2);6839 6840  void test0() {6841    i.get();  // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}6842    *i = 2;   // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \6843              // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}6844 6845  }6846 6847  void test1() {6848    mu1.Lock();6849 6850    i.get();6851    *i = 2;   // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}6852 6853    mu1.Unlock();6854  }6855 6856  void test2() {6857    mu2.Lock();6858 6859    i.get();  // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}6860    *i = 2;   // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}6861 6862    mu2.Unlock();6863  }6864 6865  void test3() {6866    mu1.Lock();6867    mu2.Lock();6868 6869    i.get();6870    *i = 2;6871 6872    mu2.Unlock();6873    mu1.Unlock();6874  }6875};6876} // namespace Derived_Smart_Pointer6877 6878// Test for capabilities that are heap-allocated and stored in static variables.6879namespace FunctionStaticVariable {6880struct Data {6881  Mutex mu;6882  int x GUARDED_BY(mu);6883};6884 6885void testStaticVariable() {6886}6887 6888void testHeapAllocation() {6889  static Data *d = new Data;6890  d->mu.Lock();6891  d->x = 5;6892  d->mu.Unlock();6893}6894 6895void testHeapAllocationBug() {6896  static auto *d = new Data;6897  d->x = 10; // expected-warning{{writing variable 'x' requires holding mutex 'd->mu' exclusively}}6898}6899 6900void testHeapAllocationScopedLock() {6901  static Mutex *mu = new Mutex;6902  MutexLock lock(mu);6903}6904} // namespace FunctionStaticVariable6905 6906namespace Reentrancy {6907 6908class LOCKABLE REENTRANT_CAPABILITY ReentrantMutex {6909 public:6910  void Lock() EXCLUSIVE_LOCK_FUNCTION();6911  void ReaderLock() SHARED_LOCK_FUNCTION();6912  void Unlock() UNLOCK_FUNCTION();6913  void ExclusiveUnlock() EXCLUSIVE_UNLOCK_FUNCTION();6914  void ReaderUnlock() SHARED_UNLOCK_FUNCTION();6915  bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);6916  bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);6917 6918  // for negative capabilities6919  const ReentrantMutex& operator!() const { return *this; }6920 6921  void AssertHeld()       ASSERT_EXCLUSIVE_LOCK();6922  void AssertReaderHeld() ASSERT_SHARED_LOCK();6923};6924 6925class SCOPED_LOCKABLE ReentrantMutexLock {6926 public:6927  ReentrantMutexLock(ReentrantMutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);6928  ~ReentrantMutexLock() UNLOCK_FUNCTION();6929};6930 6931class SCOPED_LOCKABLE ReentrantReaderMutexLock {6932 public:6933  ReentrantReaderMutexLock(ReentrantMutex *mu) SHARED_LOCK_FUNCTION(mu);6934  ~ReentrantReaderMutexLock() UNLOCK_FUNCTION();6935};6936 6937class SCOPED_LOCKABLE RelockableReentrantMutexLock {6938public:6939  RelockableReentrantMutexLock(ReentrantMutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);6940  ~RelockableReentrantMutexLock() EXCLUSIVE_UNLOCK_FUNCTION();6941 6942  void Lock() EXCLUSIVE_LOCK_FUNCTION();6943  void Unlock() UNLOCK_FUNCTION();6944};6945 6946ReentrantMutex rmu;6947int guard_var __attribute__((guarded_var)) = 0;6948int guardby_var __attribute__((guarded_by(rmu))) = 0;6949 6950void testReentrantMany() {6951  rmu.Lock();6952  rmu.Lock();6953  rmu.Lock();6954  rmu.Lock();6955  rmu.Lock();6956  rmu.Lock();6957  rmu.Lock();6958  rmu.Lock();6959  rmu.Unlock();6960  rmu.Unlock();6961  rmu.Unlock();6962  rmu.Unlock();6963  rmu.Unlock();6964  rmu.Unlock();6965  rmu.Unlock();6966  rmu.Unlock();6967}6968 6969void testReentrantManyReader() {6970  rmu.ReaderLock();6971  rmu.ReaderLock();6972  rmu.ReaderLock();6973  rmu.ReaderLock();6974  rmu.ReaderLock();6975  rmu.ReaderLock();6976  rmu.ReaderLock();6977  rmu.ReaderLock();6978  rmu.ReaderUnlock();6979  rmu.ReaderUnlock();6980  rmu.ReaderUnlock();6981  rmu.ReaderUnlock();6982  rmu.ReaderUnlock();6983  rmu.ReaderUnlock();6984  rmu.ReaderUnlock();6985  rmu.ReaderUnlock();6986}6987 6988void testReentrantLock1() {6989  rmu.Lock();6990  guard_var = 2;6991  rmu.Lock();6992  guard_var = 2;6993  rmu.Unlock();6994  guard_var = 2;6995  rmu.Unlock();6996  guard_var = 2; // expected-warning{{writing variable 'guard_var' requires holding any mutex exclusively}}6997}6998 6999void testReentrantReaderLock1() {7000  rmu.ReaderLock();7001  int x = guard_var;7002  rmu.ReaderLock();7003  int y = guard_var;7004  rmu.ReaderUnlock();7005  int z = guard_var;7006  rmu.ReaderUnlock();7007  int a = guard_var; // expected-warning{{reading variable 'guard_var' requires holding any mutex}}7008}7009 7010void testReentrantLock2() {7011  rmu.Lock();7012  guardby_var = 2;7013  rmu.Lock();7014  guardby_var = 2;7015  rmu.Unlock();7016  guardby_var = 2;7017  rmu.Unlock();7018  guardby_var = 2; // expected-warning{{writing variable 'guardby_var' requires holding mutex 'rmu' exclusively}}7019}7020 7021void testReentrantReaderLock2() {7022  rmu.ReaderLock();7023  int x = guardby_var;7024  rmu.ReaderLock();7025  int y = guardby_var;7026  rmu.ReaderUnlock();7027  int z = guardby_var;7028  rmu.ReaderUnlock();7029  int a = guardby_var; // expected-warning{{reading variable 'guardby_var' requires holding mutex 'rmu'}}7030}7031 7032void testReentrantTryLock1() {7033  if (rmu.TryLock()) {7034    guardby_var = 1;7035    if (rmu.TryLock()) {7036      guardby_var = 1;7037      rmu.Unlock();7038    }7039    guardby_var = 1;7040    rmu.Unlock();7041  }7042  guardby_var = 1; // expected-warning{{writing variable 'guardby_var' requires holding mutex 'rmu' exclusively}}7043}7044 7045void testReentrantTryLock2() {7046  rmu.Lock();7047  guardby_var = 1;7048  if (rmu.TryLock()) {7049    guardby_var = 1;7050    rmu.Unlock();7051  }7052  guardby_var = 1;7053  rmu.Unlock();7054  guardby_var = 1; // expected-warning{{writing variable 'guardby_var' requires holding mutex 'rmu' exclusively}}7055}7056 7057void testReentrantNotHeld() {7058  rmu.Unlock(); // \7059    // expected-warning{{releasing mutex 'rmu' that was not held}}7060}7061 7062void testReentrantMissingUnlock() {7063  rmu.Lock(); // expected-note{{mutex acquired here}}7064  rmu.Lock(); // reenter7065  rmu.Unlock();7066} // expected-warning{{mutex 'rmu' is still held at the end of function}}7067 7068// Acquiring the same capability with different access privileges is not7069// considered reentrant.7070void testMixedSharedExclusive() {7071  rmu.ReaderLock(); // expected-note{{mutex acquired here}}7072  rmu.Lock(); // expected-warning{{acquiring mutex 'rmu' that is already held}}7073  rmu.Unlock(); // expected-note{{mutex released here}}7074  rmu.ReaderUnlock(); // expected-warning{{releasing mutex 'rmu' that was not held}}7075}7076 7077void testReentrantIntersection() {7078  rmu.Lock();7079  if (guardby_var) {7080    rmu.Lock();7081    rmu.Lock();7082    rmu.Unlock();7083  } else {7084    rmu.Lock();7085    guardby_var = 1;7086  }7087  guardby_var = 1;7088  rmu.Unlock();7089  guardby_var = 1;7090  rmu.Unlock();7091  guardby_var = 1; // expected-warning{{writing variable 'guardby_var' requires holding mutex 'rmu' exclusively}}7092}7093 7094void testReentrantIntersectionBad() {7095  rmu.Lock(); // expected-note{{mutex acquired here}}7096  if (guardby_var) {7097    rmu.Lock();7098    rmu.Lock();7099  } else {7100    rmu.Lock();7101    guardby_var = 1;7102  }7103  guardby_var = 1; // expected-warning{{mutex 'rmu' is not held on every path through here with equal reentrancy depth}}7104  rmu.Unlock();7105  guardby_var = 1;7106  rmu.Unlock();7107  guardby_var = 1;7108  rmu.Unlock();7109}7110 7111void testReentrantLoopBad() {7112  rmu.Lock(); // expected-note{{mutex acquired here}}7113  while (guardby_var) { // expected-warning{{expecting mutex 'rmu' to be held at start of each loop with equal reentrancy depth}}7114    rmu.Lock();7115  }7116  rmu.Unlock();7117}7118 7119void testLocksRequiredReentrant() EXCLUSIVE_LOCKS_REQUIRED(rmu) {7120  guardby_var = 1;7121  rmu.Lock();7122  rmu.Lock();7123  guardby_var = 1;7124  rmu.Unlock();7125  rmu.Unlock();7126  guardby_var = 1;7127}7128 7129void testAssertReentrant() {7130  rmu.AssertHeld();7131  guardby_var = 1;7132  rmu.Lock();7133  guardby_var = 1;7134  rmu.Unlock();7135  guardby_var = 1;7136}7137 7138void testAssertReaderReentrant() {7139  rmu.AssertReaderHeld();7140  int x = guardby_var;7141  rmu.ReaderLock();7142  int y = guardby_var;7143  rmu.ReaderUnlock();7144  int z = guardby_var;7145}7146 7147struct TestScopedReentrantLockable {7148  ReentrantMutex mu1;7149  ReentrantMutex mu2;7150  int a __attribute__((guarded_by(mu1)));7151  int b __attribute__((guarded_by(mu2)));7152 7153  bool getBool();7154 7155  void foo1() {7156    ReentrantMutexLock mulock1(&mu1);7157    a = 5;7158    ReentrantMutexLock mulock2(&mu1);7159    a = 5;7160  }7161 7162  void foo2() {7163    ReentrantMutexLock mulock1(&mu1);7164    a = 5;7165    mu1.Lock();7166    a = 5;7167    mu1.Unlock();7168    a = 5;7169  }7170 7171#ifdef __cpp_guaranteed_copy_elision7172  void const_lock() {7173    const ReentrantMutexLock mulock1 = ReentrantMutexLock(&mu1);7174    a = 5;7175    const ReentrantMutexLock mulock2 = ReentrantMutexLock(&mu1);7176    a = 3;7177  }7178#endif7179 7180  void temporary() {7181    ReentrantMutexLock{&mu1}, a = 1, ReentrantMutexLock{&mu1}, a = 5;7182  }7183 7184  void lifetime_extension() {7185    const ReentrantMutexLock &mulock1 = ReentrantMutexLock(&mu1);7186    a = 5;7187    const ReentrantMutexLock &mulock2 = ReentrantMutexLock(&mu1);7188    a = 5;7189  }7190 7191  void foo3() {7192    ReentrantReaderMutexLock mulock1(&mu1);7193    if (getBool()) {7194      ReentrantMutexLock mulock2a(&mu2);7195      b = a + 1;7196    }7197    else {7198      ReentrantMutexLock mulock2b(&mu2);7199      b = a + 2;7200    }7201  }7202 7203  void foo4() {7204    ReentrantMutexLock mulock_a(&mu1);7205    ReentrantMutexLock mulock_b(&mu1);7206  }7207 7208  void temporary_double_lock() {7209    ReentrantMutexLock mulock_a(&mu1);7210    ReentrantMutexLock{&mu1};7211  }7212 7213  void foo5() {7214    ReentrantMutexLock mulock1(&mu1), mulock2(&mu2);7215    {7216      ReentrantMutexLock mulock3(&mu1), mulock4(&mu2);7217      a = b+1;7218    }7219    b = a+1;7220  }7221};7222 7223void scopedDoubleUnlock() {7224  RelockableReentrantMutexLock scope(&rmu);7225  scope.Unlock(); // expected-note{{mutex released here}}7226  scope.Unlock(); // expected-warning {{releasing mutex 'rmu' that was not held}}7227}7228 7229void scopedDoubleLock1() {7230  RelockableReentrantMutexLock scope(&rmu);7231  scope.Lock();7232  scope.Unlock();7233}7234 7235void scopedDoubleLock2() {7236  RelockableReentrantMutexLock scope(&rmu);7237  scope.Unlock();7238  scope.Lock();7239  scope.Lock();7240  scope.Unlock();7241}7242 7243typedef int __attribute__((capability("bitlock"))) REENTRANT_CAPABILITY *bitlock_t;7244void bit_lock(bitlock_t l) EXCLUSIVE_LOCK_FUNCTION(l);7245void bit_unlock(bitlock_t l) UNLOCK_FUNCTION(l);7246bitlock_t bl;7247void testReentrantTypedef() {7248  bit_lock(bl);7249  bit_lock(bl);7250  bit_unlock(bl);7251  bit_unlock(bl);7252}7253 7254class TestNegativeWithReentrantMutex {7255  ReentrantMutex rmu;7256  int a GUARDED_BY(rmu);7257 7258public:7259  void baz() EXCLUSIVE_LOCKS_REQUIRED(!rmu) {7260    rmu.Lock();7261    rmu.Lock();7262    a = 0;7263    rmu.Unlock();7264    rmu.Unlock();7265  }7266};7267 7268} // namespace Reentrancy7269 7270// Tests for tracking aliases of capabilities.7271namespace CapabilityAliases {7272struct Foo {7273  Mutex mu;7274  int data GUARDED_BY(mu);7275};7276 7277Foo *returnsFoo();7278Foo *returnsFoo(Foo *foo);7279void locksRequired(Foo *foo) EXCLUSIVE_LOCKS_REQUIRED(foo->mu);7280void escapeAlias(int a, Foo *&ptr);7281void escapeAlias(int b, Foo **ptr);7282void passByConstRef(Foo* const& ptr);7283 7284void testBasicPointerAlias(Foo *f) {7285  Foo *ptr = f;7286  ptr->mu.Lock();         // lock through alias7287  f->data = 42;           // access through original7288  ptr->mu.Unlock();       // unlock through alias7289}7290 7291void testBasicPointerAliasNoInit(Foo *f) {7292  Foo *ptr;7293 7294  ptr = nullptr;7295  ptr = f;7296  ptr->mu.Lock();7297  f->data = 42;7298  ptr->mu.Unlock();7299  ptr = nullptr;7300}7301 7302void testBasicPointerAliasLoop() {7303  for (;;) {7304    Foo *f = returnsFoo();7305    Foo *ptr = f;7306    if (!ptr)7307      break;7308    ptr->mu.Lock();7309    f->data = 42;7310    ptr->mu.Unlock();7311  }7312}7313 7314void testPointerAliasNoEscape1(Foo *f) {7315  Foo *ptr = f;7316  testBasicPointerAlias(ptr);  // pass alias by value7317 7318  ptr->mu.Lock();7319  f->data = 42;7320  ptr->mu.Unlock();7321}7322 7323void testPointerAliasNoEscape2(Foo *f) {7324  Foo *ptr = f;7325  passByConstRef(ptr);  // pass alias by const ref7326 7327  ptr->mu.Lock();7328  f->data = 42;7329  ptr->mu.Unlock();7330}7331 7332void testPointerAliasNoEscape3() {7333  Foo *ptr = returnsFoo();7334  ptr->mu.Lock();7335  locksRequired(ptr);7336  ptr->mu.Unlock();7337}7338 7339void testPointerAliasEscape1(Foo *f) {7340  Foo *ptr = f;7341  escapeAlias(0, ptr);7342 7343  ptr->mu.Lock();7344  f->data = 42;           // expected-warning{{writing variable 'data' requires holding mutex 'f->mu' exclusively}} \7345                          // expected-note{{found near match 'ptr->mu'}}7346  ptr->mu.Unlock();7347}7348 7349void testPointerAliasEscape2(Foo *f) {7350  Foo *ptr = f;7351  escapeAlias(0, &ptr);7352 7353  ptr->mu.Lock();7354  f->data = 42;           // expected-warning{{writing variable 'data' requires holding mutex 'f->mu' exclusively}} \7355                          // expected-note{{found near match 'ptr->mu'}}7356  ptr->mu.Unlock();7357}7358 7359void testPointerAliasEscape3(Foo *f) {7360  Foo *ptr;7361 7362  ptr = f;7363  escapeAlias(0, &ptr);7364 7365  ptr->mu.Lock();7366  f->data = 42;           // expected-warning{{writing variable 'data' requires holding mutex 'f->mu' exclusively}} \7367                          // expected-note{{found near match 'ptr->mu'}}7368  ptr->mu.Unlock();7369}7370 7371void testPointerAliasEscapeAndReset(Foo *f) {7372  Foo *ptr;7373 7374  ptr = f;7375  escapeAlias(0, &ptr);7376  ptr = f;7377 7378  ptr->mu.Lock();7379  f->data = 42;7380  ptr->mu.Unlock();7381}7382 7383void testPointerAliasTryLock1() {7384  Foo *ptr = returnsFoo();7385  if (ptr->mu.TryLock()) {7386    locksRequired(ptr);7387    ptr->mu.Unlock();7388  }7389}7390 7391void testPointerAliasTryLock2() {7392  Foo *ptr;7393  ptr = returnsFoo();7394  Foo *ptr2 = ptr;7395  if (ptr->mu.TryLock()) {7396    locksRequired(ptr);7397    ptr2->mu.Unlock();7398  }7399}7400 7401// FIXME: This test demonstrates a dubious pattern that the analysis correctly7402// flags as unsafe, though the user might perceive it as a false positive. The7403// pattern combines a TryLock() failure path with a conditional reassignment of7404// the pointer being locked:7405//7406// 1.  The conditional reassignment `ptr = returnsFoo(ptr);` forces `ptr` to7407//     become a phi node in the CFG at the subsequent merge point. The alias7408//     analysis correctly tracks that `ptr` could refer to one of two distinct7409//     objects.7410//7411// 2.  The lock acquired on the `!TryLock()` path should be (conceptually)7412//     `phi(P1, P2)->mu`, while the lock on the successful path is on the7413//     original `P1->mu`. When the paths merge the analysis currently discards7414//     the alias as it cannot prove a single alias on that path.7415//7416// While this pattern is stylistically fragile and difficult to reason about, a7417// robust solution would require a more advanced symbolic representation of7418// capabilities within the analyzer. For now, we warn on such ambiguity.7419void testPointerAliasTryLockDubious(int x) {7420  Foo *ptr = returnsFoo();7421  if (!ptr->mu.TryLock()) {  // expected-note{{mutex acquired here}}7422    if (x)7423      ptr = returnsFoo(ptr); // <-- this breaks the pattern7424    ptr->mu.Lock();          // expected-note{{mutex acquired here}}7425  }7426  ptr->data = 42;            // expected-warning{{writing variable 'data' requires holding mutex 'ptr->mu' exclusively}} \7427                             // expected-warning{{mutex 'ptr->mu' is not held on every path through here}} \7428                             // expected-warning{{mutex 'returnsFoo().mu' is not held on every path through here}}7429  ptr->mu.Unlock();          // expected-warning{{releasing mutex 'ptr->mu' that was not held}}7430}7431 7432void testReassignment() {7433  Foo f1, f2;7434  Foo *ptr = &f1;7435  ptr->mu.Lock();7436  f1.data = 42;7437  ptr->mu.Unlock();7438 7439  ptr = &f2;7440  ptr->mu.Lock();7441  f2.data = 42;7442  f1.data = 42;           // expected-warning{{writing variable 'data' requires holding mutex 'f1.mu'}} \7443                          // expected-note{{found near match 'f2.mu'}}7444  ptr->mu.Unlock();7445}7446 7447// Nested field access through pointer7448struct Container {7449  Foo foo;7450};7451 7452void testNestedAccess(Container *c) {7453  Foo *ptr = &c->foo; // pointer to nested field7454  ptr->mu.Lock();7455  c->foo.data = 42;7456  ptr->mu.Unlock();7457}7458 7459void testNestedAcquire(Container *c) EXCLUSIVE_LOCK_FUNCTION(&c->foo.mu) {7460  Foo *buf = &c->foo;7461  buf->mu.Lock();7462}7463 7464struct ContainerOfPtr {7465  Foo *foo_ptr;7466  ContainerOfPtr *next;7467};7468 7469void testIndirectAccess(ContainerOfPtr *fc) {7470  Foo *ptr = fc->foo_ptr; // get pointer7471  ptr->mu.Lock();7472  fc->foo_ptr->data = 42; // access via original7473  ptr->mu.Unlock();7474}7475 7476void testAliasChainUnrelatedReassignment1(ContainerOfPtr *list) {7477  Foo *eb = list->foo_ptr;7478  eb->mu.Lock();7479  list = list->next;7480  eb->data = 42;7481  eb->mu.Unlock();7482}7483 7484void testAliasChainUnrelatedReassignment2(ContainerOfPtr *list) {7485  ContainerOfPtr *busyp = list;7486  Foo *eb = busyp->foo_ptr;7487  eb->mu.Lock();7488  busyp = busyp->next;7489  eb->data = 42;7490  eb->mu.Unlock();7491}7492 7493void testControlFlowDoWhile(Foo *f, int x) {7494  Foo *ptr = f;7495 7496  f->mu.Lock();7497  if (x) {7498    // complex merge7499    do { } while (x--);7500  }7501  ptr->data = 42;7502  ptr->mu.Unlock();7503}7504 7505// FIXME: No alias tracking through complex control flow.7506void testComplexControlFlow(Foo *f1, Foo *f2, bool cond) {7507  Foo *ptr;7508  if (cond) {7509    ptr = f1;7510  } else {7511    ptr = f2;7512  }7513  ptr->mu.Lock();7514  if (cond) {7515    f1->data = 42; // expected-warning{{writing variable 'data' requires holding mutex 'f1->mu' exclusively}} \7516                   // expected-note{{found near match 'ptr->mu'}}7517  } else {7518    f2->data = 42; // expected-warning{{writing variable 'data' requires holding mutex 'f2->mu' exclusively}} \7519                   // expected-note{{found near match 'ptr->mu'}}7520  }7521  ptr->mu.Unlock();7522}7523 7524void testLockFunction(Foo *f) EXCLUSIVE_LOCK_FUNCTION(&f->mu) {7525  Mutex *mu = &f->mu;7526  mu->Lock();7527}7528 7529void testUnlockFunction(Foo *f) UNLOCK_FUNCTION(&f->mu) {7530  Mutex *mu = &f->mu;7531  mu->Unlock();7532}7533 7534// This is an idiom to deal with "pointer to returned object has a lock held,7535// but you must unlock it later" where the statement expression would be hidden7536// behind a macro.7537void lockWithinStatementExpr() {7538  Foo *f = ({ auto x = returnsFoo(); x->mu.Lock(); x; });7539  f->data = 42;7540  f->mu.Unlock();7541}7542 7543// Semantically UB, but let's not crash the compiler with this (should be7544// handled by -Wuninitialized).7545void testSelfInit() {7546  Mutex *mu = mu; // don't do this at home7547  mu->Lock();7548  mu->Unlock();7549}7550 7551void testSelfAssign() {7552  Foo *f = returnsFoo();7553  f = f;7554  f->mu.Lock();7555  f->data = 42;7556  f->mu.Unlock();7557}7558 7559void testRecursiveAssign() {7560  Foo *f = returnsFoo();7561  f = returnsFoo(f);7562  f->mu.Lock();7563  f->data = 42;7564  f->mu.Unlock();7565}7566 7567void testNew(Mutex *&out, int &x) {7568  Mutex *mu = new Mutex;7569  __atomic_store_n(&out, mu, __ATOMIC_RELEASE);7570  mu->Lock();7571  x = 42;  // ... perhaps guarded by mu7572  mu->Unlock();7573}7574 7575void testNestedLoopInvariant(Container *c, int n) {7576  Foo *ptr = &c->foo;7577  ptr->mu.Lock();7578 7579  for (int i = 0; i < n; ++i) {7580    for (int j = 0; j < n; ++j) {7581    }7582  }7583 7584  c->foo.data = 42; // ok: alias still valid7585  ptr->mu.Unlock();7586}7587 7588void testLoopWithBreak(Foo *f, bool cond) {7589  Foo *ptr = f;7590  ptr->mu.Lock();7591  for (int i = 0; i < 10; ++i) {7592    if (cond) {7593      break; // merge point is after the loop7594    }7595  }7596  f->data = 42; // ok7597  ptr->mu.Unlock();7598}7599 7600void testLoopWithContinue(Foo *f, bool cond) {7601  Foo *ptr = f;7602  ptr->mu.Lock();7603  for (int i = 0; i < 10; ++i) {7604    if (cond) {7605      continue; // tests merge at the top of loop.7606    }7607  }7608  f->data = 42; // ok7609  ptr->mu.Unlock();7610}7611 7612void testLoopConditionalReassignment(Foo *f1, Foo *f2, bool cond) {7613  Foo *ptr = f1;7614  ptr->mu.Lock(); // expected-note{{mutex acquired here}}7615 7616  for (int i = 0; i < 10; ++i) {7617    if (cond) {7618      ptr = f2; // alias is reassigned on some path inside the loop.7619    }7620  }7621  f1->data = 42;7622  ptr->mu.Unlock(); // expected-warning{{releasing mutex 'ptr->mu' that was not held}}7623} // expected-warning{{mutex 'f1->mu' is still held at the end of function}}7624}  // namespace CapabilityAliases7625