// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.unix.PthreadLock -verify %s // Tests performing normal locking patterns and wrong locking orders typedef struct { void *foo; } pthread_mutex_t; typedef pthread_mutex_t lck_mtx_t; extern int pthread_mutex_lock(pthread_mutex_t *); extern int pthread_mutex_unlock(pthread_mutex_t *); extern int pthread_mutex_trylock(pthread_mutex_t *); extern int lck_mtx_lock(lck_mtx_t *); extern int lck_mtx_unlock(lck_mtx_t *); extern int lck_mtx_try_lock(lck_mtx_t *); pthread_mutex_t mtx1, mtx2; lck_mtx_t lck1, lck2; void ok1(void) { pthread_mutex_lock(&mtx1); // no-warning } void ok2(void) { pthread_mutex_unlock(&mtx1); // no-warning } void ok3(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok4(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx2); // no-warning } void ok5(void) { if (pthread_mutex_trylock(&mtx1) == 0) // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok6(void) { lck_mtx_lock(&lck1); // no-warning } void ok7(void) { if (lck_mtx_try_lock(&lck1) != 0) // no-warning lck_mtx_unlock(&lck1); // no-warning } void bad1(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // expected-warning{{This lock has already been acquired}} } void bad2(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // expected-warning{{This lock has already been acquired}} } void bad3(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx1); // expected-warning{{This was not the most recently acquired lock}} pthread_mutex_unlock(&mtx2); } void bad4(void) { if (pthread_mutex_trylock(&mtx1)) // no-warning return; pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx1); // expected-warning{{This was not the most recently acquired lock}} } void bad5(void) { lck_mtx_lock(&lck1); // no-warning lck_mtx_lock(&lck1); // expected-warning{{This lock has already been acquired}} } void bad6(void) { lck_mtx_lock(&lck1); // no-warning lck_mtx_unlock(&lck1); // no-warning lck_mtx_lock(&lck1); // no-warning lck_mtx_lock(&lck1); // expected-warning{{This lock has already been acquired}} } void bad7(void) { lck_mtx_lock(&lck1); // no-warning lck_mtx_lock(&lck2); // no-warning lck_mtx_unlock(&lck1); // expected-warning{{This was not the most recently acquired lock}} lck_mtx_unlock(&lck2); } void bad8(void) { if (lck_mtx_try_lock(&lck1) == 0) // no-warning return; lck_mtx_lock(&lck2); // no-warning lck_mtx_unlock(&lck1); // expected-warning{{This was not the most recently acquired lock}} }