1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.fuchsia.Lock -verify %s
2
3 typedef int spin_lock_t;
4 typedef int zx_status_t;
5 typedef int zx_time_t;
6
7 void spin_lock(spin_lock_t *lock);
8 int spin_trylock(spin_lock_t *lock);
9 void spin_unlock(spin_lock_t *lock);
10 void spin_lock_init(spin_lock_t *lock);
11
12 void spin_lock_save(spin_lock_t *lock, void *statep,
13 int flags);
14 void spin_unlock_restore(spin_lock_t *lock, void *old_state,
15 int flags);
16
17 spin_lock_t mtx1;
18 spin_lock_t mtx2;
19
bad1(void)20 void bad1(void)
21 {
22 spin_lock(&mtx1); // no-warning
23 spin_lock(&mtx1); // expected-warning{{This lock has already been acquired}}
24 }
25
bad2(void)26 void bad2(void) {
27 spin_lock(&mtx1);
28 spin_unlock(&mtx1);
29 spin_unlock(&mtx1); // expected-warning {{This lock has already been unlocked}}
30 }
31
bad3()32 void bad3() {
33 spin_lock_init(&mtx1);
34 if (spin_trylock(&mtx1) != 0)
35 spin_unlock(&mtx1); // expected-warning {{This lock has already been unlocked}}
36 }
37
bad4(void)38 void bad4(void) {
39 spin_lock(&mtx1);
40 spin_lock(&mtx2);
41 spin_unlock(&mtx1); // expected-warning {{This was not the most recently acquired lock. Possible lock order reversal}}
42 spin_unlock(&mtx2);
43 }
44
good()45 void good() {
46 spin_lock_t mtx;
47 spin_lock_init(&mtx);
48 spin_lock_save(&mtx, 0, 0);
49 spin_unlock_restore(&mtx, 0, 0);
50 }
51
good2()52 void good2() {
53 spin_lock_t mtx;
54 spin_lock_init(&mtx);
55 if (spin_trylock(&mtx) == 0)
56 spin_unlock(&mtx);
57 }
58
59 typedef int sync_mutex_t;
60 void sync_mutex_lock(sync_mutex_t* mutex);
61 void sync_mutex_lock_with_waiter(sync_mutex_t* mutex);
62 zx_status_t sync_mutex_timedlock(sync_mutex_t* mutex, zx_time_t deadline);
63 zx_status_t sync_mutex_trylock(sync_mutex_t* mutex);
64 void sync_mutex_unlock(sync_mutex_t* mutex);
65
66 sync_mutex_t smtx1;
67 sync_mutex_t smtx2;
68
bad11(void)69 void bad11(void)
70 {
71 sync_mutex_lock(&smtx1); // no-warning
72 sync_mutex_lock(&smtx1); // expected-warning{{This lock has already been acquired}}
73 }
74
bad12(void)75 void bad12(void) {
76 sync_mutex_lock_with_waiter(&smtx1);
77 sync_mutex_unlock(&smtx1);
78 sync_mutex_unlock(&smtx1); // expected-warning {{This lock has already been unlocked}}
79 }
80
bad13()81 void bad13() {
82 sync_mutex_unlock(&smtx1);
83 if (sync_mutex_trylock(&smtx1) != 0)
84 sync_mutex_unlock(&smtx1); // expected-warning {{This lock has already been unlocked}}
85 }
86
bad14(void)87 void bad14(void) {
88 sync_mutex_lock(&smtx1);
89 sync_mutex_lock(&smtx2);
90 sync_mutex_unlock(&smtx1); // expected-warning {{This was not the most recently acquired lock. Possible lock order reversal}}
91 sync_mutex_unlock(&smtx2);
92 }
93
good11()94 void good11() {
95 sync_mutex_t mtx;
96 if (sync_mutex_trylock(&mtx) == 0)
97 sync_mutex_unlock(&mtx);
98 }
99
good12()100 void good12() {
101 sync_mutex_t mtx;
102 if (sync_mutex_timedlock(&mtx, 0) == 0)
103 sync_mutex_unlock(&mtx);
104 }
105