| // 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; | 
 |  | 
 | #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 | 
 | 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); | 
 | } |