Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang][analyzer] Move unix.BlockInCriticalSection out of alpha #93815

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 44 additions & 43 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,50 @@ Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, mallo
.. literalinclude:: checkers/unix_api_example.c
:language: c

.. _unix-BlockInCriticalSection:

unix.BlockInCriticalSection (C, C++)
""""""""""""""""""""""""""""""""""""
Check for calls to blocking functions inside a critical section.
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
Critical section handling functions modeled by this checker:
``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.

.. code-block:: c

void pthread_lock_example(pthread_mutex_t *m) {
pthread_mutex_lock(m); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
}

.. code-block:: cpp

void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
std::lock_guard lg{m2}; // note: entering critical section here
mtx_lock(m1); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
mtx_unlock(m1);
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
// still inside of the critical section of the std::lock_guard
}

**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.
}
}

.. _unix-Errno:

unix.Errno (C)
Expand Down Expand Up @@ -3130,49 +3174,6 @@ For a more detailed description of configuration options, please see the
alpha.unix
^^^^^^^^^^

.. _alpha-unix-BlockInCriticalSection:

alpha.unix.BlockInCriticalSection (C)
"""""""""""""""""""""""""""""""""""""
Check for calls to blocking functions inside a critical section.
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
Critical section handling functions modelled by this checker: ``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.

.. code-block:: c

void pthread_lock_example(pthread_mutex_t *m) {
pthread_mutex_lock(m); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
pthread_mutex_unlock(m);
}

.. code-block:: cpp

void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
std::lock_guard lg{m2}; // note: entering critical section here
mtx_lock(m1); // note: entering critical section here
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
mtx_unlock(m1);
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
// still inside of the critical section of the std::lock_guard
}

**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)
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ def UnixAPIMisuseChecker : Checker<"API">,
HelpText<"Check calls to various UNIX/Posix functions">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
HelpText<"The base of several malloc() related checkers. On it's own it "
"emits no reports, but adds valuable information to the analysis "
Expand Down Expand Up @@ -619,10 +623,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
Documentation<HasDocumentation>;

def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
Documentation<HasDocumentation>;

} // end "alpha.unix"

//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions clang/test/Analysis/analyzer-enabled-checkers.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
// CHECK-NEXT: security.insecureAPI.mktemp
// CHECK-NEXT: security.insecureAPI.vfork
// CHECK-NEXT: unix.API
// CHECK-NEXT: unix.BlockInCriticalSection
// CHECK-NEXT: unix.cstring.CStringModeling
// CHECK-NEXT: unix.DynamicMemoryModeling
// CHECK-NEXT: unix.Errno
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify %s
// expected-no-diagnostics

// This should not crash
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 \
// RUN: -analyzer-checker=alpha.unix.BlockInCriticalSection \
// RUN: -analyzer-checker=unix.BlockInCriticalSection \
// RUN: -std=c++11 \
// RUN: -analyzer-output text \
// RUN: -verify %s
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/block-in-critical-section.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
// expected-no-diagnostics

@interface SomeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
// CHECK-NEXT: security.insecureAPI.mktemp
// CHECK-NEXT: security.insecureAPI.vfork
// CHECK-NEXT: unix.API
// CHECK-NEXT: unix.BlockInCriticalSection
// CHECK-NEXT: unix.cstring.CStringModeling
// CHECK-NEXT: unix.DynamicMemoryModeling
// CHECK-NEXT: unix.Errno
Expand Down
33 changes: 0 additions & 33 deletions clang/www/analyzer/alpha_checks.html
Original file line number Diff line number Diff line change
Expand Up @@ -780,39 +780,6 @@ <h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
<tbody>


<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
alpha.unix.BlockInCriticalSection</span><span class="lang">
(C)</span><div class="descr">
Check for calls to blocking functions inside a critical section. Applies to:
<div class=functions>
lock<br>
unlock<br>
sleep<br>
getc<br>
fgets<br>
read<br>
revc<br>
pthread_mutex_lock<br>
pthread_mutex_unlock<br>
mtx_lock<br>
mtx_timedlock<br>
mtx_trylock<br>
mtx_unlock<br>
lock_guard<br>
unique_lock</div>
</div></div></a></td>
<td><div class="exampleContainer expandable">
<div class="example"><pre>
void test() {
std::mutex m;
m.lock();
sleep(3); // warn: a blocking function sleep is called inside a critical
// section
m.unlock();
}
</pre></div></div></td></tr>


<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
alpha.unix.Chroot</span><span class="lang">
(C)</span><div class="descr">
Expand Down
Loading