brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · d33917e Raw
320 lines · cpp
1// Test this without pch.2// RUN: %clang_cc1 -include %s -fsyntax-only -verify -Wthread-safety -std=c++11 %s3 4// Test with pch.5// RUN: %clang_cc1 -emit-pch -o %t %s -std=c++116// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify -Wthread-safety -std=c++11 %s7 8#ifndef HEADER9#define HEADER10 11#define LOCKABLE            __attribute__ ((lockable))12#define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))13#define GUARDED_BY(x)       __attribute__ ((guarded_by(x)))14#define GUARDED_VAR         __attribute__ ((guarded_var))15#define PT_GUARDED_BY(x)    __attribute__ ((pt_guarded_by(x)))16#define PT_GUARDED_VAR      __attribute__ ((pt_guarded_var))17#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))18#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))19#define EXCLUSIVE_LOCK_FUNCTION(...)   __attribute__ ((exclusive_lock_function(__VA_ARGS__)))20#define SHARED_LOCK_FUNCTION(...)      __attribute__ ((shared_lock_function(__VA_ARGS__)))21#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))22#define SHARED_TRYLOCK_FUNCTION(...)    __attribute__ ((shared_trylock_function(__VA_ARGS__)))23#define UNLOCK_FUNCTION(...)            __attribute__ ((unlock_function(__VA_ARGS__)))24#define LOCK_RETURNED(x)    __attribute__ ((lock_returned(x)))25#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))26#define EXCLUSIVE_LOCKS_REQUIRED(...) \27  __attribute__ ((exclusive_locks_required(__VA_ARGS__)))28#define SHARED_LOCKS_REQUIRED(...) \29  __attribute__ ((shared_locks_required(__VA_ARGS__)))30#define NO_THREAD_SAFETY_ANALYSIS  __attribute__ ((no_thread_safety_analysis))31 32 33class  __attribute__((lockable)) Mutex {34 public:35  void Lock() __attribute__((exclusive_lock_function));36  void ReaderLock() __attribute__((shared_lock_function));37  void Unlock() __attribute__((unlock_function));38  bool TryLock() __attribute__((exclusive_trylock_function(true)));39  bool ReaderTryLock() __attribute__((shared_trylock_function(true)));40  void LockWhen(const int &cond) __attribute__((exclusive_lock_function));41};42 43class __attribute__((scoped_lockable)) MutexLock {44 public:45  MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));46  ~MutexLock() __attribute__((unlock_function));47};48 49class __attribute__((scoped_lockable)) ReaderMutexLock {50 public:51  ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));52  ~ReaderMutexLock() __attribute__((unlock_function));53};54 55class SCOPED_LOCKABLE ReleasableMutexLock {56 public:57  ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);58  ~ReleasableMutexLock() UNLOCK_FUNCTION();59 60  void Release() UNLOCK_FUNCTION();61};62 63 64// The universal lock, written "*", allows checking to be selectively turned65// off for a particular piece of code.66void beginNoWarnOnReads()  SHARED_LOCK_FUNCTION("*");67void endNoWarnOnReads()    UNLOCK_FUNCTION("*");68void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");69void endNoWarnOnWrites()   UNLOCK_FUNCTION("*");70 71 72// For testing handling of smart pointers.73template<class T>74class SmartPtr {75public:76  SmartPtr(T* p) : ptr_(p) { }77  SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }78  ~SmartPtr();79 80  T* get()        const { return ptr_; }81  T* operator->() const { return ptr_; }82  T& operator*()  const { return *ptr_; }83 84private:85  T* ptr_;86};87 88 89// For testing destructor calls and cleanup.90class MyString {91public:92  MyString(const char* s);93  ~MyString();94};95 96 97 98Mutex sls_mu;99 100Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));101int sls_guard_var __attribute__((guarded_var)) = 0;102int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;103 104bool getBool();105 106class MutexWrapper {107public:108   Mutex mu;109   int x __attribute__((guarded_by(mu)));110   void MyLock() __attribute__((exclusive_lock_function(mu)));111};112 113#else114 115MutexWrapper sls_mw;116 117void sls_fun_0() {118  sls_mw.mu.Lock();119  sls_mw.x = 5;120  sls_mw.mu.Unlock();121}122 123void sls_fun_2() {124  sls_mu.Lock();125  int x = sls_guard_var;126  sls_mu.Unlock();127}128 129void sls_fun_3() {130  sls_mu.Lock();131  sls_guard_var = 2;132  sls_mu.Unlock();133}134 135void sls_fun_4() {136  sls_mu2.Lock();137  sls_guard_var = 2;138  sls_mu2.Unlock();139}140 141void sls_fun_5() {142  sls_mu.Lock();143  int x = sls_guardby_var;144  sls_mu.Unlock();145}146 147void sls_fun_6() {148  sls_mu.Lock();149  sls_guardby_var = 2;150  sls_mu.Unlock();151}152 153void sls_fun_7() {154  sls_mu.Lock();155  sls_mu2.Lock();156  sls_mu2.Unlock();157  sls_mu.Unlock();158}159 160void sls_fun_8() {161  sls_mu.Lock();162  if (getBool())163    sls_mu.Unlock();164  else165    sls_mu.Unlock();166}167 168void sls_fun_9() {169  if (getBool())170    sls_mu.Lock();171  else172    sls_mu.Lock();173  sls_mu.Unlock();174}175 176void sls_fun_good_6() {177  if (getBool()) {178    sls_mu.Lock();179  } else {180    if (getBool()) {181      getBool(); // EMPTY182    } else {183      getBool(); // EMPTY184    }185    sls_mu.Lock();186  }187  sls_mu.Unlock();188}189 190void sls_fun_good_7() {191  sls_mu.Lock();192  while (getBool()) {193    sls_mu.Unlock();194    if (getBool()) {195      if (getBool()) {196        sls_mu.Lock();197        continue;198      }199    }200    sls_mu.Lock();201  }202  sls_mu.Unlock();203}204 205void sls_fun_good_8() {206  sls_mw.MyLock();207  sls_mw.mu.Unlock();208}209 210void sls_fun_bad_1() {211  sls_mu.Unlock(); // \212    // expected-warning{{releasing mutex 'sls_mu' that was not held}}213}214 215void sls_fun_bad_2() {216  sls_mu.Lock(); // expected-note{{mutex acquired here}}217  sls_mu.Lock(); // \218    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}219  sls_mu.Unlock();220}221 222void sls_fun_bad_3() {223  sls_mu.Lock(); // expected-note {{mutex acquired here}}224} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}225 226void sls_fun_bad_4() {227  if (getBool())228    sls_mu.Lock();  // expected-note{{mutex acquired here}}229  else230    sls_mu2.Lock(); // expected-note{{mutex acquired here}}231} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \232  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}233 234void sls_fun_bad_5() {235  sls_mu.Lock(); // expected-note {{mutex acquired here}}236  if (getBool())237    sls_mu.Unlock();238} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}239 240void sls_fun_bad_6() {241  if (getBool()) {242    sls_mu.Lock(); // expected-note {{mutex acquired here}}243  } else {244    if (getBool()) {245      getBool(); // EMPTY246    } else {247      getBool(); // EMPTY248    }249  }250  sls_mu.Unlock(); // \251    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\252    expected-warning{{releasing mutex 'sls_mu' that was not held}}253}254 255void sls_fun_bad_7() {256  sls_mu.Lock();257  while (getBool()) { // \258        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}259    sls_mu.Unlock();260    if (getBool()) {261      if (getBool()) {262        continue;263      }264    }265    sls_mu.Lock(); // expected-note {{mutex acquired here}}266  }267  sls_mu.Unlock();268}269 270void sls_fun_bad_8() {271  sls_mu.Lock(); // expected-note{{mutex acquired here}}272 273  do {274    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}275  } while (getBool());276}277 278void sls_fun_bad_9() {279  do {280    sls_mu.Lock();  // \281      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \282      // expected-note{{mutex acquired here}}283  } while (getBool());284  sls_mu.Unlock();285}286 287void sls_fun_bad_10() {288  sls_mu.Lock();  // expected-note 2{{mutex acquired here}}289  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}290    sls_mu.Unlock();291  }292} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}293 294void sls_fun_bad_11() {295  while (getBool()) { // \296      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}297    sls_mu.Lock(); // expected-note {{mutex acquired here}}298  }299  sls_mu.Unlock(); // \300    // expected-warning{{releasing mutex 'sls_mu' that was not held}}301}302 303void sls_fun_bad_12() {304  sls_mu.Lock(); // expected-note {{mutex acquired here}}305  while (getBool()) {306    sls_mu.Unlock();307    if (getBool()) {308      if (getBool()) {309        break;310      }311    }312    sls_mu.Lock();313  }314  sls_mu.Unlock(); // \315    expected-warning{{mutex 'sls_mu' is not held on every path through here}} \316    expected-warning{{releasing mutex 'sls_mu' that was not held}}317}318 319#endif320