https://github.com/zeyi2 created https://github.com/llvm/llvm-project/pull/212770
None >From abdbf30df148b5d6be55c448ff6de58a627b9054 Mon Sep 17 00:00:00 2001 From: Zeyi Xu <[email protected]> Date: Wed, 29 Jul 2026 21:31:58 +0800 Subject: [PATCH] [clang-tidy] Rewrite remaining bugprone check docs to Markdown [3/N] --- .../checks/bugprone/random-generator-seed.rst | 52 +- .../raw-memory-call-on-non-trivial-type.rst | 50 +- .../bugprone/redundant-branch-condition.rst | 137 +++--- .../checks/bugprone/reserved-identifier.rst | 54 +- .../return-const-ref-from-parameter.rst | 56 +-- .../bugprone/shared-ptr-array-mismatch.rst | 43 +- .../checks/bugprone/signal-handler.rst | 120 +++-- .../checks/bugprone/signed-char-misuse.rst | 161 +++--- .../checks/bugprone/sizeof-expression.rst | 462 +++++++++--------- .../checks/bugprone/standalone-empty.rst | 46 +- .../bugprone/std-exception-baseclass.rst | 44 +- .../bugprone/std-namespace-modification.rst | 68 ++- .../checks/bugprone/string-constructor.rst | 73 ++- .../bugprone/string-integer-assignment.rst | 50 +- .../string-literal-with-embedded-nul.rst | 36 +- .../checks/bugprone/stringview-nullptr.rst | 79 +-- .../checks/bugprone/suspicious-enum-usage.rst | 112 ++--- .../bugprone/suspicious-memory-comparison.rst | 24 +- .../bugprone/suspicious-memset-usage.rst | 71 ++- .../bugprone/suspicious-missing-comma.rst | 81 ++- 20 files changed, 887 insertions(+), 932 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.rst index c789f0fa6b27c..4c90025f8368e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.rst @@ -1,44 +1,40 @@ -.. title:: clang-tidy - bugprone-random-generator-seed +```{title} clang-tidy - bugprone-random-generator-seed +``` -bugprone-random-generator-seed -============================== +# bugprone-random-generator-seed Flags all pseudo-random number engines, engine adaptor -instantiations and ``srand()`` when initialized or seeded with default +instantiations and `srand()` when initialized or seeded with default argument, constant expression or any user-configurable type. Pseudo-random number engines seeded with a predictable value may cause vulnerabilities e.g. in security protocols. Examples: -.. code-block:: c++ +```c++ +void foo() { + std::mt19937 engine1; // Diagnose, always generate the same sequence + std::mt19937 engine2(1); // Diagnose + engine1.seed(); // Diagnose + engine2.seed(1); // Diagnose - void foo() { - std::mt19937 engine1; // Diagnose, always generate the same sequence - std::mt19937 engine2(1); // Diagnose - engine1.seed(); // Diagnose - engine2.seed(1); // Diagnose + std::time_t t; + engine1.seed(std::time(&t)); // Diagnose, system time might be controlled by user - std::time_t t; - engine1.seed(std::time(&t)); // Diagnose, system time might be controlled by user + int x = atoi(argv[1]); + std::mt19937 engine3(x); // Will not warn +} +``` - int x = atoi(argv[1]); - std::mt19937 engine3(x); // Will not warn - } +## Options -Options -------- +```{option} DisallowedSeedTypes +A comma-separated list of the type names which are disallowed. +Default value is `time_t,std::time_t`. +``` -.. option:: DisallowedSeedTypes - - A comma-separated list of the type names which are disallowed. - Default value is `time_t,std::time_t`. - -References ----------- +## References This check corresponds to the CERT C++ Coding Standard rules -`MSC51-CPP. Ensure your random number generator is properly seeded -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/miscellaneous-msc/msc51-cpp/>`_ and -`MSC32-C. Properly seed pseudorandom number generators -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/miscellaneous-msc/msc32-c/>`_. +[MSC51-CPP. Ensure your random number generator is properly seeded](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/miscellaneous-msc/msc51-cpp/) and +[MSC32-C. Properly seed pseudorandom number generators](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/miscellaneous-msc/msc32-c/). diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.rst index 3385abdc39ab3..c057e2302d2ae 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.rst @@ -1,35 +1,33 @@ -.. title:: clang-tidy - bugprone-raw-memory-call-on-non-trivial-type +```{title} clang-tidy - bugprone-raw-memory-call-on-non-trivial-type +``` -bugprone-raw-memory-call-on-non-trivial-type -============================================ +# bugprone-raw-memory-call-on-non-trivial-type -Flags use of the C standard library functions ``memset``, ``memcpy`` and -``memcmp`` and similar derivatives on non-trivial types. +Flags use of the C standard library functions `memset`, `memcpy` and +`memcmp` and similar derivatives on non-trivial types. -The check will detect the following functions: ``memset``, ``std::memset``, -``std::memcpy``, ``memcpy``, ``std::memmove``, ``memmove``, ``std::strcpy``, -``strcpy``, ``memccpy``, ``stpncpy``, ``strncpy``, ``std::memcmp``, ``memcmp``, -``std::strcmp``, ``strcmp``, ``strncmp``. +The check will detect the following functions: `memset`, `std::memset`, +`std::memcpy`, `memcpy`, `std::memmove`, `memmove`, `std::strcpy`, +`strcpy`, `memccpy`, `stpncpy`, `strncpy`, `std::memcmp`, `memcmp`, +`std::strcmp`, `strcmp`, `strncmp`. -Options -------- +## Options -.. option:: MemSetNames +```{option} MemSetNames +Specify extra functions to flag that act similarly to `memset`. Specify +names in a semicolon-delimited list. Default is an empty string. +``` - Specify extra functions to flag that act similarly to ``memset``. Specify - names in a semicolon-delimited list. Default is an empty string. +```{option} MemCpyNames +Specify extra functions to flag that act similarly to `memcpy`. Specify +names in a semicolon-delimited list. Default is an empty string. +``` -.. option:: MemCpyNames - - Specify extra functions to flag that act similarly to ``memcpy``. Specify - names in a semicolon-delimited list. Default is an empty string. - -.. option:: MemCmpNames - - Specify extra functions to flag that act similarly to ``memcmp``. Specify - names in a semicolon-delimited list. Default is an empty string. +```{option} MemCmpNames +Specify extra functions to flag that act similarly to `memcmp`. Specify +names in a semicolon-delimited list. Default is an empty string. +``` This check corresponds to the CERT C++ Coding Standard rule -`OOP57-CPP. Prefer special member functions and overloaded operators to C -Standard Library functions -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/object-oriented-programming-oop/oop57-cpp/>`_. +[OOP57-CPP. Prefer special member functions and overloaded operators to C +Standard Library functions](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/object-oriented-programming-oop/oop57-cpp/). diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.rst index 7a321bd9c0f06..1361990d25a65 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.rst @@ -1,107 +1,106 @@ -.. title:: clang-tidy - bugprone-redundant-branch-condition +```{title} clang-tidy - bugprone-redundant-branch-condition +``` -bugprone-redundant-branch-condition -=================================== +# bugprone-redundant-branch-condition -Finds condition variables in nested ``if`` statements that were also checked in -the outer ``if`` statement and were not changed. +Finds condition variables in nested `if` statements that were also checked in +the outer `if` statement and were not changed. Simple example: -.. code-block:: c - - bool onFire = isBurning(); - if (onFire) { - if (onFire) - scream(); - } +```c +bool onFire = isBurning(); +if (onFire) { + if (onFire) + scream(); +} +``` -Here `onFire` is checked both in the outer ``if`` and the inner ``if`` +Here `onFire` is checked both in the outer `if` and the inner `if` statement without a possible change between the two checks. The check warns for -this code and suggests removal of the second checking of variable `onFire`. +this code and suggests removal of the second checking of variable +`onFire`. The checker also detects redundant condition checks if the condition variable -is an operand of a logical "and" (``&&``) or a logical "or" (``||``) operator: - -.. code-block:: c +is an operand of a logical "and" (`&&`) or a logical "or" (`||`) operator: - bool onFire = isBurning(); - if (onFire) { - if (onFire && peopleInTheBuilding > 0) - scream(); - } - -.. code-block:: c +```c +bool onFire = isBurning(); +if (onFire) { + if (onFire && peopleInTheBuilding > 0) + scream(); +} +``` - bool onFire = isBurning(); - if (onFire) { - if (onFire || isCollapsing()) - scream(); - } +```c +bool onFire = isBurning(); +if (onFire) { + if (onFire || isCollapsing()) + scream(); +} +``` In the first case (logical "and") the suggested fix is to remove the redundant -condition variable and keep the other side of the ``&&``. In the second case -(logical "or") the whole ``if`` is removed similarly to the simple case on the +condition variable and keep the other side of the `&&`. In the second case +(logical "or") the whole `if` is removed similarly to the simple case on the top. -The condition of the outer ``if`` statement may also be a logical "and" -(``&&``) expression: - -.. code-block:: c +The condition of the outer `if` statement may also be a logical "and" +(`&&`) expression: - bool onFire = isBurning(); - if (onFire && fireFighters < 10) { - if (someOtherCondition()) { - if (onFire) - scream(); - } +```c +bool onFire = isBurning(); +if (onFire && fireFighters < 10) { + if (someOtherCondition()) { + if (onFire) + scream(); } +} +``` The error is also detected if both the outer statement is a logical "and" -(``&&``) and the inner statement is a logical "and" (``&&``) or "or" (``||``). -The inner ``if`` statement does not have to be a direct descendant of the outer +(`&&`) and the inner statement is a logical "and" (`&&`) or "or" (`||`). +The inner `if` statement does not have to be a direct descendant of the outer one. No error is detected if the condition variable may have been changed between the two checks: -.. code-block:: c - - bool onFire = isBurning(); - if (onFire) { - tryToExtinguish(onFire); - if (onFire && peopleInTheBuilding > 0) - scream(); - } +```c +bool onFire = isBurning(); +if (onFire) { + tryToExtinguish(onFire); + if (onFire && peopleInTheBuilding > 0) + scream(); +} +``` Every possible change is considered, thus if the condition variable is not a local variable of the function, it is a volatile or it has an alias (pointer or reference) then no warning is issued. +## Limitations -Limitations ------------ - -The ``else`` branch is not checked currently for negated condition variable: +The `else` branch is not checked currently for negated condition variable: -.. code-block:: c - - bool onFire = isBurning(); - if (onFire) { - scream(); - } else { - if (!onFire) { - continueWork(); - } +```c +bool onFire = isBurning(); +if (onFire) { + scream(); +} else { + if (!onFire) { + continueWork(); } +} +``` The checker currently only detects redundant checking of single condition variables. More complex expressions are not checked: -.. code-block:: c - +```c +if (peopleInTheBuilding == 1) { if (peopleInTheBuilding == 1) { - if (peopleInTheBuilding == 1) { - doSomething(); - } + doSomething(); } +} +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.rst index f181659270a84..ddda4bafbba4b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.rst @@ -1,9 +1,10 @@ -.. title:: clang-tidy - bugprone-reserved-identifier +```{title} clang-tidy - bugprone-reserved-identifier +``` -bugprone-reserved-identifier -============================ +# bugprone-reserved-identifier -`cert-dcl37-c` and `cert-dcl51-cpp` redirect here as an alias for this check. +`cert-dcl37-c` and `cert-dcl51-cpp` redirect +here as an alias for this check. Checks for usages of identifiers reserved for use by the implementation. @@ -18,14 +19,14 @@ underscore occurring anywhere. Violating the naming rules above results in undefined behavior. -.. code-block:: c++ - - namespace NS { - void __f(); // name is not allowed in user code - using _Int = int; // same with this - #define cool__macro // also this - } - int _g(); // disallowed in global namespace only +```c++ +namespace NS { + void __f(); // name is not allowed in user code + using _Int = int; // same with this + #define cool__macro // also this +} +int _g(); // disallowed in global namespace only +``` The check can also be inverted, i.e. it can be configured to flag any identifier that is *not* a reserved identifier. This mode is for use by e.g. @@ -36,22 +37,19 @@ This check does not (yet) check for other reserved names, e.g. macro names identical to language keywords, and names specifically reserved by language standards, e.g. C++ 'zombie names' and C future library directions. -This check corresponds to CERT C Coding Standard rule `DCL37-C. Do not declare -or define a reserved identifier -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/declarations-and-initialization-dcl/dcl37-c/>`_ -as well as its C++ counterpart, `DCL51-CPP. Do not declare or define a reserved -identifier -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/declarations-and-initialization-dcl/dcl51-cpp/>`_. - -Options -------- - -.. option:: Invert +This check corresponds to CERT C Coding Standard rule [DCL37-C. Do not declare +or define a reserved identifier](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/declarations-and-initialization-dcl/dcl37-c/) +as well as its C++ counterpart, [DCL51-CPP. Do not declare or define a reserved +identifier](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/declarations-and-initialization-dcl/dcl51-cpp/). - If `true`, inverts the check, i.e. flags names that are not reserved. - Default is `false`. +## Options -.. option:: AllowedIdentifiers +```{option} Invert +If `true`, inverts the check, i.e. flags names that are not reserved. +Default is `false`. +``` - Semicolon-separated list of regular expressions that the check ignores. Default is an - empty list. +```{option} AllowedIdentifiers +Semicolon-separated list of regular expressions that the check ignores. Default is an +empty list. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst index 663e2149c7ac9..11d4540f9d6d4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-return-const-ref-from-parameter +```{title} clang-tidy - bugprone-return-const-ref-from-parameter +``` -bugprone-return-const-ref-from-parameter -======================================== +# bugprone-return-const-ref-from-parameter Detects return statements that return a constant reference parameter as constant reference. This may cause use-after-free errors if the caller @@ -12,40 +12,38 @@ destructed after the call. When the function returns such a parameter also as constant reference, then the returned reference can be used after the object it refers to has been destroyed. -Example -------- +## Example -.. code-block:: c++ +```c++ +struct S { + int v; + S(int); + ~S(); +}; - struct S { - int v; - S(int); - ~S(); - }; - - const S &fn(const S &a) { - return a; - } - - const S& s = fn(S{1}); - s.v; // use after free +const S &fn(const S &a) { + return a; +} +const S& s = fn(S{1}); +s.v; // use after free +``` This issue can be resolved by declaring an overload of the problematic function -where the ``const &`` parameter is instead declared as ``&&``. The developer has +where the `const &` parameter is instead declared as `&&`. The developer has to ensure that the implementation of that function does not produce a use-after-free, the exact error that this check is warning against. -Marking such an ``&&`` overload as ``deleted``, will silence the warning as -well. In the case of different ``const &`` parameters being returned depending +Marking such an `&&` overload as `deleted`, will silence the warning as +well. In the case of different `const &` parameters being returned depending on the control flow of the function, an overload where all problematic -``const &`` parameters have been declared as ``&&`` will resolve the issue. +`const &` parameters have been declared as `&&` will resolve the issue. -This issue can also be resolved by adding ``[[clang::lifetimebound]]``. Clang -enable ``-Wdangling`` warning by default which can detect mis-uses of the -annotated function. See `lifetimebound attribute <https://clang.llvm.org/docs/AttributeReference.html#lifetimebound>`_ +This issue can also be resolved by adding `[[clang::lifetimebound]]`. Clang +enable `-Wdangling` warning by default which can detect mis-uses of the +annotated function. See [lifetimebound attribute](https://clang.llvm.org/docs/AttributeReference.html#lifetimebound) for details. -.. code-block:: c++ - - const int &f(const int &a [[clang::lifetimebound]]) { return a; } // no warning - const int &v = f(1); // warning: temporary bound to local reference 'v' will be destroyed at the end of the full-expression [-Wdangling] +```c++ +const int &f(const int &a [[clang::lifetimebound]]) { return a; } // no warning +const int &v = f(1); // warning: temporary bound to local reference 'v' will be destroyed at the end of the full-expression [-Wdangling] +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.rst index 003be010f359b..dd0420c6499ef 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.rst @@ -1,36 +1,35 @@ -.. title:: clang-tidy - bugprone-shared-ptr-array-mismatch +```{title} clang-tidy - bugprone-shared-ptr-array-mismatch +``` -bugprone-shared-ptr-array-mismatch -================================== +# bugprone-shared-ptr-array-mismatch Finds initializations of C++ shared pointers to non-array type that are initialized with an array. -If a shared pointer ``std::shared_ptr<T>`` is initialized with a new-expression -``new T[]`` the memory is not deallocated correctly. The pointer uses plain -``delete`` in this case to deallocate the target memory. Instead a ``delete[]`` -call is needed. A ``std::shared_ptr<T[]>`` calls the correct delete operator. +If a shared pointer `std::shared_ptr<T>` is initialized with a new-expression +`new T[]` the memory is not deallocated correctly. The pointer uses plain +`delete` in this case to deallocate the target memory. Instead a `delete[]` +call is needed. A `std::shared_ptr<T[]>` calls the correct delete operator. -The check offers replacement of ``shared_ptr<T>`` to ``shared_ptr<T[]>`` if it +The check offers replacement of `shared_ptr<T>` to `shared_ptr<T[]>` if it is used at a single variable declaration (one variable in one statement). Example: -.. code-block:: c++ +```c++ +std::shared_ptr<Foo> x(new Foo[10]); // -> std::shared_ptr<Foo[]> x(new Foo[10]); +// ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] +std::shared_ptr<Foo> x1(new Foo), x2(new Foo[10]); // no replacement +// ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] - std::shared_ptr<Foo> x(new Foo[10]); // -> std::shared_ptr<Foo[]> x(new Foo[10]); - // ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] - std::shared_ptr<Foo> x1(new Foo), x2(new Foo[10]); // no replacement - // ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] - - std::shared_ptr<Foo> x3(new Foo[10], [](const Foo *ptr) { delete[] ptr; }); // no warning +std::shared_ptr<Foo> x3(new Foo[10], [](const Foo *ptr) { delete[] ptr; }); // no warning - struct S { - std::shared_ptr<Foo> x(new Foo[10]); // no replacement in this case - // ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] - }; +struct S { + std::shared_ptr<Foo> x(new Foo[10]); // no replacement in this case + // ^ warning: shared pointer to non-array is initialized with array [bugprone-shared-ptr-array-mismatch] +}; +``` This check partially covers the CERT C++ Coding Standard rule -`MEM51-CPP. Properly deallocate dynamically allocated resources -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/memory-management-mem/mem51-cpp/>`_ -However, only the ``std::shared_ptr`` case is detected by this check. +[MEM51-CPP. Properly deallocate dynamically allocated resources](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/memory-management-mem/mem51-cpp/) +However, only the `std::shared_ptr` case is detected by this check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst index f5648654023c0..b1e738cc8332a 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-signal-handler +```{title} clang-tidy - bugprone-signal-handler +``` -bugprone-signal-handler -======================= +# bugprone-signal-handler Finds specific constructs in signal handler functions that can cause undefined behavior. The rules for what is allowed differ between C++ language versions. @@ -30,68 +30,64 @@ Calls to user-defined functions with visible definitions are checked recursively. This check implements the CERT C Coding Standard rule -`SIG30-C. Call only asynchronous-safe functions within signal handlers -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/signals-sig/sig30-c/>`_ +[SIG30-C. Call only asynchronous-safe functions within signal handlers](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/signals-sig/sig30-c/) and the rule -`MSC54-CPP. A signal handler must be a plain old function -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/miscellaneous-msc/msc54-cpp/>`_. -It has the alias names ``cert-sig30-c`` and ``cert-msc54-cpp``. +[MSC54-CPP. A signal handler must be a plain old function](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/miscellaneous-msc/msc54-cpp/). +It has the alias names `cert-sig30-c` and `cert-msc54-cpp`. -Options -------- +## Options -.. option:: AsyncSafeFunctionSet +```{option} AsyncSafeFunctionSet +Selects which set of functions is considered as asynchronous-safe +(and therefore allowed in signal handlers). It can be set to the following values: - Selects which set of functions is considered as asynchronous-safe - (and therefore allowed in signal handlers). It can be set to the following values: +- `minimal` + : Selects a minimal set that is defined in the CERT SIG30-C rule. + and includes functions `abort()`, `_Exit()`, `quick_exit()` and + `signal()`. +- `POSIX` + : Selects a larger set of functions that is listed in POSIX.1-2017 (see [this + link](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03) + for more information). The following functions are included: + `_Exit`, `_exit`, `abort`, `accept`, `access`, `aio_error`, + `aio_return`, `aio_suspend`, `alarm`, `bind`, `cfgetispeed`, + `cfgetospeed`, `cfsetispeed`, `cfsetospeed`, `chdir`, `chmod`, + `chown`, `clock_gettime`, `close`, `connect`, `creat`, `dup`, + `dup2`, `execl`, `execle`, `execv`, `execve`, `faccessat`, + `fchdir`, `fchmod`, `fchmodat`, `fchown`, `fchownat`, `fcntl`, + `fdatasync`, `fexecve`, `ffs`, `fork`, `fstat`, `fstatat`, + `fsync`, `ftruncate`, `futimens`, `getegid`, `geteuid`, + `getgid`, `getgroups`, `getpeername`, `getpgrp`, `getpid`, + `getppid`, `getsockname`, `getsockopt`, `getuid`, `htonl`, + `htons`, `kill`, `link`, `linkat`, `listen`, `longjmp`, + `lseek`, `lstat`, `memccpy`, `memchr`, `memcmp`, `memcpy`, + `memmove`, `memset`, `mkdir`, `mkdirat`, `mkfifo`, `mkfifoat`, + `mknod`, `mknodat`, `ntohl`, `ntohs`, `open`, `openat`, + `pause`, `pipe`, `poll`, `posix_trace_event`, `pselect`, + `pthread_kill`, `pthread_self`, `pthread_sigmask`, `quick_exit`, + `raise`, `read`, `readlink`, `readlinkat`, `recv`, `recvfrom`, + `recvmsg`, `rename`, `renameat`, `rmdir`, `select`, `sem_post`, + `send`, `sendmsg`, `sendto`, `setgid`, `setpgid`, `setsid`, + `setsockopt`, `setuid`, `shutdown`, `sigaction`, `sigaddset`, + `sigdelset`, `sigemptyset`, `sigfillset`, `sigismember`, + `siglongjmp`, `signal`, `sigpause`, `sigpending`, `sigprocmask`, + `sigqueue`, `sigset`, `sigsuspend`, `sleep`, `sockatmark`, + `socket`, `socketpair`, `stat`, `stpcpy`, `stpncpy`, + `strcat`, `strchr`, `strcmp`, `strcpy`, `strcspn`, `strlen`, + `strncat`, `strncmp`, `strncpy`, `strnlen`, `strpbrk`, + `strrchr`, `strspn`, `strstr`, `strtok_r`, `symlink`, + `symlinkat`, `tcdrain`, `tcflow`, `tcflush`, `tcgetattr`, + `tcgetpgrp`, `tcsendbreak`, `tcsetattr`, `tcsetpgrp`, + `time`, `timer_getoverrun`, `timer_gettime`, `timer_settime`, + `times`, `umask`, `uname`, `unlink`, `unlinkat`, `utime`, + `utimensat`, `utimes`, `wait`, `waitpid`, `wcpcpy`, + `wcpncpy`, `wcscat`, `wcschr`, `wcscmp`, `wcscpy`, `wcscspn`, + `wcslen`, `wcsncat`, `wcsncmp`, `wcsncpy`, `wcsnlen`, `wcspbrk`, + `wcsrchr`, `wcsspn`, `wcsstr`, `wcstok`, `wmemchr`, `wmemcmp`, + `wmemcpy`, `wmemmove`, `wmemset`, `write` - - `minimal` - Selects a minimal set that is defined in the CERT SIG30-C rule. - and includes functions ``abort()``, ``_Exit()``, ``quick_exit()`` and - ``signal()``. - - `POSIX` - Selects a larger set of functions that is listed in POSIX.1-2017 (see `this - link - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03>`_ - for more information). The following functions are included: - ``_Exit``, ``_exit``, ``abort``, ``accept``, ``access``, ``aio_error``, - ``aio_return``, ``aio_suspend``, ``alarm``, ``bind``, ``cfgetispeed``, - ``cfgetospeed``, ``cfsetispeed``, ``cfsetospeed``, ``chdir``, ``chmod``, - ``chown``, ``clock_gettime``, ``close``, ``connect``, ``creat``, ``dup``, - ``dup2``, ``execl``, ``execle``, ``execv``, ``execve``, ``faccessat``, - ``fchdir``, ``fchmod``, ``fchmodat``, ``fchown``, ``fchownat``, ``fcntl``, - ``fdatasync``, ``fexecve``, ``ffs``, ``fork``, ``fstat``, ``fstatat``, - ``fsync``, ``ftruncate``, ``futimens``, ``getegid``, ``geteuid``, - ``getgid``, ``getgroups``, ``getpeername``, ``getpgrp``, ``getpid``, - ``getppid``, ``getsockname``, ``getsockopt``, ``getuid``, ``htonl``, - ``htons``, ``kill``, ``link``, ``linkat``, ``listen``, ``longjmp``, - ``lseek``, ``lstat``, ``memccpy``, ``memchr``, ``memcmp``, ``memcpy``, - ``memmove``, ``memset``, ``mkdir``, ``mkdirat``, ``mkfifo``, ``mkfifoat``, - ``mknod``, ``mknodat``, ``ntohl``, ``ntohs``, ``open``, ``openat``, - ``pause``, ``pipe``, ``poll``, ``posix_trace_event``, ``pselect``, - ``pthread_kill``, ``pthread_self``, ``pthread_sigmask``, ``quick_exit``, - ``raise``, ``read``, ``readlink``, ``readlinkat``, ``recv``, ``recvfrom``, - ``recvmsg``, ``rename``, ``renameat``, ``rmdir``, ``select``, ``sem_post``, - ``send``, ``sendmsg``, ``sendto``, ``setgid``, ``setpgid``, ``setsid``, - ``setsockopt``, ``setuid``, ``shutdown``, ``sigaction``, ``sigaddset``, - ``sigdelset``, ``sigemptyset``, ``sigfillset``, ``sigismember``, - ``siglongjmp``, ``signal``, ``sigpause``, ``sigpending``, ``sigprocmask``, - ``sigqueue``, ``sigset``, ``sigsuspend``, ``sleep``, ``sockatmark``, - ``socket``, ``socketpair``, ``stat``, ``stpcpy``, ``stpncpy``, - ``strcat``, ``strchr``, ``strcmp``, ``strcpy``, ``strcspn``, ``strlen``, - ``strncat``, ``strncmp``, ``strncpy``, ``strnlen``, ``strpbrk``, - ``strrchr``, ``strspn``, ``strstr``, ``strtok_r``, ``symlink``, - ``symlinkat``, ``tcdrain``, ``tcflow``, ``tcflush``, ``tcgetattr``, - ``tcgetpgrp``, ``tcsendbreak``, ``tcsetattr``, ``tcsetpgrp``, - ``time``, ``timer_getoverrun``, ``timer_gettime``, ``timer_settime``, - ``times``, ``umask``, ``uname``, ``unlink``, ``unlinkat``, ``utime``, - ``utimensat``, ``utimes``, ``wait``, ``waitpid``, ``wcpcpy``, - ``wcpncpy``, ``wcscat``, ``wcschr``, ``wcscmp``, ``wcscpy``, ``wcscspn``, - ``wcslen``, ``wcsncat``, ``wcsncmp``, ``wcsncpy``, ``wcsnlen``, ``wcspbrk``, - ``wcsrchr``, ``wcsspn``, ``wcsstr``, ``wcstok``, ``wmemchr``, ``wmemcmp``, - ``wmemcpy``, ``wmemmove``, ``wmemset``, ``write`` + The function `quick_exit` is not included in the POSIX list but it + is included here in the set of safe functions. - The function ``quick_exit`` is not included in the POSIX list but it - is included here in the set of safe functions. - - The default value is `POSIX`. +The default value is `POSIX`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.rst index 2a728d1093f6f..ee42351cebcc1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.rst @@ -1,125 +1,124 @@ -.. title:: clang-tidy - bugprone-signed-char-misuse +```{title} clang-tidy - bugprone-signed-char-misuse +``` -bugprone-signed-char-misuse -=========================== +# bugprone-signed-char-misuse -`cert-str34-c` redirects here as an alias for this check. For the CERT alias, -the `DiagnoseSignedUnsignedCharComparisons` option is set to `false`. +`cert-str34-c` redirects here as an alias for this check. For +the CERT alias, the `DiagnoseSignedUnsignedCharComparisons` +option is set to `false`. -Finds those ``signed char`` -> integer conversions which might indicate a -programming error. The basic problem with the ``signed char``, that it might +Finds those `signed char` -> integer conversions which might indicate a +programming error. The basic problem with the `signed char`, that it might store the non-ASCII characters as negative values. This behavior can cause a misunderstanding of the written code both when an explicit and when an implicit conversion happens. -When the code contains an explicit ``signed char`` -> integer conversion, the +When the code contains an explicit `signed char` -> integer conversion, the human programmer probably expects that the converted value matches with the character code (a value from [0..255]), however, the actual value is in [-128..127] interval. To avoid this kind of misinterpretation, the desired way -of converting from a ``signed char`` to an integer value is converting to -``unsigned char`` first, which stores all the characters in the positive +of converting from a `signed char` to an integer value is converting to +`unsigned char` first, which stores all the characters in the positive [0..255] interval which matches the known character codes. In case of implicit conversion, the programmer might not actually be aware that a conversion happened and char value is used as an integer. There are some use cases when this unawareness might lead to a functionally imperfect -code. For example, checking the equality of a ``signed char`` and an -``unsigned char`` variable is something we should avoid in C++ code. During +code. For example, checking the equality of a `signed char` and an +`unsigned char` variable is something we should avoid in C++ code. During this comparison, the two variables are converted to integers which have -different value ranges. For ``signed char``, the non-ASCII characters are +different value ranges. For `signed char`, the non-ASCII characters are stored as a value in [-128..-1] interval, while the same characters are -stored in the [128..255] interval for an ``unsigned char``. +stored in the [128..255] interval for an `unsigned char`. -It depends on the actual platform whether plain ``char`` is handled as -``signed char`` by default and so it is caught by this check or not. -To change the default behavior you can use ``-funsigned-char`` and -``-fsigned-char`` compilation options. +It depends on the actual platform whether plain `char` is handled as +`signed char` by default and so it is caught by this check or not. +To change the default behavior you can use `-funsigned-char` and +`-fsigned-char` compilation options. Currently, this check warns in the following cases: -- ``signed char`` is assigned to an integer variable -- ``signed char`` and ``unsigned char`` are compared with +- `signed char` is assigned to an integer variable +- `signed char` and `unsigned char` are compared with equality/inequality operator -- ``signed char`` is converted to an integer in the array subscript +- `signed char` is converted to an integer in the array subscript See also: -`STR34-C. Cast characters to unsigned char before converting to larger -integer sizes -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/characters-and-strings-str/str34-c/>`_ +[STR34-C. Cast characters to unsigned char before converting to larger +integer sizes](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/characters-and-strings-str/str34-c/) -A good example from the CERT description when a ``char`` variable is used to +A good example from the CERT description when a `char` variable is used to read from a file that might contain non-ASCII characters. The problem comes -up when the code uses the ``-1`` integer value as EOF, while the 255 character -code is also stored as ``-1`` in two's complement form of char type. +up when the code uses the `-1` integer value as EOF, while the 255 character +code is also stored as `-1` in two's complement form of char type. See a simple example of this below. This code stops not only when it reaches the end of the file, but also when it gets a character with the 255 code. -.. code-block:: c++ +```c++ +#define EOF (-1) - #define EOF (-1) +int read(void) { + char CChar; + int IChar = EOF; - int read(void) { - char CChar; - int IChar = EOF; - - if (readChar(CChar)) { - IChar = CChar; - } - return IChar; + if (readChar(CChar)) { + IChar = CChar; } + return IChar; +} +``` -A proper way to fix the code above is converting the ``char`` variable to -an ``unsigned char`` value first. - -.. code-block:: c++ +A proper way to fix the code above is converting the `char` variable to +an `unsigned char` value first. - #define EOF (-1) +```c++ +#define EOF (-1) - int read(void) { - char CChar; - int IChar = EOF; +int read(void) { + char CChar; + int IChar = EOF; - if (readChar(CChar)) { - IChar = static_cast<unsigned char>(CChar); - } - return IChar; + if (readChar(CChar)) { + IChar = static_cast<unsigned char>(CChar); } + return IChar; +} +``` -Another use case is checking the equality of two ``char`` variables with +Another use case is checking the equality of two `char` variables with different signedness. Inside the non-ASCII value range this comparison between -a ``signed char`` and an ``unsigned char`` always returns ``false``. - -.. code-block:: c++ +a `signed char` and an `unsigned char` always returns `false`. - bool compare(signed char SChar, unsigned char USChar) { - if (SChar == USChar) - return true; - return false; - } +```c++ +bool compare(signed char SChar, unsigned char USChar) { + if (SChar == USChar) + return true; + return false; +} +``` The easiest way to fix this kind of comparison is casting one of the arguments, so both arguments will have the same type. -.. code-block:: c++ - - bool compare(signed char SChar, unsigned char USChar) { - if (static_cast<unsigned char>(SChar) == USChar) - return true; - return false; - } - -Options -------- - -.. option:: CharTypedefsToIgnore - - A semicolon-separated list of typedef names. In this list, we can list - typedefs for ``char`` or ``signed char``, which will be ignored by the - check. This is useful when a typedef introduces an integer alias like - ``sal_Int8`` or ``int8_t``. In this case, human misinterpretation is not - an issue. Default is an empty string. - -.. option:: DiagnoseSignedUnsignedCharComparisons - - When `true`, the check will warn on ``signed char``/``unsigned char`` comparisons, - otherwise these comparisons are ignored. By default, this option is set to `true`. +```c++ +bool compare(signed char SChar, unsigned char USChar) { + if (static_cast<unsigned char>(SChar) == USChar) + return true; + return false; +} +``` + +## Options + +```{option} CharTypedefsToIgnore +A semicolon-separated list of typedef names. In this list, we can list +typedefs for `char` or `signed char`, which will be ignored by the +check. This is useful when a typedef introduces an integer alias like +`sal_Int8` or `int8_t`. In this case, human misinterpretation is not +an issue. Default is an empty string. +``` + +```{option} DiagnoseSignedUnsignedCharComparisons +When `true`, the check will warn on `signed char`/`unsigned char` comparisons, +otherwise these comparisons are ignored. By default, this option is set to `true`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst index 4ed7cdc8cab4b..c1bbadd64f59b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst @@ -1,328 +1,312 @@ -.. title:: clang-tidy - bugprone-sizeof-expression +```{title} clang-tidy - bugprone-sizeof-expression +``` -bugprone-sizeof-expression -========================== +# bugprone-sizeof-expression -The check finds usages of ``sizeof`` expressions which are most likely errors. +The check finds usages of `sizeof` expressions which are most likely errors. -The ``sizeof`` operator yields the size (in bytes) of its operand, which may be +The `sizeof` operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. Misuse of this operator may be leading to errors and possible software vulnerabilities. -Suspicious usage of 'sizeof(K)' -------------------------------- +## Suspicious usage of 'sizeof(K)' -A common mistake is to query the ``sizeof`` of an integer literal. This is -equivalent to query the size of its type (probably ``int``). The intent of the +A common mistake is to query the `sizeof` of an integer literal. This is +equivalent to query the size of its type (probably `int`). The intent of the programmer was probably to simply get the integer and not its size. -.. code-block:: c++ +```c++ +#define BUFLEN 42 +char buf[BUFLEN]; +memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) +``` - #define BUFLEN 42 - char buf[BUFLEN]; - memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) - -Suspicious usage of 'sizeof(expr)' ----------------------------------- +## Suspicious usage of 'sizeof(expr)' In cases, where there is an enum or integer to represent a type, a common -mistake is to query the ``sizeof`` on the integer or enum that represents the -type that should be used by ``sizeof``. This results in the size of the integer +mistake is to query the `sizeof` on the integer or enum that represents the +type that should be used by `sizeof`. This results in the size of the integer and not of the type the integer represents: -.. code-block:: c++ - - enum data_type { - FLOAT_TYPE, - DOUBLE_TYPE - }; - - struct data { - data_type type; - void* buffer; - data_type get_type() { - return type; - } - }; - - void f(data d, int numElements) { - // should be sizeof(float) or sizeof(double), depending on d.get_type() - int numBytes = numElements * sizeof(d.get_type()); - ... +```c++ +enum data_type { + FLOAT_TYPE, + DOUBLE_TYPE +}; + +struct data { + data_type type; + void* buffer; + data_type get_type() { + return type; } +}; +void f(data d, int numElements) { + // should be sizeof(float) or sizeof(double), depending on d.get_type() + int numBytes = numElements * sizeof(d.get_type()); + ... +} +``` -Suspicious usage of 'sizeof(this)' ----------------------------------- +## Suspicious usage of 'sizeof(this)' -The ``this`` keyword is evaluated to a pointer to an object of a given type. -The expression ``sizeof(this)`` is returning the size of a pointer. The +The `this` keyword is evaluated to a pointer to an object of a given type. +The expression `sizeof(this)` is returning the size of a pointer. The programmer most likely wanted the size of the object and not the size of the pointer. -.. code-block:: c++ - - class Point { - [...] - size_t size() { return sizeof(this); } // should probably be sizeof(*this) - [...] - }; +```c++ +class Point { + [...] + size_t size() { return sizeof(this); } // should probably be sizeof(*this) + [...] +}; +``` -Suspicious usage of 'sizeof(char*)' ------------------------------------ +## Suspicious usage of 'sizeof(char\*)' There is a subtle difference between declaring a string literal with -``char* A = ""`` and ``char A[] = ""``. The first case has the type ``char*`` -instead of the aggregate type ``char[]``. Using ``sizeof`` on an object -declared with ``char*`` type is returning the size of a pointer instead of +`char* A = ""` and `char A[] = ""`. The first case has the type `char*` +instead of the aggregate type `char[]`. Using `sizeof` on an object +declared with `char*` type is returning the size of a pointer instead of the number of characters (bytes) in the string literal. -.. code-block:: c++ +```c++ +const char* kMessage = "Hello World!"; // const char kMessage[] = "..."; +void getMessage(char* buf) { + memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*) +} +``` - const char* kMessage = "Hello World!"; // const char kMessage[] = "..."; - void getMessage(char* buf) { - memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*) - } - -Suspicious usage of 'sizeof(A*)' --------------------------------- +## Suspicious usage of 'sizeof(A\*)' A common mistake is to compute the size of a pointer instead of its pointee. These cases may occur because of explicit cast or implicit conversion. -.. code-block:: c++ - - int A[10]; - memset(A, 0, sizeof(A + 0)); +```c++ +int A[10]; +memset(A, 0, sizeof(A + 0)); - struct Point point; - memset(point, 0, sizeof(&point)); +struct Point point; +memset(point, 0, sizeof(&point)); +``` -Suspicious usage of 'sizeof(...)/sizeof(...)' ---------------------------------------------- +## Suspicious usage of 'sizeof(...)/sizeof(...)' -Dividing ``sizeof`` expressions is typically used to retrieve the number of +Dividing `sizeof` expressions is typically used to retrieve the number of elements of an aggregate. This check warns on incompatible or suspicious cases. In the following example, the entity has 10-bytes and is incompatible with the -type ``int`` which has 4 bytes. - -.. code-block:: c++ - - char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10 - void getMessage(char* dst) { - memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes] - } - -In the following example, the expression ``sizeof(Values)`` is returning the -size of ``char*``. One can easily be fooled by its declaration, but in parameter -declaration the size '10' is ignored and the function is receiving a ``char*``. - -.. code-block:: c++ - - char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - return CompareArray(char Values[10]) { - return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*] - } - -Suspicious 'sizeof' by 'sizeof' expression ------------------------------------------- - -Multiplying ``sizeof`` expressions typically makes no sense and is probably a -logic error. In the following example, the programmer used ``*`` instead of -``/``. - -.. code-block:: c++ - - const char kMessage[] = "Hello World!"; - void getMessage(char* buf) { - memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char) - } +type `int` which has 4 bytes. + +```c++ +char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10 +void getMessage(char* dst) { + memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes] +} +``` + +In the following example, the expression `sizeof(Values)` is returning the +size of `char*`. One can easily be fooled by its declaration, but in parameter +declaration the size '10' is ignored and the function is receiving a `char*`. + +```c++ +char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +return CompareArray(char Values[10]) { + return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*] +} +``` + +## Suspicious 'sizeof' by 'sizeof' expression + +Multiplying `sizeof` expressions typically makes no sense and is probably a +logic error. In the following example, the programmer used `*` instead of +`/`. + +```c++ +const char kMessage[] = "Hello World!"; +void getMessage(char* buf) { + memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char) +} +``` This check may trigger on code using the arraysize macro. The following code is -working correctly but should be simplified by using only the ``sizeof`` +working correctly but should be simplified by using only the `sizeof` operator. -.. code-block:: c++ - - extern Object objects[100]; - void InitializeObjects() { - memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects) - } +```c++ +extern Object objects[100]; +void InitializeObjects() { + memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects) +} +``` -Suspicious usage of 'sizeof(sizeof(...))' ------------------------------------------ +## Suspicious usage of 'sizeof(sizeof(...))' -Getting the ``sizeof`` of a ``sizeof`` makes no sense and is typically an error +Getting the `sizeof` of a `sizeof` makes no sense and is typically an error hidden through macros. -.. code-block:: c++ +```c++ +#define INT_SZ sizeof(int) +int buf[] = { 42 }; +void getInt(int* dst) { + memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious. +} +``` - #define INT_SZ sizeof(int) - int buf[] = { 42 }; - void getInt(int* dst) { - memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious. - } - -Suspicious usages of 'sizeof(...)' in pointer arithmetic --------------------------------------------------------- +## Suspicious usages of 'sizeof(...)' in pointer arithmetic Arithmetic operators on pointers automatically scale the result with the size of the pointed typed. -Further use of ``sizeof`` around pointer arithmetic will typically result in an +Further use of `sizeof` around pointer arithmetic will typically result in an unintended result. -Scaling the result of pointer difference -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +### Scaling the result of pointer difference Subtracting two pointers results in an integer expression (of type -``ptrdiff_t``) which expresses the distance between the two pointed objects in +`ptrdiff_t`) which expresses the distance between the two pointed objects in "number of objects between". A common mistake is to think that the result is "number of bytes between", and -scale the difference with ``sizeof``, such as ``P1 - P2 == N * sizeof(T)`` -(instead of ``P1 - P2 == N``) or ``(P1 - P2) / sizeof(T)`` instead of -``P1 - P2``. - -.. code-block:: c++ - - void splitFour(const Obj* Objs, size_t N, Obj Delimiter) { - const Obj *P = Objs; - while (P < Objs + N) { - if (*P == Delimiter) { - break; - } - } - - if (P - Objs != 4 * sizeof(Obj)) { // Expecting a distance multiplied by sizeof is suspicious. - error(); +scale the difference with `sizeof`, such as `P1 - P2 == N * sizeof(T)` +(instead of `P1 - P2 == N`) or `(P1 - P2) / sizeof(T)` instead of +`P1 - P2`. + +```c++ +void splitFour(const Obj* Objs, size_t N, Obj Delimiter) { + const Obj *P = Objs; + while (P < Objs + N) { + if (*P == Delimiter) { + break; } } -.. code-block:: c++ + if (P - Objs != 4 * sizeof(Obj)) { // Expecting a distance multiplied by sizeof is suspicious. + error(); + } +} +``` - void iterateIfEvenLength(int *Begin, int *End) { - auto N = (Begin - End) / sizeof(int); // Dividing by sizeof() is suspicious. - if (N % 2) - return; +```c++ +void iterateIfEvenLength(int *Begin, int *End) { + auto N = (Begin - End) / sizeof(int); // Dividing by sizeof() is suspicious. + if (N % 2) + return; - // ... - } + // ... +} +``` -Stepping a pointer with a scaled integer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +### Stepping a pointer with a scaled integer Conversely, when performing pointer arithmetics to add or subtract from a pointer, the arithmetic operator implicitly scales the value actually added to -the pointer with the size of the pointee, as ``Ptr + N`` expects ``N`` to be +the pointer with the size of the pointee, as `Ptr + N` expects `N` to be "number of objects to step", and not "number of bytes to step". -Seeing the calculation of a pointer where ``sizeof`` appears is suspicious, +Seeing the calculation of a pointer where `sizeof` appears is suspicious, and the result is typically unintended, often out of bounds. -``Ptr + sizeof(T)`` will offset the pointer by ``sizeof(T)`` elements, +`Ptr + sizeof(T)` will offset the pointer by `sizeof(T)` elements, effectively exponentiating the scaling factor to the power of 2. -Similarly, multiplying or dividing a numeric value with the ``sizeof`` of an +Similarly, multiplying or dividing a numeric value with the `sizeof` of an element or the whole buffer is suspicious, because the dimensional connection -between the numeric value and the actual ``sizeof`` result can not always be +between the numeric value and the actual `sizeof` result can not always be deduced. -While scaling an integer up (multiplying) with ``sizeof`` is likely **always** +While scaling an integer up (multiplying) with `sizeof` is likely **always** an issue, a scaling down (division) is not always inherently dangerous, in case the developer is aware that the division happens between an appropriate number -of _bytes_ and a ``sizeof`` value. -Turning :option:`WarnOnOffsetDividedBySizeOf` off will restrict the +of \_bytes\_ and a `sizeof` value. +Turning {option}`WarnOnOffsetDividedBySizeOf` off will restrict the warnings to the multiplication case. -This case also checks suspicious ``alignof`` and ``offsetof`` usages in +This case also checks suspicious `alignof` and `offsetof` usages in pointer arithmetic, as both return the "size" in bytes and not elements, potentially resulting in doubly-scaled offsets. -.. code-block:: c++ - - void printEveryEvenIndexElement(int *Array, size_t N) { - int *P = Array; - while (P <= Array + N * sizeof(int)) { // Suspicious pointer arithmetic using sizeof()! - printf("%d ", *P); +```c++ +void printEveryEvenIndexElement(int *Array, size_t N) { + int *P = Array; + while (P <= Array + N * sizeof(int)) { // Suspicious pointer arithmetic using sizeof()! + printf("%d ", *P); - P += 2 * sizeof(int); // Suspicious pointer arithmetic using sizeof()! - } + P += 2 * sizeof(int); // Suspicious pointer arithmetic using sizeof()! } - -.. code-block:: c++ - - struct Message { /* ... */; char Flags[8]; }; - void clearFlags(Message *Array, size_t N) { - const Message *End = Array + N; - while (Array < End) { - memset(Array + offsetof(Message, Flags), // Suspicious pointer arithmetic using offsetof()! - 0, sizeof(Message::Flags)); - ++Array; - } +} +``` + +```c++ +struct Message { /* ... */; char Flags[8]; }; +void clearFlags(Message *Array, size_t N) { + const Message *End = Array + N; + while (Array < End) { + memset(Array + offsetof(Message, Flags), // Suspicious pointer arithmetic using offsetof()! + 0, sizeof(Message::Flags)); + ++Array; } +} +``` For this checked bogus pattern, `cert-arr39-c` redirects here as an alias of this check. This check corresponds to the CERT C Coding Standard rule -`ARR39-C. Do not add or subtract a scaled integer to a pointer -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/arrays-arr/arr39-c/>`_. - +[ARR39-C. Do not add or subtract a scaled integer to a pointer](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/arrays-arr/arr39-c/). -Limitations ------------ +## Limitations Cases where the pointee type has a size of `1` byte (such as, and most -importantly, ``char``) are excluded. - -Options -------- - -.. option:: WarnOnSizeOfConstant - - When `true`, the check will warn on an expression like - ``sizeof(CONSTANT)``. Default is `true`. - -.. option:: WarnOnSizeOfIntegerExpression - - When `true`, the check will warn on an expression like ``sizeof(expr)`` - where the expression results in an integer. Default is `false`. - -.. option:: WarnOnSizeOfThis - - When `true`, the check will warn on an expression like ``sizeof(this)``. - Default is `true`. - -.. option:: WarnOnSizeOfCompareToConstant - - When `true`, the check will warn on an expression like - ``sizeof(expr) <= k`` for a suspicious constant `k` while `k` is `0` or - greater than `0x8000`. Default is `true`. - -.. option:: WarnOnSizeOfPointerToAggregate - - When `true`, the check will warn when the argument of ``sizeof`` is either a - pointer-to-aggregate type, an expression returning a pointer-to-aggregate - value or an expression that returns a pointer from an array-to-pointer - conversion (that may be implicit or explicit, for example ``array + 2`` or - ``(int *)array``). Default is `true`. - -.. option:: WarnOnSizeOfPointer - - When `true`, the check will report all expressions where the argument of - ``sizeof`` is an expression that produces a pointer (except for a few - idiomatic expressions that are probably intentional and correct). - This detects occurrences of CWE 467. Default is `false`. - -.. option:: WarnOnOffsetDividedBySizeOf - - When `true`, the check will warn on pointer arithmetic where the - element count is obtained from a division with ``sizeof(...)``, - e.g., ``Ptr + Bytes / sizeof(*T)``. Default is `true`. - -.. option:: WarnOnSizeOfInLoopTermination - - When `true`, the check will warn about incorrect use of sizeof expression - in loop termination condition. The warning triggers if the ``sizeof`` - expression appears to be incorrectly used to determine the number of - array/buffer elements. - e.g, ``long arr[10]; for(int i = 0; i < sizeof(arr); i++) { ... }``. Default - is `true`. +importantly, `char`) are excluded. + +## Options + +```{option} WarnOnSizeOfConstant +When `true`, the check will warn on an expression like +`sizeof(CONSTANT)`. Default is `true`. +``` + +```{option} WarnOnSizeOfIntegerExpression +When `true`, the check will warn on an expression like `sizeof(expr)` +where the expression results in an integer. Default is `false`. +``` + +```{option} WarnOnSizeOfThis +When `true`, the check will warn on an expression like `sizeof(this)`. +Default is `true`. +``` + +```{option} WarnOnSizeOfCompareToConstant +When `true`, the check will warn on an expression like +`sizeof(expr) <= k` for a suspicious constant `k` while `k` is `0` or +greater than `0x8000`. Default is `true`. +``` + +```{option} WarnOnSizeOfPointerToAggregate +When `true`, the check will warn when the argument of `sizeof` is either a +pointer-to-aggregate type, an expression returning a pointer-to-aggregate +value or an expression that returns a pointer from an array-to-pointer +conversion (that may be implicit or explicit, for example `array + 2` or +`(int *)array`). Default is `true`. +``` + +```{option} WarnOnSizeOfPointer +When `true`, the check will report all expressions where the argument of +`sizeof` is an expression that produces a pointer (except for a few +idiomatic expressions that are probably intentional and correct). +This detects occurrences of CWE 467. Default is `false`. +``` + +```{option} WarnOnOffsetDividedBySizeOf +When `true`, the check will warn on pointer arithmetic where the +element count is obtained from a division with `sizeof(...)`, +e.g., `Ptr + Bytes / sizeof(*T)`. Default is `true`. +``` + +```{option} WarnOnSizeOfInLoopTermination +When `true`, the check will warn about incorrect use of sizeof expression +in loop termination condition. The warning triggers if the `sizeof` +expression appears to be incorrectly used to determine the number of +array/buffer elements. +e.g, `long arr[10]; for(int i = 0; i < sizeof(arr); i++) { ... }`. Default +is `true`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.rst index 8fdf2fcc6821f..4f1b4c2de0a6e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.rst @@ -1,39 +1,37 @@ -.. title:: clang-tidy - bugprone-standalone-empty +```{title} clang-tidy - bugprone-standalone-empty +``` -bugprone-standalone-empty -========================= +# bugprone-standalone-empty -Warns when ``empty()`` is used on a range and the result is ignored. Suggests -``clear()`` if it is an existing member function. +Warns when `empty()` is used on a range and the result is ignored. Suggests +`clear()` if it is an existing member function. -The ``empty()`` method on several common ranges returns a Boolean indicating +The `empty()` method on several common ranges returns a Boolean indicating whether or not the range is empty, but is often mistakenly interpreted as -a way to clear the contents of a range. Some ranges offer a ``clear()`` +a way to clear the contents of a range. Some ranges offer a `clear()` method for this purpose. This check warns when a call to empty returns a -result that is ignored, and suggests replacing it with a call to ``clear()`` +result that is ignored, and suggests replacing it with a call to `clear()` if it is available as a member function of the range. For example, the following code could be used to indicate whether a range is empty or not, but the result is ignored: -.. code-block:: c++ +```c++ +std::vector<int> v; +... +v.empty(); +``` - std::vector<int> v; - ... - v.empty(); +A call to `clear()` would appropriately clear the contents of the range: -A call to ``clear()`` would appropriately clear the contents of the range: +```c++ +std::vector<int> v; +... +v.clear(); +``` -.. code-block:: c++ +## Limitations - std::vector<int> v; - ... - v.clear(); - - -Limitations ------------ - -* Doesn't warn if ``empty()`` is defined and used with the ignore result in the +- Doesn't warn if `empty()` is defined and used with the ignore result in the class template definition (for example in the library implementation). These - error cases can be caught with ``[[nodiscard]]`` attribute. + error cases can be caught with `[[nodiscard]]` attribute. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.rst index 41b14537eb36f..51401ab4d9f98 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.rst @@ -1,32 +1,32 @@ -.. title:: clang-tidy - bugprone-std-exception-baseclass +```{title} clang-tidy - bugprone-std-exception-baseclass +``` -bugprone-std-exception-baseclass -================================ +# bugprone-std-exception-baseclass -Ensure that every value that in a ``throw`` expression is an instance of -``std::exception``. +Ensure that every value that in a `throw` expression is an instance of +`std::exception`. -Deriving all exceptions from ``std::exception`` allows callers to catch +Deriving all exceptions from `std::exception` allows callers to catch all exceptions with a single catch block and provides access to the -``what()`` method for diagnostics. Throwing arbitrary types creates +`what()` method for diagnostics. Throwing arbitrary types creates hidden contracts, reduces interoperability with the standard library, and may result in program termination. -.. code-block:: c++ +```c++ +class custom_exception {}; - class custom_exception {}; +void throwing() noexcept(false) { + // Problematic throw expressions. + throw int(42); + throw custom_exception(); +} - void throwing() noexcept(false) { - // Problematic throw expressions. - throw int(42); - throw custom_exception(); - } +class mathematical_error : public std::exception {}; - class mathematical_error : public std::exception {}; - - void throwing2() noexcept(false) { - // These kind of throws are ok. - throw mathematical_error(); - throw std::runtime_error(); - throw std::exception(); - } +void throwing2() noexcept(false) { + // These kind of throws are ok. + throw mathematical_error(); + throw std::runtime_error(); + throw std::exception(); +} +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst index 29e128e3b1f20..92d429594e734 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.rst @@ -1,17 +1,17 @@ -.. title:: clang-tidy - bugprone-std-namespace-modification +```{title} clang-tidy - bugprone-std-namespace-modification +``` -bugprone-std-namespace-modification -=================================== +# bugprone-std-namespace-modification -Warns on modifications of the ``std`` or ``posix`` namespaces which can +Warns on modifications of the `std` or `posix` namespaces which can result in undefined behavior. -The ``std`` (or ``posix``) namespace is allowed to be extended with (class or +The `std` (or `posix`) namespace is allowed to be extended with (class or function) template specializations that depend on an user-defined type (a type that is not defined in the standard system headers). The check detects the following (user provided) declarations in namespace -``std`` or ``posix``: +`std` or `posix`: - Anything that is not a template specialization. - Explicit specializations of any standard library function template or class @@ -25,44 +25,42 @@ The check detects the following (user provided) declarations in namespace Examples: -.. code-block:: c++ +```c++ +namespace std { + int x; // warning: modification of 'std' namespace can result in undefined behavior [bugprone-dont-modify-std-namespace] +} - namespace std { - int x; // warning: modification of 'std' namespace can result in undefined behavior [bugprone-dont-modify-std-namespace] - } +namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior +} - namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior +template <> +struct ::std::hash<long> { // warning: modification of 'std' namespace can result in undefined behavior + unsigned long operator()(const long &K) const { + return K; } +}; - template <> - struct ::std::hash<long> { // warning: modification of 'std' namespace can result in undefined behavior - unsigned long operator()(const long &K) const { - return K; - } - }; +struct MyData { long data; }; - struct MyData { long data; }; +template <> +struct ::std::hash<MyData> { // no warning: specialization with user-defined type + unsigned long operator()(const MyData &K) const { + return K.data; + } +}; +namespace std { template <> - struct ::std::hash<MyData> { // no warning: specialization with user-defined type - unsigned long operator()(const MyData &K) const { - return K.data; - } - }; + void swap<bool>(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior - namespace std { - template <> - void swap<bool>(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior - - template <> - bool less<void>::operator()<MyData &&, MyData &&>(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior - return true; - } + template <> + bool less<void>::operator()<MyData &&, MyData &&>(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior + return true; } +} +``` -References ----------- +## References This check corresponds to the CERT C++ Coding Standard rule -`DCL58-CPP. Do not modify the standard namespaces -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/declarations-and-initialization-dcl/dcl58-cpp/>`_. +[DCL58-CPP. Do not modify the standard namespaces](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/declarations-and-initialization-dcl/dcl58-cpp/). diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst index ad4ed895bf012..c7166d7dfe13e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-string-constructor +```{title} clang-tidy - bugprone-string-constructor +``` -bugprone-string-constructor -=========================== +# bugprone-string-constructor Finds string constructors that are suspicious and probably errors. @@ -9,59 +9,58 @@ A common mistake is to swap parameters to the 'fill' string-constructor. Examples: -.. code-block:: c++ - - std::string str('x', 50); // should be str(50, 'x') +```c++ +std::string str('x', 50); // should be str(50, 'x') +``` Calling the string-literal constructor with a length bigger than the literal is suspicious and adds extra random characters to the string. Examples: -.. code-block:: c++ - - std::string("test", 200); // Will include random characters after "test". - std::string("test", 2, 5); // Will include random characters after "st". - std::string_view("test", 200); +```c++ +std::string("test", 200); // Will include random characters after "test". +std::string("test", 2, 5); // Will include random characters after "st". +std::string_view("test", 200); +``` Creating an empty string from constructors with parameters is considered suspicious. The programmer should use the empty constructor instead. Examples: -.. code-block:: c++ - - std::string("test", 0); // Creation of an empty string. - std::string("test", 1, 0); - std::string_view("test", 0); +```c++ +std::string("test", 0); // Creation of an empty string. +std::string("test", 1, 0); +std::string_view("test", 0); +``` Passing an invalid first character position parameter to constructor will -cause ``std::out_of_range`` exception at runtime. +cause `std::out_of_range` exception at runtime. Examples: -.. code-block:: c++ - - std::string("test", -1, 10); // Negative first character position. - std::string("test", 10, 10); // First character position is bigger than string literal character range". - -Options -------- - -.. option:: WarnOnLargeLength - - When `true`, the check will warn on a string with a length greater than - :option:`LargeLengthThreshold`. Default is `true`. +```c++ +std::string("test", -1, 10); // Negative first character position. +std::string("test", 10, 10); // First character position is bigger than string literal character range". +``` -.. option:: LargeLengthThreshold +## Options - An integer specifying the large length threshold. Default is `0x800000`. +```{option} WarnOnLargeLength +When `true`, the check will warn on a string with a length greater than +{option}`LargeLengthThreshold`. Default is `true`. +``` -.. option:: StringNames +```{option} LargeLengthThreshold +An integer specifying the large length threshold. Default is `0x800000`. +``` - Default is `::std::basic_string;::std::basic_string_view`. +```{option} StringNames +Default is `::std::basic_string;::std::basic_string_view`. - Semicolon-delimited list of class names to apply this check to. - By default `::std::basic_string` applies to ``std::string`` and - ``std::wstring``. Set to e.g. `::std::basic_string;llvm::StringRef;QString` - to perform this check on custom classes. +Semicolon-delimited list of class names to apply this check to. +By default `::std::basic_string` applies to `std::string` and +`std::wstring`. Set to e.g. `::std::basic_string;llvm::StringRef;QString` +to perform this check on custom classes. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.rst index 6401f008d2e0a..a225593aaf530 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.rst @@ -1,37 +1,37 @@ -.. title:: clang-tidy - bugprone-string-integer-assignment +```{title} clang-tidy - bugprone-string-integer-assignment +``` -bugprone-string-integer-assignment -================================== +# bugprone-string-integer-assignment -The check finds assignments of an integer to ``std::basic_string<CharT>`` -(``std::string``, ``std::wstring``, etc.). The source of the problem is the -following assignment operator of ``std::basic_string<CharT>``: +The check finds assignments of an integer to `std::basic_string<CharT>` +(`std::string`, `std::wstring`, etc.). The source of the problem is the +following assignment operator of `std::basic_string<CharT>`: -.. code-block:: c++ - - basic_string& operator=( CharT ch ); +```c++ +basic_string& operator=( CharT ch ); +``` Numeric types can be implicitly casted to character types. -.. code-block:: c++ - - std::string s; - int x = 5965; - s = 6; - s = x; +```c++ +std::string s; +int x = 5965; +s = 6; +s = x; +``` Use the appropriate conversion functions or character literals. -.. code-block:: c++ - - std::string s; - int x = 5965; - s = '6'; - s = std::to_string(x); +```c++ +std::string s; +int x = 5965; +s = '6'; +s = std::to_string(x); +``` In order to suppress false positives, use an explicit cast. -.. code-block:: c++ - - std::string s; - s = static_cast<char>(6); +```c++ +std::string s; +s = static_cast<char>(6); +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.rst index bc5f2ce2cc885..d9536d22bd0a6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.rst @@ -1,36 +1,34 @@ -.. title:: clang-tidy - bugprone-string-literal-with-embedded-nul +```{title} clang-tidy - bugprone-string-literal-with-embedded-nul +``` -bugprone-string-literal-with-embedded-nul -========================================= +# bugprone-string-literal-with-embedded-nul Finds occurrences of string literal with embedded NUL character and validates their usage. -Invalid escaping ----------------- +## Invalid escaping Special characters can be escaped within a string literal by using their -hexadecimal encoding like ``\x42``. A common mistake is to escape them -like this ``\0x42`` where the ``\0`` stands for the NUL character. +hexadecimal encoding like `\x42`. A common mistake is to escape them +like this `\0x42` where the `\0` stands for the NUL character. -.. code-block:: c++ +```c++ +const char* Example[] = "Invalid character: \0x12 should be \x12"; +const char* Bytes[] = "\x03\0x02\0x01\0x00\0xFF\0xFF\0xFF"; +``` - const char* Example[] = "Invalid character: \0x12 should be \x12"; - const char* Bytes[] = "\x03\0x02\0x01\0x00\0xFF\0xFF\0xFF"; - -Truncated literal ------------------ +## Truncated literal String-like classes can manipulate strings with embedded NUL as they are keeping track of the bytes and the length. This is not the case for a -``char*`` (NUL-terminated) string. +`char*` (NUL-terminated) string. A common mistake is to pass a string-literal with embedded NUL to a string constructor expecting a NUL-terminated string. The bytes after the first NUL character are truncated. -.. code-block:: c++ - - std::string str("abc\0def"); // "def" is truncated - str += "\0"; // This statement is doing nothing - if (str == "\0abc") return; // This expression is always true +```c++ +std::string str("abc\0def"); // "def" is truncated +str += "\0"; // This statement is doing nothing +if (str == "\0abc") return; // This expression is always true +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.rst index 7138c97b745ae..582c7438bcb78 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.rst @@ -1,63 +1,64 @@ -.. title:: clang-tidy - bugprone-stringview-nullptr +```{title} clang-tidy - bugprone-stringview-nullptr +``` -bugprone-stringview-nullptr -=========================== -Checks for various ways that the ``const CharT*`` constructor of -``std::basic_string_view`` can be passed a null argument and replaces them +# bugprone-stringview-nullptr + +Checks for various ways that the `const CharT*` constructor of +`std::basic_string_view` can be passed a null argument and replaces them with the default constructor in most cases. For the comparison operators, -braced initializer list does not compile so instead a call to ``.empty()`` +braced initializer list does not compile so instead a call to `.empty()` or the empty string literal are used, where appropriate. This prevents code from invoking behavior which is unconditionally undefined. -The single-argument ``const CharT*`` constructor does not check for the null +The single-argument `const CharT*` constructor does not check for the null case before dereferencing its input. The standard is slated to add an explicitly-deleted overload to catch some of these cases: wg21.link/p2166 -To catch the additional cases of ``NULL`` (which expands to ``__null``) and -``0``, first run the ``modernize-use-nullptr`` check to convert the callers to -``nullptr``. - -.. code-block:: c++ +To catch the additional cases of `NULL` (which expands to `__null`) and +`0`, first run the `modernize-use-nullptr` check to convert the callers to +`nullptr`. - std::string_view sv = nullptr; +```c++ +std::string_view sv = nullptr; - sv = nullptr; +sv = nullptr; - bool is_empty = sv == nullptr; - bool isnt_empty = sv != nullptr; +bool is_empty = sv == nullptr; +bool isnt_empty = sv != nullptr; - accepts_sv(nullptr); +accepts_sv(nullptr); - accepts_sv({{}}); // A +accepts_sv({{}}); // A - accepts_sv({nullptr, 0}); // B +accepts_sv({nullptr, 0}); // B +``` is translated into... -.. code-block:: c++ - - std::string_view sv = {}; - - sv = {}; - - bool is_empty = sv.empty(); - bool isnt_empty = !sv.empty(); +```c++ +std::string_view sv = {}; - accepts_sv(""); +sv = {}; - accepts_sv(""); // A +bool is_empty = sv.empty(); +bool isnt_empty = !sv.empty(); - accepts_sv({nullptr, 0}); // B +accepts_sv(""); -.. note:: +accepts_sv(""); // A - The source pattern with trailing comment "A" selects the ``(const CharT*)`` - constructor overload and then value-initializes the pointer, causing a null - dereference. It happens to not include the ``nullptr`` literal, but it is - still within the scope of this ClangTidy check. +accepts_sv({nullptr, 0}); // B +``` -.. note:: +```{note} +The source pattern with trailing comment "A" selects the `(const CharT*)` +constructor overload and then value-initializes the pointer, causing a null +dereference. It happens to not include the `nullptr` literal, but it is +still within the scope of this ClangTidy check. +``` - The source pattern with trailing comment "B" selects the - ``(const CharT*, size_type)`` constructor which is perfectly valid, since the - length argument is ``0``. It is not changed by this ClangTidy check. +```{note} +The source pattern with trailing comment "B" selects the +`(const CharT*, size_type)` constructor which is perfectly valid, since the +length argument is `0`. It is not changed by this ClangTidy check. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.rst index 94e3db9770cbc..991ec9e603a6b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-suspicious-enum-usage +```{title} clang-tidy - bugprone-suspicious-enum-usage +``` -bugprone-suspicious-enum-usage -============================== +# bugprone-suspicious-enum-usage The checker detects various cases when an enum is probably misused (as a bitmask). @@ -9,71 +9,71 @@ The checker detects various cases when an enum is probably misused 1. When "ADD" or "bitwise OR" is used between two enum which come from different types and these types value ranges are not disjoint. -The following cases will be investigated only using :option:`StrictMode`. We +The following cases will be investigated only using {option}`StrictMode`. We regard the enum as a (suspicious) bitmask if the three conditions below are true at the same time: -* at most half of the elements of the enum are non pow-of-2 numbers (because of +- at most half of the elements of the enum are non pow-of-2 numbers (because of short enumerations) -* there is another non pow-of-2 number than the enum constant representing all +- there is another non pow-of-2 number than the enum constant representing all choices (the result "bitwise OR" operation of all enum elements) -* enum type variable/enumconstant is used as an argument of a `+` or "bitwise +- enum type variable/enumconstant is used as an argument of a + `+` or "bitwise OR" operator So whenever the non pow-of-2 element is used as a bitmask element we diagnose a misuse and give a warning. -2. Investigating the right hand side of ``+=`` and ``|=`` operator. -3. Check only the enum value side of a ``|`` and ``+`` operator if one of +2. Investigating the right hand side of `+=` and `|=` operator. +3. Check only the enum value side of a `|` and `+` operator if one of them is not enum val. -4. Check both side of ``|`` or ``+`` operator where the enum values are from +4. Check both side of `|` or `+` operator where the enum values are from the same enum type. Examples: -.. code-block:: c++ - - enum { A, B, C }; - enum { D, E, F = 5 }; - enum { G = 10, H = 11, I = 12 }; - - unsigned flag; - flag = - A | - H; // OK, disjoint value intervals in the enum types ->probably good use. - flag = B | F; // Warning, have common values so they are probably misused. - - // Case 2: - enum Bitmask { - A = 0, - B = 1, - C = 2, - D = 4, - E = 8, - F = 16, - G = 31 // OK, real bitmask. - }; - - enum Almostbitmask { - AA = 0, - BB = 1, - CC = 2, - DD = 4, - EE = 8, - FF = 16, - GG // Problem, forgot to initialize. - }; - - unsigned flag = 0; - flag |= E; // OK. - flag |= - EE; // Warning at the decl, and note that it was used here as a bitmask. - -Options -------- - -.. option:: StrictMode - - Default value: 0. - When non-null the suspicious bitmask usage will be investigated additionally - to the different enum usage check. +```c++ +enum { A, B, C }; +enum { D, E, F = 5 }; +enum { G = 10, H = 11, I = 12 }; + +unsigned flag; +flag = + A | + H; // OK, disjoint value intervals in the enum types ->probably good use. +flag = B | F; // Warning, have common values so they are probably misused. + +// Case 2: +enum Bitmask { + A = 0, + B = 1, + C = 2, + D = 4, + E = 8, + F = 16, + G = 31 // OK, real bitmask. +}; + +enum Almostbitmask { + AA = 0, + BB = 1, + CC = 2, + DD = 4, + EE = 8, + FF = 16, + GG // Problem, forgot to initialize. +}; + +unsigned flag = 0; +flag |= E; // OK. +flag |= + EE; // Warning at the decl, and note that it was used here as a bitmask. +``` + +## Options + +```{option} StrictMode +Default value: 0. +When non-null the suspicious bitmask usage will be investigated additionally +to the different enum usage check. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.rst index 7babea1361e83..c7ace31c125c1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.rst @@ -1,9 +1,9 @@ -.. title:: clang-tidy - bugprone-suspicious-memory-comparison +```{title} clang-tidy - bugprone-suspicious-memory-comparison +``` -bugprone-suspicious-memory-comparison -===================================== +# bugprone-suspicious-memory-comparison -Finds potentially incorrect calls to ``memcmp()`` based on properties of the +Finds potentially incorrect calls to `memcmp()` based on properties of the arguments. The following cases are covered: **Case 1: Non-standard-layout type** @@ -17,19 +17,15 @@ Objects with the same value may not have the same object representation. This may be caused by padding or floating-point types. See also: -`EXP42-C. Do not compare padding data -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/expressions-exp/exp42-c/>`_ +[EXP42-C. Do not compare padding data](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/expressions-exp/exp42-c/) and -`FLP37-C. Do not use object representations to compare floating-point values -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/floating-point-flp/flp37-c/>`_ +[FLP37-C. Do not use object representations to compare floating-point values](https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/floating-point-flp/flp37-c/) This check is also related to and partially overlaps the CERT C++ Coding Standard rules -`OOP57-CPP. Prefer special member functions and overloaded operators to -C Standard Library functions -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/object-oriented-programming-oop/oop57-cpp/>`_ +[OOP57-CPP. Prefer special member functions and overloaded operators to +C Standard Library functions](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/object-oriented-programming-oop/oop57-cpp/) and -`EXP62-CPP. Do not access the bits of an object representation that are not -part of the object's value representation -<https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/expressions-exp/exp62-cpp/>`_ +[EXP62-CPP. Do not access the bits of an object representation that are not +part of the object's value representation](https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/expressions-exp/exp62-cpp/) `cert-exp42-c` redirects here as an alias of this check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.rst index 82609d13e4efe..23a6557610b43 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.rst @@ -1,54 +1,53 @@ -.. title:: clang-tidy - bugprone-suspicious-memset-usage +```{title} clang-tidy - bugprone-suspicious-memset-usage +``` -bugprone-suspicious-memset-usage -================================ +# bugprone-suspicious-memset-usage -This check finds ``memset()`` calls with potential mistakes in their arguments. -Considering the function as ``void* memset(void* destination, int fill_value, -size_t byte_count)``, the following cases are covered: +This check finds `memset()` calls with potential mistakes in their arguments. +Considering the function as `void* memset(void* destination, int fill_value, +size_t byte_count)`, the following cases are covered: -**Case 1: Fill value is a character ``'0'``** +**Case 1: Fill value is a character `'0'`** Filling up a memory area with ASCII code 48 characters is not customary, possibly integer zeroes were intended instead. -The check offers a replacement of ``'0'`` with ``0``. Memsetting character -pointers with ``'0'`` is allowed. +The check offers a replacement of `'0'` with `0`. Memsetting character +pointers with `'0'` is allowed. **Case 2: Fill value is truncated** -Memset converts ``fill_value`` to ``unsigned char`` before using it. If -``fill_value`` is out of unsigned character range, it gets truncated +Memset converts `fill_value` to `unsigned char` before using it. If +`fill_value` is out of unsigned character range, it gets truncated and memory will not contain the desired pattern. **Case 3: Byte count is zero** -Calling memset with a literal zero in its ``byte_count`` argument is likely -to be unintended and swapped with ``fill_value``. The check offers to swap +Calling memset with a literal zero in its `byte_count` argument is likely +to be unintended and swapped with `fill_value`. The check offers to swap these two arguments. -Corresponding cpplint.py check name: ``runtime/memset``. - +Corresponding cpplint.py check name: `runtime/memset`. Examples: -.. code-block:: c++ - - void foo() { - int i[5] = {1, 2, 3, 4, 5}; - int *ip = i; - char c = '1'; - char *cp = &c; - int v = 0; - - // Case 1 - memset(ip, '0', 1); // suspicious - memset(cp, '0', 1); // OK - - // Case 2 - memset(ip, 0xabcd, 1); // fill value gets truncated - memset(ip, 0x00, 1); // OK - - // Case 3 - memset(ip, sizeof(int), v); // zero length, potentially swapped - memset(ip, 0, 1); // OK - } +```c++ +void foo() { + int i[5] = {1, 2, 3, 4, 5}; + int *ip = i; + char c = '1'; + char *cp = &c; + int v = 0; + + // Case 1 + memset(ip, '0', 1); // suspicious + memset(cp, '0', 1); // OK + + // Case 2 + memset(ip, 0xabcd, 1); // fill value gets truncated + memset(ip, 0x00, 1); // OK + + // Case 3 + memset(ip, sizeof(int), v); // zero length, potentially swapped + memset(ip, 0, 1); // OK +} +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.rst index 7455a2ef13509..51e30084cc3b0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-suspicious-missing-comma +```{title} clang-tidy - bugprone-suspicious-missing-comma +``` -bugprone-suspicious-missing-comma -================================= +# bugprone-suspicious-missing-comma String literals placed side-by-side are concatenated at translation phase 6 (after the preprocessor). This feature is used to represent long string @@ -9,51 +9,50 @@ literal on multiple lines. For instance, the following declarations are equivalent: -.. code-block:: c++ - - const char* A[] = "This is a test"; - const char* B[] = "This" " is a " "test"; +```c++ +const char* A[] = "This is a test"; +const char* B[] = "This" " is a " "test"; +``` A common mistake done by programmers is to forget a comma between two string literals in an array initializer list. -.. code-block:: c++ - - const char* Test[] = { - "line 1", - "line 2" // Missing comma! - "line 3", - "line 4", - "line 5" - }; +```c++ +const char* Test[] = { + "line 1", + "line 2" // Missing comma! + "line 3", + "line 4", + "line 5" +}; +``` The array contains the string "line 2line3" at offset 1 (i.e. Test[1]). Clang won't generate warnings at compile time. This check may warn incorrectly on cases like: -.. code-block:: c++ - - const char* SupportedFormat[] = { - "Error %s", - "Code " PRIu64, // May warn here. - "Warning %s", - }; - -Options -------- - -.. option:: SizeThreshold - - An unsigned integer specifying the minimum size of a string literal to be - considered by the check. Default is ``5U``. - -.. option:: RatioThreshold - - A string specifying the maximum threshold ratio [0, 1.0] of suspicious string - literals to be considered. Default is ``".2"``. - -.. option:: MaxConcatenatedTokens - - An unsigned integer specifying the maximum number of concatenated tokens. - Default is ``5U``. +```c++ +const char* SupportedFormat[] = { + "Error %s", + "Code " PRIu64, // May warn here. + "Warning %s", +}; +``` + +## Options + +```{option} SizeThreshold +An unsigned integer specifying the minimum size of a string literal to be +considered by the check. Default is `5U`. +``` + +```{option} RatioThreshold +A string specifying the maximum threshold ratio [0, 1.0] of suspicious string +literals to be considered. Default is `".2"`. +``` + +```{option} MaxConcatenatedTokens +An unsigned integer specifying the maximum number of concatenated tokens. +Default is `5U`. +``` _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
