https://github.com/gamesh411 updated https://github.com/llvm/llvm-project/pull/93799
From 6cc7b93783993e0e7f21124f2d640cb92484faff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fu...@sigmatechnology.com> Date: Thu, 30 May 2024 11:12:59 +0200 Subject: [PATCH 1/3] [clang][analyzer][NFC] Add test for a limitation of alpha.unix.BlockInCriticalSection checker Updated the documentation in `checkers.rst` to include an example of how `trylock` function is handled. Added a new test for a scenario where `pthread_mutex_trylock` is used, demonstrating the current limitation. --- clang/docs/analyzer/checkers.rst | 15 +++++++++ .../Analysis/block-in-critical-section.cpp | 31 ++++++++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 3a31708a1e9de..b677c5f3efa04 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3148,6 +3148,21 @@ Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,` m.unlock(); } +**Limitations** +* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed. + This can lead to false positives. + +.. code-block:: c + +void trylock_example(pthread_mutex_t *m) { + if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } else { + sleep(10); // false positive: Incorrect warning about blocking function inside critical section. + } +} + .. _alpha-unix-Chroot: alpha.unix.Chroot (C) diff --git a/clang/test/Analysis/block-in-critical-section.cpp b/clang/test/Analysis/block-in-critical-section.cpp index 87c26b9f1b520..403b7a16726a2 100644 --- a/clang/test/Analysis/block-in-critical-section.cpp +++ b/clang/test/Analysis/block-in-critical-section.cpp @@ -36,15 +36,15 @@ ssize_t read(int fd, void *buf, size_t count); ssize_t recv(int sockfd, void *buf, size_t len, int flags); struct pthread_mutex_t; -void pthread_mutex_lock(pthread_mutex_t *mutex); -void pthread_mutex_trylock(pthread_mutex_t *mutex); -void pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); struct mtx_t; -void mtx_lock(mtx_t *mutex); -void mtx_timedlock(mtx_t *mutex); -void mtx_trylock(mtx_t *mutex); -void mtx_unlock(mtx_t *mutex); +int mtx_lock(mtx_t *mutex); +int mtx_timedlock(mtx_t *mutex); +int mtx_trylock(mtx_t *mutex); +int mtx_unlock(mtx_t *mutex); // global params for dummy function calls FILE *stream; @@ -292,3 +292,20 @@ void testBlockInCriticalSectionUniqueLockNested() { testBlockInCriticalSectionUniqueLock(); // expected-note {{Calling 'testBlockInCriticalSectionUniqueLock'}} sleep(1); // no-warning } + +void testTrylockCurrentlyFalsePositive(pthread_mutex_t *m) { + // expected-note@+4 {{Assuming the condition is true}} + // expected-note@+3 {{Taking true branch}} + // expected-note@+2 {{Assuming the condition is false}} + // expected-note@+1 {{Taking false branch}} + if (pthread_mutex_trylock(m) == 0) { // expected-note 2 {{Entering critical section here}} + // FIXME: we are entering the critical section only in the true branch + sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + pthread_mutex_unlock(m); + } else { + sleep(10); // expected-warning {{Call to blocking function 'sleep' inside of critical section}} + // expected-note@-1 {{Call to blocking function 'sleep' inside of critical section}} + // FIXME: this is a false positive, the lock was not acquired + } +} From 71509c4f16915483a34ad6745e555481e4a872e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fu...@sigmatechnology.com> Date: Thu, 30 May 2024 14:16:12 +0200 Subject: [PATCH 2/3] fix indentation --- clang/docs/analyzer/checkers.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index b677c5f3efa04..5416a4d7d7f78 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3154,14 +3154,14 @@ Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,` .. code-block:: c -void trylock_example(pthread_mutex_t *m) { - if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds - sleep(10); // warn: Call to blocking function 'sleep' inside of critical section - pthread_mutex_unlock(m); - } else { - sleep(10); // false positive: Incorrect warning about blocking function inside critical section. - } -} + void trylock_example(pthread_mutex_t *m) { + if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } else { + sleep(10); // false positive: Incorrect warning about blocking function inside critical section. + } + } .. _alpha-unix-Chroot: From f44af12b4eda012f84354aaadc9dc26c3ccbd82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fu...@sigmatechnology.com> Date: Thu, 30 May 2024 14:34:06 +0200 Subject: [PATCH 3/3] fix missing newline --- clang/docs/analyzer/checkers.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 5416a4d7d7f78..71f8ad7d0cbc4 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3149,6 +3149,7 @@ Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,` } **Limitations** + * The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed. This can lead to false positives. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits