// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.PthreadLock -verify %s
// Tests performing normal locking patterns and wrong locking orders
typedef struct {
void *foo;
} pthread_mutex_t;
typedef struct {
void *foo;
} pthread_mutexattr_t;
typedef struct {
void *foo;
} lck_grp_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 pthread_mutex_destroy(pthread_mutex_t *);
extern int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
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 *);
extern void lck_mtx_destroy(lck_mtx_t *lck, lck_grp_t *grp);
pthread_mutex_t mtx1, mtx2;
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
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}}
}