Author: Zeyi Xu Date: 2026-08-09T12:22:25+08:00 New Revision: 5d343220655174fd1d51131eb9368d16c3a05683
URL: https://github.com/llvm/llvm-project/commit/5d343220655174fd1d51131eb9368d16c3a05683 DIFF: https://github.com/llvm/llvm-project/commit/5d343220655174fd1d51131eb9368d16c3a05683.diff LOG: [clang-tidy][docs] Rewrite bugprone check docs to Markdown [3/4] (#214422) Tracking issue: #201242 See the [migration guide] for more information. [migration guide]: https://llvm.org/docs/SphinxQuickstartTemplate.html#markdown-migration-guidelines This rewrites part 3/4 of the remaining bugprone check documentation from reST to MyST Markdown. AI Usage: This was prepared with rst2myst and GPT5.6-assisted cleanup. I manually verified that the documentation renders as expected. Preview site: https://broken.life/llvm-staging/bugprone-markdown-port/ Added: Modified: clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.md clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.md clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.md clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.md clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.md clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.md clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.md clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.md clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.md clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.md clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.md clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.md clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.md clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.md clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.md clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.md clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.md clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.md clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.md clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.md Removed: ################################################################################ diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.md index c789f0fa6b27c..4b5bd5549fe15 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/random-generator-seed.md @@ -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 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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.md index 3385abdc39ab3..c057e2302d2ae 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/raw-memory-call-on-non-trivial-type.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.md index 7a321bd9c0f06..d6284355e40c5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.md @@ -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`. - -The checker also detects redundant condition checks if the condition variable -is an operand of a logical "and" (``&&``) or a logical "or" (``||``) operator: +this code and suggests removal of the second checking of variable +`onFire`. -.. code-block:: c +The check also detects redundant condition checks if the condition variable +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 +The check 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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.md index f181659270a84..d476d8889ac37 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/reserved-identifier.md @@ -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 string. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.md index 663e2149c7ac9..11d4540f9d6d4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.md @@ -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 diff erent ``const &`` parameters being returned depending +Marking such an `&&` overload as `deleted`, will silence the warning as +well. In the case of diff erent `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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.md index 003be010f359b..dd0420c6499ef 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/shared-ptr-array-mismatch.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.md index f5648654023c0..7a4958a0b80f9 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signal-handler.md @@ -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 diff er 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`. +Default is `POSIX`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.md index 2a728d1093f6f..e2fd4bac5893e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/signed-char-misuse.md @@ -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 - diff erent value ranges. For ``signed char``, the non-ASCII characters are + diff erent 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 diff erent 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. Default is `true`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.md index 4ed7cdc8cab4b..c1bbadd64f59b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.md @@ -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 diff erence 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 diff erence -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +### Scaling the result of pointer diff erence Subtracting two pointers results in an integer expression (of type -``ptr diff _t``) which expresses the distance between the two pointed objects in +`ptr diff _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 diff erence 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 diff erence 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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.md index 8fdf2fcc6821f..4f1b4c2de0a6e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/standalone-empty.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.md index 41b14537eb36f..51401ab4d9f98 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-exception-baseclass.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.md index 29e128e3b1f20..92d429594e734 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/std-namespace-modification.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.md index ad4ed895bf012..b894f0a2a8dc5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.md @@ -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,57 @@ 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`. - -.. option:: LargeLengthThreshold - - An integer specifying the large length threshold. Default is `0x800000`. - -.. 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. +```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`. +``` + +```{option} LargeLengthThreshold +An integer specifying the large length threshold. Default is `0x800000`. +``` + +```{option} StringNames +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. +Default is `::std::basic_string;::std::basic_string_view`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.md index 6401f008d2e0a..a225593aaf530 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-integer-assignment.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.md index bc5f2ce2cc885..d9536d22bd0a6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-literal-with-embedded-nul.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.md index 7138c97b745ae..13e5c03c402b8 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/stringview-nullptr.md @@ -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 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 check. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.md index 94e3db9770cbc..8ca5da87e5e11 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-enum-usage.md @@ -1,79 +1,79 @@ -.. 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 +The check detects various cases when an enum is probably misused (as a bitmask). 1. When "ADD" or "bitwise OR" is used between two enum which come from diff erent 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 diff erent 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 +When non-null the suspicious bitmask usage will be investigated additionally +to the diff erent enum usage check. +Default is `0`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.md index 7babea1361e83..c7ace31c125c1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memory-comparison.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.md index 82609d13e4efe..23a6557610b43 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-memset-usage.md @@ -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.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.md index 7455a2ef13509..51e30084cc3b0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-missing-comma.md @@ -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
