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