Skip to content

Commit 6ef785c

Browse files
authored
[clang][analyzer] Move unix.BlockInCriticalSection out of alpha (#93815)
After recent improvements (#80029) and testing on open-source projects, the checker is ready to move out of the alpha package.
1 parent 72c901f commit 6ef785c

File tree

8 files changed

+53
-83
lines changed

8 files changed

+53
-83
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,50 @@ Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, mallo
12351235
.. literalinclude:: checkers/unix_api_example.c
12361236
:language: c
12371237
1238+
.. _unix-BlockInCriticalSection:
1239+
1240+
unix.BlockInCriticalSection (C, C++)
1241+
""""""""""""""""""""""""""""""""""""
1242+
Check for calls to blocking functions inside a critical section.
1243+
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
1244+
Critical section handling functions modeled by this checker:
1245+
``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``.
1246+
1247+
.. code-block:: c
1248+
1249+
void pthread_lock_example(pthread_mutex_t *m) {
1250+
pthread_mutex_lock(m); // note: entering critical section here
1251+
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
1252+
pthread_mutex_unlock(m);
1253+
}
1254+
1255+
.. code-block:: cpp
1256+
1257+
void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
1258+
std::lock_guard lg{m2}; // note: entering critical section here
1259+
mtx_lock(m1); // note: entering critical section here
1260+
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
1261+
mtx_unlock(m1);
1262+
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
1263+
// still inside of the critical section of the std::lock_guard
1264+
}
1265+
1266+
**Limitations**
1267+
1268+
* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed.
1269+
This can lead to false positives.
1270+
1271+
.. code-block:: c
1272+
1273+
void trylock_example(pthread_mutex_t *m) {
1274+
if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds
1275+
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
1276+
pthread_mutex_unlock(m);
1277+
} else {
1278+
sleep(10); // false positive: Incorrect warning about blocking function inside critical section.
1279+
}
1280+
}
1281+
12381282
.. _unix-Errno:
12391283
12401284
unix.Errno (C)
@@ -3130,49 +3174,6 @@ For a more detailed description of configuration options, please see the
31303174
alpha.unix
31313175
^^^^^^^^^^
31323176
3133-
.. _alpha-unix-BlockInCriticalSection:
3134-
3135-
alpha.unix.BlockInCriticalSection (C)
3136-
"""""""""""""""""""""""""""""""""""""
3137-
Check for calls to blocking functions inside a critical section.
3138-
Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``.
3139-
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``.
3140-
3141-
.. code-block:: c
3142-
3143-
void pthread_lock_example(pthread_mutex_t *m) {
3144-
pthread_mutex_lock(m); // note: entering critical section here
3145-
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
3146-
pthread_mutex_unlock(m);
3147-
}
3148-
3149-
.. code-block:: cpp
3150-
3151-
void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) {
3152-
std::lock_guard lg{m2}; // note: entering critical section here
3153-
mtx_lock(m1); // note: entering critical section here
3154-
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
3155-
mtx_unlock(m1);
3156-
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
3157-
// still inside of the critical section of the std::lock_guard
3158-
}
3159-
3160-
**Limitations**
3161-
3162-
* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed.
3163-
This can lead to false positives.
3164-
3165-
.. code-block:: c
3166-
3167-
void trylock_example(pthread_mutex_t *m) {
3168-
if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds
3169-
sleep(10); // warn: Call to blocking function 'sleep' inside of critical section
3170-
pthread_mutex_unlock(m);
3171-
} else {
3172-
sleep(10); // false positive: Incorrect warning about blocking function inside critical section.
3173-
}
3174-
}
3175-
31763177
.. _alpha-unix-Chroot:
31773178
31783179
alpha.unix.Chroot (C)

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,10 @@ def UnixAPIMisuseChecker : Checker<"API">,
509509
HelpText<"Check calls to various UNIX/Posix functions">,
510510
Documentation<HasDocumentation>;
511511

512+
def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
513+
HelpText<"Check for calls to blocking functions inside a critical section">,
514+
Documentation<HasDocumentation>;
515+
512516
def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
513517
HelpText<"The base of several malloc() related checkers. On it's own it "
514518
"emits no reports, but adds valuable information to the analysis "
@@ -619,10 +623,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">,
619623
HelpText<"Check for misuses of stream APIs">,
620624
Documentation<HasDocumentation>;
621625

622-
def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
623-
HelpText<"Check for calls to blocking functions inside a critical section">,
624-
Documentation<HasDocumentation>;
625-
626626
} // end "alpha.unix"
627627

628628
//===----------------------------------------------------------------------===//

clang/test/Analysis/analyzer-enabled-checkers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
// CHECK-NEXT: security.insecureAPI.mktemp
4343
// CHECK-NEXT: security.insecureAPI.vfork
4444
// CHECK-NEXT: unix.API
45+
// CHECK-NEXT: unix.BlockInCriticalSection
4546
// CHECK-NEXT: unix.cstring.CStringModeling
4647
// CHECK-NEXT: unix.DynamicMemoryModeling
4748
// CHECK-NEXT: unix.Errno

clang/test/Analysis/block-in-critical-section.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify %s
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify %s
22
// expected-no-diagnostics
33

44
// This should not crash

clang/test/Analysis/block-in-critical-section.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_analyze_cc1 \
2-
// RUN: -analyzer-checker=alpha.unix.BlockInCriticalSection \
2+
// RUN: -analyzer-checker=unix.BlockInCriticalSection \
33
// RUN: -std=c++11 \
44
// RUN: -analyzer-output text \
55
// RUN: -verify %s

clang/test/Analysis/block-in-critical-section.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
22
// expected-no-diagnostics
33

44
@interface SomeClass

clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
// CHECK-NEXT: security.insecureAPI.mktemp
5151
// CHECK-NEXT: security.insecureAPI.vfork
5252
// CHECK-NEXT: unix.API
53+
// CHECK-NEXT: unix.BlockInCriticalSection
5354
// CHECK-NEXT: unix.cstring.CStringModeling
5455
// CHECK-NEXT: unix.DynamicMemoryModeling
5556
// CHECK-NEXT: unix.Errno

clang/www/analyzer/alpha_checks.html

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -780,39 +780,6 @@ <h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
780780
<tbody>
781781

782782

783-
<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
784-
alpha.unix.BlockInCriticalSection</span><span class="lang">
785-
(C)</span><div class="descr">
786-
Check for calls to blocking functions inside a critical section. Applies to:
787-
<div class=functions>
788-
lock<br>
789-
unlock<br>
790-
sleep<br>
791-
getc<br>
792-
fgets<br>
793-
read<br>
794-
revc<br>
795-
pthread_mutex_lock<br>
796-
pthread_mutex_unlock<br>
797-
mtx_lock<br>
798-
mtx_timedlock<br>
799-
mtx_trylock<br>
800-
mtx_unlock<br>
801-
lock_guard<br>
802-
unique_lock</div>
803-
</div></div></a></td>
804-
<td><div class="exampleContainer expandable">
805-
<div class="example"><pre>
806-
void test() {
807-
std::mutex m;
808-
m.lock();
809-
sleep(3); // warn: a blocking function sleep is called inside a critical
810-
// section
811-
m.unlock();
812-
}
813-
</pre></div></div></td></tr>
814-
815-
816783
<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
817784
alpha.unix.Chroot</span><span class="lang">
818785
(C)</span><div class="descr">

0 commit comments

Comments
 (0)