1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s 2 sleep(int x)3void sleep(int x) {} 4 5 namespace std { 6 struct mutex { lockstd::mutex7 void lock() {} unlockstd::mutex8 void unlock() {} 9 }; 10 template<typename T> 11 struct lock_guard { lock_guardstd::lock_guard12 lock_guard<T>(std::mutex) {} 13 ~lock_guard<T>() {} 14 }; 15 template<typename T> 16 struct unique_lock { unique_lockstd::unique_lock17 unique_lock<T>(std::mutex) {} 18 ~unique_lock<T>() {} 19 }; 20 template<typename T> 21 struct not_real_lock { not_real_lockstd::not_real_lock22 not_real_lock<T>(std::mutex) {} 23 }; 24 } 25 getc()26void getc() {} fgets()27void fgets() {} read()28void read() {} recv()29void recv() {} 30 pthread_mutex_lock()31void pthread_mutex_lock() {} pthread_mutex_trylock()32void pthread_mutex_trylock() {} pthread_mutex_unlock()33void pthread_mutex_unlock() {} 34 mtx_lock()35void mtx_lock() {} mtx_timedlock()36void mtx_timedlock() {} mtx_trylock()37void mtx_trylock() {} mtx_unlock()38void mtx_unlock() {} 39 testBlockInCriticalSectionWithStdMutex()40void testBlockInCriticalSectionWithStdMutex() { 41 std::mutex m; 42 m.lock(); 43 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 44 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 45 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 46 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 47 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 48 m.unlock(); 49 } 50 testBlockInCriticalSectionWithPthreadMutex()51void testBlockInCriticalSectionWithPthreadMutex() { 52 pthread_mutex_lock(); 53 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 54 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 55 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 56 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 57 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 58 pthread_mutex_unlock(); 59 60 pthread_mutex_trylock(); 61 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 62 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 63 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 64 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 65 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 66 pthread_mutex_unlock(); 67 } 68 testBlockInCriticalSectionC11Locks()69void testBlockInCriticalSectionC11Locks() { 70 mtx_lock(); 71 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 72 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 73 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 74 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 75 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 76 mtx_unlock(); 77 78 mtx_timedlock(); 79 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 80 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 81 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 82 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 83 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 84 mtx_unlock(); 85 86 mtx_trylock(); 87 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 88 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 89 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 90 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 91 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 92 mtx_unlock(); 93 } 94 testBlockInCriticalSectionWithNestedMutexes()95void testBlockInCriticalSectionWithNestedMutexes() { 96 std::mutex m, n, k; 97 m.lock(); 98 n.lock(); 99 k.lock(); 100 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 101 k.unlock(); 102 sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 103 n.unlock(); 104 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 105 m.unlock(); 106 sleep(3); // no-warning 107 } 108 f()109void f() { 110 sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 111 } 112 testBlockInCriticalSectionInterProcedural()113void testBlockInCriticalSectionInterProcedural() { 114 std::mutex m; 115 m.lock(); 116 f(); 117 m.unlock(); 118 } 119 testBlockInCriticalSectionUnexpectedUnlock()120void testBlockInCriticalSectionUnexpectedUnlock() { 121 std::mutex m; 122 m.unlock(); 123 sleep(1); // no-warning 124 m.lock(); 125 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 126 } 127 testBlockInCriticalSectionLockGuard()128void testBlockInCriticalSectionLockGuard() { 129 std::mutex g_mutex; 130 std::not_real_lock<std::mutex> not_real_lock(g_mutex); 131 sleep(1); // no-warning 132 133 std::lock_guard<std::mutex> lock(g_mutex); 134 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 135 } 136 testBlockInCriticalSectionLockGuardNested()137void testBlockInCriticalSectionLockGuardNested() { 138 testBlockInCriticalSectionLockGuard(); 139 sleep(1); // no-warning 140 } 141 testBlockInCriticalSectionUniqueLock()142void testBlockInCriticalSectionUniqueLock() { 143 std::mutex g_mutex; 144 std::not_real_lock<std::mutex> not_real_lock(g_mutex); 145 sleep(1); // no-warning 146 147 std::unique_lock<std::mutex> lock(g_mutex); 148 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 149 } 150 testBlockInCriticalSectionUniqueLockNested()151void testBlockInCriticalSectionUniqueLockNested() { 152 testBlockInCriticalSectionUniqueLock(); 153 sleep(1); // no-warning 154 } 155