[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / clang / test / Analysis / block-in-critical-section.cpp
blobee9a708f231a868b3ecc20f94066f5e036c525ee
1 // RUN: %clang_analyze_cc1 \
2 // RUN: -analyzer-checker=unix.BlockInCriticalSection \
3 // RUN: -std=c++11 \
4 // RUN: -analyzer-output text \
5 // RUN: -verify %s
7 void sleep(int x) {}
9 namespace std {
10 struct mutex {
11 void lock() {}
12 void unlock() {}
14 template<typename T>
15 struct lock_guard {
16 lock_guard<T>(std::mutex) {}
17 ~lock_guard<T>() {}
19 template<typename T>
20 struct unique_lock {
21 unique_lock<T>(std::mutex) {}
22 ~unique_lock<T>() {}
24 template<typename T>
25 struct not_real_lock {
26 not_real_lock<T>(std::mutex) {}
28 } // namespace std
30 struct FILE;
31 int getc(FILE *stream);
32 char* fgets(char *str, FILE *stream);
33 using ssize_t = long long;
34 using size_t = unsigned long long;
35 ssize_t read(int fd, void *buf, size_t count);
36 ssize_t recv(int sockfd, void *buf, size_t len, int flags);
38 struct pthread_mutex_t;
39 int pthread_mutex_lock(pthread_mutex_t *mutex);
40 int pthread_mutex_trylock(pthread_mutex_t *mutex);
41 int pthread_mutex_unlock(pthread_mutex_t *mutex);
43 struct mtx_t;
44 int mtx_lock(mtx_t *mutex);
45 int mtx_timedlock(mtx_t *mutex);
46 int mtx_trylock(mtx_t *mutex);
47 int mtx_unlock(mtx_t *mutex);
49 // global params for dummy function calls
50 FILE *stream;
51 char *str;
52 int fd;
53 void *buf;
54 size_t count;
55 int sockfd;
56 size_t len;
57 int flags;
59 void testBlockInCriticalSectionWithStdMutex() {
60 std::mutex m;
61 m.lock(); // expected-note 5{{Entering critical section here}}
62 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
63 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
64 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
65 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
66 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
67 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
68 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
69 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
70 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
71 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
72 m.unlock();
75 void testBlockInCriticalSectionWithPthreadMutex(pthread_mutex_t *mutex) {
76 pthread_mutex_lock(mutex); // expected-note 5{{Entering critical section here}}
77 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
78 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
79 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
80 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
81 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
82 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
83 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
84 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
85 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
86 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
87 pthread_mutex_unlock(mutex);
89 pthread_mutex_trylock(mutex); // expected-note 5{{Entering critical section here}}
90 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
91 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
92 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
93 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
94 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
95 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
96 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
97 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
98 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
99 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
100 pthread_mutex_unlock(mutex);
103 void testBlockInCriticalSectionC11Locks(mtx_t *mutex) {
104 mtx_lock(mutex); // expected-note 5{{Entering critical section here}}
105 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
106 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
107 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
108 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
109 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
110 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
111 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
112 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
113 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
114 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
115 mtx_unlock(mutex);
117 mtx_timedlock(mutex); // expected-note 5{{Entering critical section here}}
118 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
119 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
120 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
121 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
122 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
123 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
124 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
125 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
126 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
127 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
128 mtx_unlock(mutex);
130 mtx_trylock(mutex); // expected-note 5{{Entering critical section here}}
131 sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
132 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
133 getc(stream); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
134 // expected-note@-1 {{Call to blocking function 'getc' inside of critical section}}
135 fgets(str, stream); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
136 // expected-note@-1 {{Call to blocking function 'fgets' inside of critical section}}
137 read(fd, buf, count); // expected-warning {{Call to blocking function 'read' inside of critical section}}
138 // expected-note@-1 {{Call to blocking function 'read' inside of critical section}}
139 recv(sockfd, buf, count, flags); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
140 // expected-note@-1 {{Call to blocking function 'recv' inside of critical section}}
141 mtx_unlock(mutex);
144 void testMultipleBlockingCalls() {
145 std::mutex m;
146 m.lock(); // expected-note 1{{Entering critical section here}}
147 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
148 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
149 m.unlock();
150 sleep(2); // no-warning
153 void testMultipleMutexesMultipleBlockingCalls() {
154 std::mutex m, n, k;
155 m.lock(); // expected-note 2{{Entering critical section here}}
156 n.lock(); // expected-note 2{{Entering critical section here}}
157 k.lock(); // expected-note 1{{Entering critical section here}}
158 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
159 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
160 k.unlock();
161 sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
162 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
166 void testRecursiveAcquisition() {
167 std::mutex m;
168 m.lock(); // expected-note {{Entering critical section for the 1st time here}}
169 m.lock(); // expected-note {{Entering critical section for the 2nd time here}}
170 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
171 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
172 m.unlock();
173 m.unlock();
176 void testRecursiveAcquisitionWithMultipleBlockingCalls() {
177 std::mutex m;
178 m.lock(); // expected-note 1{{Entering critical section for the 1st time here}}
179 // expected-note@-1 {{Entering critical section here}}
180 m.lock(); // expected-note 1{{Entering critical section for the 2nd time here}}
181 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
182 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
183 m.unlock();
184 // this next 'sleep' call is only in the critical section of the first lock
185 sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
186 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
187 m.unlock();
190 void testRecursiveAcquisitionWithMultipleMutexes() {
191 std::mutex m, n;
192 m.lock(); // expected-note 1{{Entering critical section here}}
193 n.lock(); // expected-note 2{{Entering critical section here}}
194 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
195 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
196 m.unlock();
197 // this next 'sleep' call is only in the critical section of mutex 'n'
198 sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
199 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
200 n.unlock();
204 void testNestedMutexes() {
205 std::mutex m, n, k;
206 m.lock(); // expected-note 3{{Entering critical section here}}
207 n.lock(); // expected-note 2{{Entering critical section here}}
208 k.lock(); // expected-note 1{{Entering critical section here}}
209 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
210 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
211 k.unlock();
212 sleep(2); // 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 n.unlock();
215 sleep(3); // 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 m.unlock();
218 sleep(4); // no-warning
221 void testNonOverlappingMutexes() {
222 std::mutex m;
223 m.lock(); // There should be no warning here
224 m.unlock();
225 m.lock(); // expected-note {{Entering critical section here}}
226 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
227 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
228 m.unlock();
231 void testMixedMutexLocksWithIntermittentUnlock() {
232 std::mutex m, n, k;
233 m.lock(); // expected-note {{Entering critical section here}}
234 n.lock(); // the problem is not is this lock's critical section
235 n.unlock();
236 k.lock(); // same as for n.lock()
237 k.unlock();
238 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
239 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
240 m.unlock();
243 void f() {
244 sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
245 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
248 void testBlockInCriticalSectionInterProcedural() {
249 std::mutex m;
250 m.lock(); // expected-note {{Entering critical section here}}
251 f(); // expected-note {{Calling 'f'}}
252 m.unlock();
255 void unknown_function_that_may_lock(std::mutex &);
256 void testBlockInCriticalSectionUnexpectedUnlock() {
257 std::mutex m;
258 unknown_function_that_may_lock(m);
259 m.unlock();
260 sleep(1); // no-warning
261 m.lock(); // expected-note {{Entering critical section here}}
262 sleep(2); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
263 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
266 void testBlockInCriticalSectionLockGuard() {
267 std::mutex g_mutex;
268 std::not_real_lock<std::mutex> not_real_lock(g_mutex);
269 sleep(1); // no-warning
271 std::lock_guard<std::mutex> lock(g_mutex); // expected-note {{Entering critical section here}}
272 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
273 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
276 void testBlockInCriticalSectionLockGuardNested() {
277 testBlockInCriticalSectionLockGuard(); // expected-note {{Calling 'testBlockInCriticalSectionLockGuard'}}
278 sleep(1); // no-warning
281 void testBlockInCriticalSectionUniqueLock() {
282 std::mutex g_mutex;
283 std::not_real_lock<std::mutex> not_real_lock(g_mutex);
284 sleep(1); // no-warning
286 std::unique_lock<std::mutex> lock(g_mutex); // expected-note {{Entering critical section here}}
287 sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
288 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
291 void testBlockInCriticalSectionUniqueLockNested() {
292 testBlockInCriticalSectionUniqueLock(); // expected-note {{Calling 'testBlockInCriticalSectionUniqueLock'}}
293 sleep(1); // no-warning
296 void testTrylockCurrentlyFalsePositive(pthread_mutex_t *m) {
297 // expected-note@+4 {{Assuming the condition is true}}
298 // expected-note@+3 {{Taking true branch}}
299 // expected-note@+2 {{Assuming the condition is false}}
300 // expected-note@+1 {{Taking false branch}}
301 if (pthread_mutex_trylock(m) == 0) { // expected-note 2 {{Entering critical section here}}
302 // FIXME: we are entering the critical section only in the true branch
303 sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
304 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
305 pthread_mutex_unlock(m);
306 } else {
307 sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
308 // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}}
309 // FIXME: this is a false positive, the lock was not acquired