[clang] [clang-tools-extra] [clang-tidy][dataflow] Add `bugprone-null-check-after-dereference` check (PR #84166)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 7 02:46:03 PST 2024
================
@@ -0,0 +1,162 @@
+.. title:: clang-tidy - bugprone-null-check-after-dereference
+
+bugprone-null-check-after-dereference
+=====================================
+
+.. note::
+
+ This check uses a flow-sensitive static analysis to produce its
+ results. Therefore, it may be more resource intensive (RAM, CPU) than the
+ average clang-tidy check.
+
+This check identifies redundant pointer null-checks, by finding cases where the
+pointer cannot be null at the location of the null-check.
+
+Redundant null-checks can signal faulty assumptions about the current value of
+a pointer at different points in the program. Either the null-check is
+redundant, or there could be a null-pointer dereference earlier in the program.
+
+.. code-block:: c++
+
+ int f(int *ptr) {
+ *ptr = 20; // note: one of the locations where the pointer's value cannot be null
+ // ...
+ if (ptr) { // bugprone: pointer is checked even though it cannot be null at this point
+ return *ptr;
+ }
+ return 0;
+ }
+
+Supported pointer operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pointer null-checks
+-------------------
+
+The checker currently supports null-checks on pointers that use
+``operator bool``, such as when being used as the condition
+for an `if` statement.
+
+.. code-block:: c++
+
+ int f(int *ptr) {
+ if (ptr) {
+ if (ptr) { // bugprone: pointer is re-checked after its null-ness is already checked.
+ return *ptr;
+ }
+
+ return ptr ? *ptr : 0; // bugprone: pointer is re-checked after its null-ness is already checked.
+ }
+ return 0;
+ }
+
+Pointer dereferences
+--------------------
+
+Pointer star- and arrow-dereferences are supported.
+
+.. code-block:: c++
+
+ struct S {
+ int val;
+ };
+
+ void f(int *ptr, S *wrapper) {
+ *ptr = 20;
+ wrapper->val = 15;
+ }
+
+Null-pointer and other value assignments
+----------------------------------------
+
+The checker supports assigning various values to pointers, making them *null*
+or *non-null*. The checker also supports passing pointers of a pointer to
+external functions.
+
+.. code-block:: c++
+
+ extern int *external();
+ extern void refresh(int **ptr_ptr);
+
+ int f() {
+ int *ptr_null = nullptr;
+ if (ptr_null) { // bugprone: pointer is checked where it cannot be non-null.
+ return *ptr_null;
+ }
+
+ int *ptr = external();
+ if (ptr) { // safe: external() could return either nullable or nonnull pointers.
+ return *ptr;
+ }
+
+ int *ptr2 = external();
+ *ptr2 = 20;
+ refresh(&ptr2);
+ if (ptr2) { // safe: pointer could be changed by refresh().
+ return *ptr2;
+ }
+ return 0;
+ }
+
+Limitations
+~~~~~~~~~~~
+
+The check only supports C++ due to limitations in the data-flow framework.
+
+The annotations ``_nullable`` and ``_nonnull`` are not supported.
----------------
martinboehme wrote:
These annotations should be upper-case (`_Nullable` and `_Nonnull`). The lower-case spellings are not supported (they produce a compiler error).
https://github.com/llvm/llvm-project/pull/84166
More information about the cfe-commits
mailing list