| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.fuchsia.Lock -verify %s |
| |
| typedef int spin_lock_t; |
| typedef int zx_status_t; |
| typedef int zx_time_t; |
| |
| void spin_lock(spin_lock_t *lock); |
| int spin_trylock(spin_lock_t *lock); |
| void spin_unlock(spin_lock_t *lock); |
| void spin_lock_init(spin_lock_t *lock); |
| |
| void spin_lock_save(spin_lock_t *lock, void *statep, |
| int flags); |
| void spin_unlock_restore(spin_lock_t *lock, void *old_state, |
| int flags); |
| |
| spin_lock_t mtx1; |
| spin_lock_t mtx2; |
| |
| void bad1(void) |
| { |
| spin_lock(&mtx1); // no-warning |
| spin_lock(&mtx1); // expected-warning{{This lock has already been acquired}} |
| } |
| |
| void bad2(void) { |
| spin_lock(&mtx1); |
| spin_unlock(&mtx1); |
| spin_unlock(&mtx1); // expected-warning {{This lock has already been unlocked}} |
| } |
| |
| void bad3() { |
| spin_lock_init(&mtx1); |
| if (spin_trylock(&mtx1) != 0) |
| spin_unlock(&mtx1); // expected-warning {{This lock has already been unlocked}} |
| } |
| |
| void bad4(void) { |
| spin_lock(&mtx1); |
| spin_lock(&mtx2); |
| spin_unlock(&mtx1); // expected-warning {{This was not the most recently acquired lock. Possible lock order reversal}} |
| spin_unlock(&mtx2); |
| } |
| |
| void good() { |
| spin_lock_t mtx; |
| spin_lock_init(&mtx); |
| spin_lock_save(&mtx, 0, 0); |
| spin_unlock_restore(&mtx, 0, 0); |
| } |
| |
| void good2() { |
| spin_lock_t mtx; |
| spin_lock_init(&mtx); |
| if (spin_trylock(&mtx) == 0) |
| spin_unlock(&mtx); |
| } |
| |
| typedef int sync_mutex_t; |
| void sync_mutex_lock(sync_mutex_t* mutex); |
| void sync_mutex_lock_with_waiter(sync_mutex_t* mutex); |
| zx_status_t sync_mutex_timedlock(sync_mutex_t* mutex, zx_time_t deadline); |
| zx_status_t sync_mutex_trylock(sync_mutex_t* mutex); |
| void sync_mutex_unlock(sync_mutex_t* mutex); |
| |
| sync_mutex_t smtx1; |
| sync_mutex_t smtx2; |
| |
| void bad11(void) |
| { |
| sync_mutex_lock(&smtx1); // no-warning |
| sync_mutex_lock(&smtx1); // expected-warning{{This lock has already been acquired}} |
| } |
| |
| void bad12(void) { |
| sync_mutex_lock_with_waiter(&smtx1); |
| sync_mutex_unlock(&smtx1); |
| sync_mutex_unlock(&smtx1); // expected-warning {{This lock has already been unlocked}} |
| } |
| |
| void bad13() { |
| sync_mutex_unlock(&smtx1); |
| if (sync_mutex_trylock(&smtx1) != 0) |
| sync_mutex_unlock(&smtx1); // expected-warning {{This lock has already been unlocked}} |
| } |
| |
| void bad14(void) { |
| sync_mutex_lock(&smtx1); |
| sync_mutex_lock(&smtx2); |
| sync_mutex_unlock(&smtx1); // expected-warning {{This was not the most recently acquired lock. Possible lock order reversal}} |
| sync_mutex_unlock(&smtx2); |
| } |
| |
| void good11() { |
| sync_mutex_t mtx; |
| if (sync_mutex_trylock(&mtx) == 0) |
| sync_mutex_unlock(&mtx); |
| } |
| |
| void good12() { |
| sync_mutex_t mtx; |
| if (sync_mutex_timedlock(&mtx, 0) == 0) |
| sync_mutex_unlock(&mtx); |
| } |