1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s 2 3 void sleep(int x) {} 4 5 namespace std { 6 struct mutex { 7 void lock() {} 8 void unlock() {} 9 }; 10 } 11 12 void getc() {} 13 void fgets() {} 14 void read() {} 15 void recv() {} 16 17 void pthread_mutex_lock() {} 18 void pthread_mutex_trylock() {} 19 void pthread_mutex_unlock() {} 20 21 void mtx_lock() {} 22 void mtx_timedlock() {} 23 void mtx_trylock() {} 24 void mtx_unlock() {} 25 26 void testBlockInCriticalSectionWithStdMutex() { 27 std::mutex m; 28 m.lock(); 29 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 30 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 31 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 32 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 33 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 34 m.unlock(); 35 } 36 37 void testBlockInCriticalSectionWithPthreadMutex() { 38 pthread_mutex_lock(); 39 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 40 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 41 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 42 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 43 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 44 pthread_mutex_unlock(); 45 46 pthread_mutex_trylock(); 47 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 48 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 49 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 50 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 51 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 52 pthread_mutex_unlock(); 53 } 54 55 void testBlockInCriticalSectionC11Locks() { 56 mtx_lock(); 57 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 58 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 59 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 60 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 61 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 62 mtx_unlock(); 63 64 mtx_timedlock(); 65 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 66 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 67 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 68 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 69 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 70 mtx_unlock(); 71 72 mtx_trylock(); 73 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 74 getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}} 75 fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}} 76 read(); // expected-warning {{Call to blocking function 'read' inside of critical section}} 77 recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}} 78 mtx_unlock(); 79 } 80 81 void testBlockInCriticalSectionWithNestedMutexes() { 82 std::mutex m, n, k; 83 m.lock(); 84 n.lock(); 85 k.lock(); 86 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 87 k.unlock(); 88 sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 89 n.unlock(); 90 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 91 m.unlock(); 92 sleep(3); // no-warning 93 } 94 95 void f() { 96 sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 97 } 98 99 void testBlockInCriticalSectionInterProcedural() { 100 std::mutex m; 101 m.lock(); 102 f(); 103 m.unlock(); 104 } 105 106 void testBlockInCriticalSectionUnexpectedUnlock() { 107 std::mutex m; 108 m.unlock(); 109 sleep(1); // no-warning 110 m.lock(); 111 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} 112 } 113