1 // RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.PthreadLock -verify %s
2 
3 // Tests performing normal locking patterns and wrong locking orders
4 
5 typedef struct {
6 	void	*foo;
7 } pthread_mutex_t;
8 
9 typedef pthread_mutex_t lck_mtx_t;
10 
11 extern int pthread_mutex_lock(pthread_mutex_t *);
12 extern int pthread_mutex_unlock(pthread_mutex_t *);
13 extern int pthread_mutex_trylock(pthread_mutex_t *);
14 extern int lck_mtx_lock(lck_mtx_t *);
15 extern int lck_mtx_unlock(lck_mtx_t *);
16 extern int lck_mtx_try_lock(lck_mtx_t *);
17 
18 pthread_mutex_t mtx1, mtx2;
19 lck_mtx_t lck1, lck2;
20 
21 void
22 ok1(void)
23 {
24 	pthread_mutex_lock(&mtx1); // no-warning
25 }
26 
27 void
28 ok2(void)
29 {
30 	pthread_mutex_unlock(&mtx1); // no-warning
31 }
32 
33 void
34 ok3(void)
35 {
36 	pthread_mutex_lock(&mtx1);	// no-warning
37 	pthread_mutex_unlock(&mtx1);	// no-warning
38 	pthread_mutex_lock(&mtx1);	// no-warning
39 	pthread_mutex_unlock(&mtx1);	// no-warning
40 }
41 
42 void
43 ok4(void)
44 {
45 	pthread_mutex_lock(&mtx1);	// no-warning
46 	pthread_mutex_unlock(&mtx1);	// no-warning
47 	pthread_mutex_lock(&mtx2);	// no-warning
48 	pthread_mutex_unlock(&mtx2);	// no-warning
49 }
50 
51 void
52 ok5(void)
53 {
54 	if (pthread_mutex_trylock(&mtx1) == 0)	// no-warning
55 		pthread_mutex_unlock(&mtx1);	// no-warning
56 }
57 
58 void
59 ok6(void)
60 {
61 	lck_mtx_lock(&lck1);		// no-warning
62 }
63 
64 void
65 ok7(void)
66 {
67 	if (lck_mtx_try_lock(&lck1) != 0)	// no-warning
68 		lck_mtx_unlock(&lck1);		// no-warning
69 }
70 
71 void
72 bad1(void)
73 {
74 	pthread_mutex_lock(&mtx1);	// no-warning
75 	pthread_mutex_lock(&mtx1);	// expected-warning{{This lock has already been acquired}}
76 }
77 
78 void
79 bad2(void)
80 {
81 	pthread_mutex_lock(&mtx1);	// no-warning
82 	pthread_mutex_unlock(&mtx1);	// no-warning
83 	pthread_mutex_lock(&mtx1);	// no-warning
84 	pthread_mutex_lock(&mtx1);	// expected-warning{{This lock has already been acquired}}
85 }
86 
87 void
88 bad3(void)
89 {
90 	pthread_mutex_lock(&mtx1);	// no-warning
91 	pthread_mutex_lock(&mtx2);	// no-warning
92 	pthread_mutex_unlock(&mtx1);	// expected-warning{{This was not the most recently acquired lock}}
93 	pthread_mutex_unlock(&mtx2);
94 }
95 
96 void
97 bad4(void)
98 {
99 	if (pthread_mutex_trylock(&mtx1)) // no-warning
100 		return;
101 	pthread_mutex_lock(&mtx2);	// no-warning
102 	pthread_mutex_unlock(&mtx1);	// expected-warning{{This was not the most recently acquired lock}}
103 }
104 
105 void
106 bad5(void)
107 {
108 	lck_mtx_lock(&lck1);	// no-warning
109 	lck_mtx_lock(&lck1);	// expected-warning{{This lock has already been acquired}}
110 }
111 
112 void
113 bad6(void)
114 {
115 	lck_mtx_lock(&lck1);	// no-warning
116 	lck_mtx_unlock(&lck1);	// no-warning
117 	lck_mtx_lock(&lck1);	// no-warning
118 	lck_mtx_lock(&lck1);	// expected-warning{{This lock has already been acquired}}
119 }
120 
121 void
122 bad7(void)
123 {
124 	lck_mtx_lock(&lck1);	// no-warning
125 	lck_mtx_lock(&lck2);	// no-warning
126 	lck_mtx_unlock(&lck1);	// expected-warning{{This was not the most recently acquired lock}}
127 	lck_mtx_unlock(&lck2);
128 }
129 
130 void
131 bad8(void)
132 {
133 	if (lck_mtx_try_lock(&lck1) == 0) // no-warning
134 		return;
135 	lck_mtx_lock(&lck2);		// no-warning
136 	lck_mtx_unlock(&lck1);		// expected-warning{{This was not the most recently acquired lock}}
137 }
138