brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.0 KiB · 674a092 Raw
321 lines · cpp
1// RUN: %clang_analyze_cc1 \2// RUN:   -analyzer-checker=unix.BlockInCriticalSection \3// RUN:   -std=c++11 \4// RUN:   -analyzer-output text \5// RUN:   -verify %s6 7void sleep(int x) {}8 9namespace std {10struct mutex {11  void lock() {}12  void unlock() {}13};14template<typename T>15struct lock_guard {16  lock_guard<T>(std::mutex) {}17  ~lock_guard<T>() {}18};19struct defer_lock_t {};20constexpr defer_lock_t defer_lock{};21template<typename T>22struct unique_lock {23  unique_lock<T>(std::mutex) {}24  unique_lock<T>(std::mutex, defer_lock_t) {} // defer_lock parameter25  ~unique_lock<T>() {}26};27template<typename T>28struct not_real_lock {29  not_real_lock<T>(std::mutex) {}30};31} // namespace std32 33struct FILE;34int getc(FILE *stream);35char* fgets(char *str, FILE *stream);36using ssize_t = long long;37using size_t = unsigned long long;38ssize_t read(int fd, void *buf, size_t count);39ssize_t recv(int sockfd, void *buf, size_t len, int flags);40 41struct pthread_mutex_t;42int pthread_mutex_lock(pthread_mutex_t *mutex);43int pthread_mutex_trylock(pthread_mutex_t *mutex);44int pthread_mutex_unlock(pthread_mutex_t *mutex);45 46struct mtx_t;47int mtx_lock(mtx_t *mutex);48int mtx_timedlock(mtx_t *mutex);49int mtx_trylock(mtx_t *mutex);50int mtx_unlock(mtx_t *mutex);51 52// global params for dummy function calls53FILE *stream;54char *str;55int fd;56void *buf;57size_t count;58int sockfd;59size_t len;60int flags;61 62void testBlockInCriticalSectionWithStdMutex() {63  std::mutex m;64  m.lock(); // expected-note 5{{Entering critical section here}}65  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}66            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}67  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}68          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}69  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}70           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}71  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}72          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}73  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}74          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}75  m.unlock();76}77 78void testBlockInCriticalSectionWithPthreadMutex(pthread_mutex_t *mutex) {79  pthread_mutex_lock(mutex); // expected-note 5{{Entering critical section here}}80  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}81            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}82  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}83          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}84  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}85           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}86  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}87          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}88  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}89          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}90  pthread_mutex_unlock(mutex);91 92  pthread_mutex_trylock(mutex); // expected-note 5{{Entering critical section here}}93  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}94            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}95  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}96          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}97  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}98           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}99  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}100          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}101  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}102          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}103  pthread_mutex_unlock(mutex);104}105 106void testBlockInCriticalSectionC11Locks(mtx_t *mutex) {107  mtx_lock(mutex); // expected-note 5{{Entering critical section here}}108  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}109            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}110  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}111          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}112  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}113           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}114  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}115          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}116  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}117          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}118  mtx_unlock(mutex);119 120  mtx_timedlock(mutex); // expected-note 5{{Entering critical section here}}121  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}122            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}123  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}124          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}125  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}126           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}127  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}128          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}129  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}130          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}131  mtx_unlock(mutex);132 133  mtx_trylock(mutex); // expected-note 5{{Entering critical section here}}134  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}135            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}136  getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}137          // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}138  fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}139           // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}140  read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}141          // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}142  recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}143          // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}144  mtx_unlock(mutex);145}146 147void testMultipleBlockingCalls() {148  std::mutex m;149  m.lock(); // expected-note 1{{Entering critical section here}}150  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}151            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}152  m.unlock();153  sleep(2); // no-warning154}155 156void testMultipleMutexesMultipleBlockingCalls() {157  std::mutex m, n, k;158  m.lock(); // expected-note 2{{Entering critical section here}}159  n.lock(); // expected-note 2{{Entering critical section here}}160  k.lock(); // expected-note 1{{Entering critical section here}}161  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}162            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}163  k.unlock();164  sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}165            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}166}167 168 169void testRecursiveAcquisition() {170  std::mutex m;171  m.lock(); // expected-note {{Entering critical section for the 1st time here}}172  m.lock(); // expected-note {{Entering critical section for the 2nd time here}}173  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}174            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}175  m.unlock();176  m.unlock();177}178 179void testRecursiveAcquisitionWithMultipleBlockingCalls() {180  std::mutex m;181  m.lock(); // expected-note 1{{Entering critical section for the 1st time here}}182            // expected-note@-1 {{Entering critical section here}}183  m.lock(); // expected-note 1{{Entering critical section for the 2nd time here}}184  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}185            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}186  m.unlock();187  // this next 'sleep' call is only in the critical section of the first lock188  sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}189            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}190  m.unlock();191}192 193void testRecursiveAcquisitionWithMultipleMutexes() {194  std::mutex m, n;195  m.lock(); // expected-note 1{{Entering critical section here}}196  n.lock(); // expected-note 2{{Entering critical section here}}197  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}198            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}199  m.unlock();200  // this next 'sleep' call is only in the critical section of mutex 'n'201  sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}202            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}203  n.unlock();204}205 206 207void testNestedMutexes() {208  std::mutex m, n, k;209  m.lock(); // expected-note 3{{Entering critical section here}}210  n.lock(); // expected-note 2{{Entering critical section here}}211  k.lock(); // expected-note 1{{Entering critical section here}}212  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}213            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}214  k.unlock();215  sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}216            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}217  n.unlock();218  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}219            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}220  m.unlock();221  sleep(4); // no-warning222}223 224void testNonOverlappingMutexes() {225  std::mutex m;226  m.lock(); // There should be no warning here227  m.unlock();228  m.lock(); // expected-note {{Entering critical section here}}229  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}230            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}231  m.unlock();232}233 234void testMixedMutexLocksWithIntermittentUnlock() {235  std::mutex m, n, k;236  m.lock(); // expected-note {{Entering critical section here}}237  n.lock(); // the problem is not is this lock's critical section238  n.unlock();239  k.lock(); // same as for n.lock()240  k.unlock();241  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}242            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}243  m.unlock();244}245 246void f() {247  sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}248               // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}249}250 251void testBlockInCriticalSectionInterProcedural() {252  std::mutex m;253  m.lock(); // expected-note {{Entering critical section here}}254  f(); // expected-note {{Calling 'f'}}255  m.unlock();256}257 258void unknown_function_that_may_lock(std::mutex &);259void testBlockInCriticalSectionUnexpectedUnlock() {260  std::mutex m;261  unknown_function_that_may_lock(m);262  m.unlock();263  sleep(1); // no-warning264  m.lock(); // expected-note {{Entering critical section here}}265  sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}266            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}267}268 269void testBlockInCriticalSectionLockGuard() {270  std::mutex g_mutex;271  std::not_real_lock<std::mutex> not_real_lock(g_mutex);272  sleep(1); // no-warning273 274  std::lock_guard<std::mutex> lock(g_mutex); // expected-note {{Entering critical section here}}275  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}276            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}277}278 279void testBlockInCriticalSectionLockGuardNested() {280  testBlockInCriticalSectionLockGuard(); // expected-note {{Calling 'testBlockInCriticalSectionLockGuard'}}281  sleep(1); // no-warning282}283 284void testBlockInCriticalSectionUniqueLock() {285  std::mutex g_mutex;286  std::not_real_lock<std::mutex> not_real_lock(g_mutex);287  sleep(1); // no-warning288 289  std::unique_lock<std::mutex> lock(g_mutex); // expected-note {{Entering critical section here}}290  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}291            // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}292}293 294void testBlockInCriticalSectionUniqueLockNested() {295  testBlockInCriticalSectionUniqueLock(); // expected-note {{Calling 'testBlockInCriticalSectionUniqueLock'}}296  sleep(1); // no-warning297}298 299void testTrylockCurrentlyFalsePositive(pthread_mutex_t *m) {300                                       // expected-note@+4 {{Assuming the condition is true}}301                                       // expected-note@+3 {{Taking true branch}}302                                       // expected-note@+2 {{Assuming the condition is false}}303                                       // expected-note@+1 {{Taking false branch}}304  if (pthread_mutex_trylock(m) == 0) { // expected-note 2 {{Entering critical section here}}305                                       // FIXME: we are entering the critical section only in the true branch306    sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}307               // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}308    pthread_mutex_unlock(m);309  } else {310    sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}311               // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}312               // FIXME: this is a false positive, the lock was not acquired313  }314}315 316void testBlockInCriticalSectionUniqueLockWithDeferLock() {317  std::mutex g_mutex;318  std::unique_lock<std::mutex> lock(g_mutex, std::defer_lock);319  sleep(1); // no-warning320}321