// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.PthreadLock -verify %s // Tests performing normal locking patterns and wrong locking orders #include "Inputs/system-header-simulator-for-pthread-lock.h" pthread_mutex_t mtx1, mtx2; pthread_mutex_t *pmtx; lck_mtx_t lck1, lck2; lck_grp_t grp1; lck_rw_t rw; #define NULL 0 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 ok8(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx2); // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok9(void) { pthread_mutex_unlock(&mtx1); // no-warning if (pthread_mutex_trylock(&mtx1) == 0) // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok10(void) { if (pthread_mutex_trylock(&mtx1) != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok11(void) { pthread_mutex_destroy(&mtx1); // no-warning } void ok12(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_destroy(&mtx2); // no-warning } void ok13(void) { pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // no-warning } void ok14(void) { pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_unlock(&mtx2); // no-warning pthread_mutex_destroy(&mtx2); // no-warning } void ok15(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // no-warning } void ok16(void) { pthread_mutex_init(&mtx1, NULL); // no-warning } void ok17(void) { pthread_mutex_init(&mtx1, NULL); // no-warning pthread_mutex_init(&mtx2, NULL); // no-warning } void ok18(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // no-warning } void ok19(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // no-warning pthread_mutex_destroy(&mtx2); // no-warning pthread_mutex_init(&mtx2, NULL); // no-warning } void ok20(void) { pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // no-warning pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // no-warning } void ok21(void) { pthread_mutex_lock(pmtx); // no-warning pthread_mutex_unlock(pmtx); // no-warning } void ok22(void) { pthread_mutex_lock(pmtx); // no-warning pthread_mutex_unlock(pmtx); // no-warning pthread_mutex_lock(pmtx); // no-warning pthread_mutex_unlock(pmtx); // no-warning } void ok23(void) { if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_destroy(&mtx1); // no-warning } void ok24(void) { if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning } void ok25(void) { if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_unlock(&mtx1); // no-warning } void ok26(void) { pthread_mutex_unlock(&mtx1); // no-warning if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning } void ok27(void) { pthread_mutex_unlock(&mtx1); // no-warning if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning else pthread_mutex_init(&mtx1, NULL); // no-warning } void ok28(void) { if (pthread_mutex_destroy(&mtx1) != 0) { // no-warning pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // no-warning } } void ok29(void) { lck_rw_lock_shared(&rw); lck_rw_unlock_shared(&rw); lck_rw_lock_exclusive(&rw); // no-warning lck_rw_unlock_exclusive(&rw); // no-warning } void escape_mutex(pthread_mutex_t *m); void ok30(void) { pthread_mutex_t local_mtx; pthread_mutex_init(&local_mtx, NULL); pthread_mutex_lock(&local_mtx); escape_mutex(&local_mtx); pthread_mutex_lock(&local_mtx); // no-warning pthread_mutex_unlock(&local_mtx); pthread_mutex_destroy(&local_mtx); } void ok31(void) { pthread_mutex_t local_mtx; pthread_mutex_init(&local_mtx, NULL); pthread_mutex_lock(&local_mtx); fake_system_function_that_takes_a_mutex(&local_mtx); pthread_mutex_lock(&local_mtx); // no-warning pthread_mutex_unlock(&local_mtx); pthread_mutex_destroy(&local_mtx); } 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}} } void bad9(void) { lck_mtx_unlock(&lck1); // no-warning lck_mtx_unlock(&lck1); // expected-warning{{This lock has already been unlocked}} } void bad10(void) { lck_mtx_lock(&lck1); // no-warning lck_mtx_unlock(&lck1); // no-warning lck_mtx_unlock(&lck1); // expected-warning{{This lock has already been unlocked}} } static void bad11_sub(pthread_mutex_t *lock) { lck_mtx_unlock(lock); // expected-warning{{This lock has already been unlocked}} } void bad11(int i) { lck_mtx_lock(&lck1); // no-warning lck_mtx_unlock(&lck1); // no-warning if (i < 5) bad11_sub(&lck1); } void bad12(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 pthread_mutex_unlock(&mtx1); // expected-warning{{This lock has already been unlocked}} } void bad13(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 pthread_mutex_unlock(&mtx1); // expected-warning{{This lock has already been unlocked}} } void bad14(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx2); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_unlock(&mtx2); // expected-warning{{This lock has already been unlocked}} } void bad15(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_lock(&mtx2); // no-warning pthread_mutex_unlock(&mtx2); // no-warning pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx2); // expected-warning{{This lock has already been unlocked}} } void bad16(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad17(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad18(void) { pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad19(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_destroy(&mtx1); // expected-warning{{This lock is still locked}} } void bad20(void) { lck_mtx_destroy(&mtx1, &grp1); // no-warning lck_mtx_lock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad21(void) { lck_mtx_destroy(&mtx1, &grp1); // no-warning lck_mtx_unlock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad22(void) { lck_mtx_destroy(&mtx1, &grp1); // no-warning lck_mtx_destroy(&mtx1, &grp1); // expected-warning{{This lock has already been destroyed}} } void bad23(void) { lck_mtx_lock(&mtx1); // no-warning lck_mtx_destroy(&mtx1, &grp1); // expected-warning{{This lock is still locked}} } void bad24(void) { pthread_mutex_init(&mtx1, NULL); // no-warning pthread_mutex_init(&mtx1, NULL); // expected-warning{{This lock has already been initialized}} } void bad25(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // expected-warning{{This lock is still being held}} } void bad26(void) { pthread_mutex_unlock(&mtx1); // no-warning pthread_mutex_init(&mtx1, NULL); // expected-warning{{This lock has already been initialized}} } void bad27(void) { pthread_mutex_unlock(&mtx1); // no-warning int ret = pthread_mutex_destroy(&mtx1); // no-warning if (ret != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning else pthread_mutex_unlock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad28(void) { pthread_mutex_unlock(&mtx1); // no-warning int ret = pthread_mutex_destroy(&mtx1); // no-warning if (ret != 0) // no-warning pthread_mutex_lock(&mtx1); // no-warning else pthread_mutex_lock(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad29(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_init(&mtx1, NULL); // expected-warning{{This lock has already been initialized}} else pthread_mutex_init(&mtx1, NULL); // no-warning } void bad30(void) { pthread_mutex_lock(&mtx1); // no-warning pthread_mutex_unlock(&mtx1); // no-warning if (pthread_mutex_destroy(&mtx1) != 0) // no-warning pthread_mutex_init(&mtx1, NULL); // expected-warning{{This lock has already been initialized}} else pthread_mutex_destroy(&mtx1); // expected-warning{{This lock has already been destroyed}} } void bad31(void) { int ret = pthread_mutex_destroy(&mtx1); // no-warning pthread_mutex_lock(&mtx1); // expected-warning{{This lock has already been destroyed}} if (ret != 0) pthread_mutex_lock(&mtx1); } void bad32(void) { lck_rw_lock_shared(&rw); lck_rw_unlock_exclusive(&rw); // FIXME: warn - should be shared? lck_rw_lock_exclusive(&rw); lck_rw_unlock_shared(&rw); // FIXME: warn - should be exclusive? } void bad33(void) { pthread_mutex_lock(pmtx); fake_system_function(); pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} }