diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2014-04-01 03:40:38 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2014-04-01 03:40:38 +0000 |
| commit | 0696bb4cef7592892019b5e6c6ee9d1603843061 (patch) | |
| tree | dc9be8b26c684ca7dda8374d78eeafde1b4fffb0 /clang/test/Analysis | |
| parent | 5557f6d6787c68719ce657cb5fee66b322f40c23 (diff) | |
| download | bcm5719-llvm-0696bb4cef7592892019b5e6c6ee9d1603843061.tar.gz bcm5719-llvm-0696bb4cef7592892019b5e6c6ee9d1603843061.zip | |
[analyzer] Add double-unlock detection to PthreadLockChecker.
We've decided to punt on supporting recursive locks for now; the common case
is non-recursive.
Patch by Daniel Fahlgren!
llvm-svn: 205274
Diffstat (limited to 'clang/test/Analysis')
| -rw-r--r-- | clang/test/Analysis/pthreadlock.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/clang/test/Analysis/pthreadlock.c b/clang/test/Analysis/pthreadlock.c index b9047742451..bc7ef66353f 100644 --- a/clang/test/Analysis/pthreadlock.c +++ b/clang/test/Analysis/pthreadlock.c @@ -69,6 +69,31 @@ ok7(void) } 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 bad1(void) { pthread_mutex_lock(&mtx1); // no-warning @@ -135,3 +160,74 @@ bad8(void) 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}} +} |

