blob: fcf6188fc033ec8f4f6f7990916003427b26a63b [file] [log] [blame]
Dominic Chen184c6242017-03-03 18:02:02 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s
Anna Zaksc154f7b2016-09-20 20:28:50 +00002
3void sleep(int x) {}
4
5namespace std {
6struct mutex {
7 void lock() {}
8 void unlock() {}
9};
Gabor Horvath9a8c8bf2017-10-30 10:09:55 +000010template<typename T>
11struct lock_guard {
12 lock_guard<T>(std::mutex) {}
13 ~lock_guard<T>() {}
14};
15template<typename T>
16struct unique_lock {
17 unique_lock<T>(std::mutex) {}
18 ~unique_lock<T>() {}
19};
20template<typename T>
21struct not_real_lock {
22 not_real_lock<T>(std::mutex) {}
23};
Anna Zaksc154f7b2016-09-20 20:28:50 +000024}
25
Gabor Horvath829c6bc2017-03-10 14:50:12 +000026void getc() {}
27void fgets() {}
28void read() {}
29void recv() {}
30
31void pthread_mutex_lock() {}
32void pthread_mutex_trylock() {}
33void pthread_mutex_unlock() {}
34
35void mtx_lock() {}
36void mtx_timedlock() {}
37void mtx_trylock() {}
38void mtx_unlock() {}
39
40void testBlockInCriticalSectionWithStdMutex() {
Anna Zaksc154f7b2016-09-20 20:28:50 +000041 std::mutex m;
42 m.lock();
Gabor Horvath829c6bc2017-03-10 14:50:12 +000043 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}}
Anna Zaksc154f7b2016-09-20 20:28:50 +000048 m.unlock();
49}
50
Gabor Horvath829c6bc2017-03-10 14:50:12 +000051void 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
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
Anna Zaksc154f7b2016-09-20 20:28:50 +000095void testBlockInCriticalSectionWithNestedMutexes() {
96 std::mutex m, n, k;
97 m.lock();
98 n.lock();
99 k.lock();
Gabor Horvath829c6bc2017-03-10 14:50:12 +0000100 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
Anna Zaksc154f7b2016-09-20 20:28:50 +0000101 k.unlock();
Gabor Horvath829c6bc2017-03-10 14:50:12 +0000102 sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
Anna Zaksc154f7b2016-09-20 20:28:50 +0000103 n.unlock();
Gabor Horvath829c6bc2017-03-10 14:50:12 +0000104 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
Anna Zaksc154f7b2016-09-20 20:28:50 +0000105 m.unlock();
106 sleep(3); // no-warning
107}
108
109void f() {
Gabor Horvath829c6bc2017-03-10 14:50:12 +0000110 sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
Anna Zaksc154f7b2016-09-20 20:28:50 +0000111}
112
113void testBlockInCriticalSectionInterProcedural() {
114 std::mutex m;
115 m.lock();
116 f();
117 m.unlock();
118}
119
120void testBlockInCriticalSectionUnexpectedUnlock() {
121 std::mutex m;
122 m.unlock();
123 sleep(1); // no-warning
124 m.lock();
Gabor Horvath829c6bc2017-03-10 14:50:12 +0000125 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
Anna Zaksc154f7b2016-09-20 20:28:50 +0000126}
Gabor Horvath9a8c8bf2017-10-30 10:09:55 +0000127
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
137void testBlockInCriticalSectionLockGuardNested() {
138 testBlockInCriticalSectionLockGuard();
139 sleep(1); // no-warning
140}
141
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
151void testBlockInCriticalSectionUniqueLockNested() {
152 testBlockInCriticalSectionUniqueLock();
153 sleep(1); // no-warning
154}