llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tidy Author: Zeyi Xu (zeyi2) <details> <summary>Changes</summary> <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> --- Patch is 80.67 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/214419.diff 20 Files Affected: - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.md (+38-38) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.md (+34-34) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-shared-from-this.md (+23-23) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/infinite-loop.md (+12-12) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/integer-division.md (+24-24) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/invalid-enum-default-initialization.md (+62-64) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.md (+25-22) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/misleading-setter-of-reference.md (+27-26) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/misplaced-operator-in-strlen-in-alloc.md (+37-41) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/misplaced-widening-cast.md (+34-37) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/missing-end-comparison.md (+68-70) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/move-forwarding-reference.md (+34-36) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/multi-level-implicit-pointer-conversion.md (+23-24) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/multiple-new-in-one-expression.md (+77-77) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/narrowing-conversions.md (+99-100) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.md (+34-36) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/nondeterministic-pointer-iteration-order.md (+22-24) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/not-null-terminated-result.md (+66-75) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/optional-value-conversion.md (+45-46) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/pointer-arithmetic-on-polymorphic-object.md (+39-42) ``````````diff diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.md index f3f0331b15b5e..9231cb6f2e844 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inc-dec-in-conditions.md @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-inc-dec-in-conditions +```{title} clang-tidy - bugprone-inc-dec-in-conditions +``` -bugprone-inc-dec-in-conditions -============================== +# bugprone-inc-dec-in-conditions Detects when a variable is both incremented/decremented and referenced inside a complex condition and suggests moving them outside to avoid ambiguity in the @@ -12,57 +12,57 @@ to unexpected behavior. The side-effect of changing the variable's value within the condition can make the code difficult to reason about. Additionally, the developer's intended timing for the modification of the variable may not be clear, leading to misunderstandings and errors. This can be particularly -problematic when the condition involves logical operators like ``&&`` and -``||``, where the order of evaluation can further complicate the situation. +problematic when the condition involves logical operators like `&&` and +`||`, where the order of evaluation can further complicate the situation. Consider the following example: -.. code-block:: c++ - - int i = 0; - // ... - if (i++ < 5 && i > 0) { - // do something - } +```c++ +int i = 0; +// ... +if (i++ < 5 && i > 0) { + // do something +} +``` In this example, the result of the expression may not be what the developer -intended. The original intention of the developer could be to increment ``i`` +intended. The original intention of the developer could be to increment `i` after the entire condition is evaluated, but in reality, i will be incremented -before ``i > 0`` is executed. This can lead to unexpected behavior and bugs in +before `i > 0` is executed. This can lead to unexpected behavior and bugs in the code. To fix this issue, the developer should separate the increment operation from the condition and perform it separately. For example, they can -increment ``i`` in a separate statement before or after the condition is -evaluated. This ensures that the value of ``i`` is predictable and consistent +increment `i` in a separate statement before or after the condition is +evaluated. This ensures that the value of `i` is predictable and consistent throughout the code. -.. code-block:: c++ - - int i = 0; - // ... - i++; - if (i <= 5 && i > 0) { - // do something - } +```c++ +int i = 0; +// ... +i++; +if (i <= 5 && i > 0) { + // do something +} +``` Another common issue occurs when multiple increments or decrements are performed on the same variable inside a complex condition. For example: -.. code-block:: c++ - - int i = 4; - // ... - if (i++ < 5 || --i > 2) { - // do something - } +```c++ +int i = 4; +// ... +if (i++ < 5 || --i > 2) { + // do something +} +``` There is a potential issue with this code due to the order of evaluation in -C++. The ``||`` operator used in the condition statement guarantees that if -the first operand evaluates to ``true``, the second operand will not be -evaluated. This means that if ``i`` were initially ``4``, the first operand -``i < 5`` would evaluate to ``true`` and the second operand ``i > 2`` would -not be evaluated. As a result, the decrement operation ``--i`` would not be -executed and ``i`` would hold value ``5``, which may not be the intended +C++. The `||` operator used in the condition statement guarantees that if +the first operand evaluates to `true`, the second operand will not be +evaluated. This means that if `i` were initially `4`, the first operand +`i < 5` would evaluate to `true` and the second operand `i > 2` would +not be evaluated. As a result, the decrement operation `--i` would not be +executed and `i` would hold value `5`, which may not be the intended behavior for the developer. To avoid this potential issue, the both increment and decrement operation on -``i`` should be moved outside the condition statement. +`i` should be moved outside the condition statement. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.md index a7860a96e3081..a054d0cf80f47 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-if.md @@ -1,48 +1,48 @@ -.. title:: clang-tidy - bugprone-incorrect-enable-if +```{title} clang-tidy - bugprone-incorrect-enable-if +``` -bugprone-incorrect-enable-if -============================ +# bugprone-incorrect-enable-if -Detects incorrect usages of ``std::enable_if`` that don't name the nested -``type`` type. +Detects incorrect usages of `std::enable_if` that don't name the nested +`type` type. -In C++11 introduced ``std::enable_if`` as a convenient way to leverage SFINAE. -One form of using ``std::enable_if`` is to declare an unnamed template type +In C++11 introduced `std::enable_if` as a convenient way to leverage SFINAE. +One form of using `std::enable_if` is to declare an unnamed template type parameter with a default type equal to -``typename std::enable_if<condition>::type``. If the author forgets to name -the nested type ``type``, then the code will always consider the candidate +`typename std::enable_if<condition>::type`. If the author forgets to name +the nested type `type`, then the code will always consider the candidate template even if the condition is not met. -Below are some examples of code using ``std::enable_if`` correctly and +Below are some examples of code using `std::enable_if` correctly and incorrect examples that this check flags. -.. code-block:: c++ +```c++ +template <typename T, typename = typename std::enable_if<T::some_trait>::type> +void valid_usage() { ... } - template <typename T, typename = typename std::enable_if<T::some_trait>::type> - void valid_usage() { ... } +template <typename T, typename = std::enable_if_t<T::some_trait>> +void valid_usage_with_trait_helpers() { ... } - template <typename T, typename = std::enable_if_t<T::some_trait>> - void valid_usage_with_trait_helpers() { ... } +// The below code is not a correct application of SFINAE. Even if +// T::some_trait is not true, the function will still be considered in the +// set of function candidates. It can either incorrectly select the function +// when it should not be a candidates, and/or lead to hard compile errors +// if the body of the template does not compile if the condition is not +// satisfied. +template <typename T, typename = std::enable_if<T::some_trait>> +void invalid_usage() { ... } - // The below code is not a correct application of SFINAE. Even if - // T::some_trait is not true, the function will still be considered in the - // set of function candidates. It can either incorrectly select the function - // when it should not be a candidates, and/or lead to hard compile errors - // if the body of the template does not compile if the condition is not - // satisfied. - template <typename T, typename = std::enable_if<T::some_trait>> - void invalid_usage() { ... } +// The tool suggests the following replacement for 'invalid_usage': +template <typename T, typename = typename std::enable_if<T::some_trait>::type> +void fixed_invalid_usage() { ... } +``` - // The tool suggests the following replacement for 'invalid_usage': - template <typename T, typename = typename std::enable_if<T::some_trait>::type> - void fixed_invalid_usage() { ... } - -C++14 introduced the trait helper ``std::enable_if_t`` which reduces the +C++14 introduced the trait helper `std::enable_if_t` which reduces the likelihood of this error. C++20 introduces constraints, which generally -supersede the use of ``std::enable_if``. See -:doc:`modernize-type-traits <../modernize/type-traits>` for another tool -that will replace ``std::enable_if`` with -``std::enable_if_t``, and see -:doc:`modernize-use-constraints <../modernize/use-constraints>` for another -tool that replaces ``std::enable_if`` with C++20 constraints. Consider these +supersede the use of `std::enable_if`. See +{doc}`modernize-type-traits <../modernize/type-traits>` for another tool +that will replace `std::enable_if` with +`std::enable_if_t`, and see +{doc}`modernize-use-constraints <../modernize/use-constraints>` for another +tool that replaces `std::enable_if` with C++20 constraints. Consider these newer mechanisms where possible. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-shared-from-this.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-shared-from-this.md index 968340a6e8f98..7608c7d7e870c 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-shared-from-this.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-enable-shared-from-this.md @@ -1,34 +1,34 @@ -.. title:: clang-tidy - bugprone-incorrect-enable-shared-from-this +```{title} clang-tidy - bugprone-incorrect-enable-shared-from-this +``` -bugprone-incorrect-enable-shared-from-this -========================================== +# bugprone-incorrect-enable-shared-from-this Detect classes or structs that do not publicly inherit from -``std::enable_shared_from_this``, because unintended behavior will -otherwise occur when calling ``shared_from_this``. +`std::enable_shared_from_this`, because unintended behavior will +otherwise occur when calling `shared_from_this`. Consider the following code: -.. code-block:: c++ +````c++ +#include <memory> - #include <memory> +// private inheritance +class BadExample : std::enable_shared_from_this<BadExample> { - // private inheritance - class BadExample : std::enable_shared_from_this<BadExample> { +// ``shared_from_this``` unintended behaviour +// `libstdc++` implementation returns uninitialized ``weak_ptr`` + public: + BadExample* foo() { return shared_from_this().get(); } + void bar() { return; } +}; - // ``shared_from_this``` unintended behaviour - // `libstdc++` implementation returns uninitialized ``weak_ptr`` - public: - BadExample* foo() { return shared_from_this().get(); } - void bar() { return; } - }; +void using_not_public() { + auto bad_example = std::make_shared<BadExample>(); + auto* b_ex = bad_example->foo(); + b_ex->bar(); +} +```` - void using_not_public() { - auto bad_example = std::make_shared<BadExample>(); - auto* b_ex = bad_example->foo(); - b_ex->bar(); - } - -Using `libstdc++` implementation, ``shared_from_this`` will throw -``std::bad_weak_ptr``. When ``using_not_public()`` is called, this code will +Using `libstdc++` implementation, `shared_from_this` will throw +`std::bad_weak_ptr`. When `using_not_public()` is called, this code will crash without exception handling. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/infinite-loop.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/infinite-loop.md index bbbc8773868a4..14d861c3ca4fd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/infinite-loop.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/infinite-loop.md @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-infinite-loop +```{title} clang-tidy - bugprone-infinite-loop +``` -bugprone-infinite-loop -====================== +# bugprone-infinite-loop Finds obvious infinite loops (loops where the condition variable is not changed at all). @@ -9,9 +9,9 @@ at all). Finding infinite loops is well-known to be impossible (halting problem). However, it is possible to detect some obvious infinite loops, for example, if the loop condition is not changed. This check detects such loops. A loop is -considered infinite if it does not have any loop exit statement (``break``, -``continue``, ``goto``, ``return``, ``throw`` or a call to a function called as -``[[noreturn]]``) and all of the following conditions hold for every variable +considered infinite if it does not have any loop exit statement (`break`, +`continue`, `goto`, `return`, `throw` or a call to a function called as +`[[noreturn]]`) and all of the following conditions hold for every variable in the condition: - It is a local variable. @@ -24,9 +24,9 @@ loop infinite since functions may return different values for different calls. For example, the following loop is considered infinite `i` is not changed in the body: -.. code-block:: c++ - - int i = 0, j = 0; - while (i < 10) { - ++j; - } +```c++ +int i = 0, j = 0; +while (i < 10) { + ++j; +} +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/integer-division.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/integer-division.md index 2c82e6fa18a3d..35ff24b0225fc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/integer-division.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/integer-division.md @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-integer-division +```{title} clang-tidy - bugprone-integer-division +``` -bugprone-integer-division -========================= +# bugprone-integer-division Finds cases where integer division in a floating point context is likely to cause unintended loss of precision. @@ -16,24 +16,24 @@ as these are interpreted as signs of deliberateness from the programmer. Examples: -.. code-block:: c++ - - float floatFunc(float); - int intFunc(int); - double d; - int i = 42; - - // Warn, floating-point values expected. - d = 32 * 8 / (2 + i); - d = 8 * floatFunc(1 + 7 / 2); - d = i / (1 << 4); - - // OK, no integer division. - d = 32 * 8.0 / (2 + i); - d = 8 * floatFunc(1 + 7.0 / 2); - d = (double)i / (1 << 4); - - // OK, there are signs of deliberateness. - d = 1 << (i / 2); - d = 9 + intFunc(6 * i / 32); - d = (int)(i / 32) - 8; +```c++ +float floatFunc(float); +int intFunc(int); +double d; +int i = 42; + +// Warn, floating-point values expected. +d = 32 * 8 / (2 + i); +d = 8 * floatFunc(1 + 7 / 2); +d = i / (1 << 4); + +// OK, no integer division. +d = 32 * 8.0 / (2 + i); +d = 8 * floatFunc(1 + 7.0 / 2); +d = (double)i / (1 << 4); + +// OK, there are signs of deliberateness. +d = 1 << (i / 2); +d = 9 + intFunc(6 * i / 32); +d = (int)(i / 32) - 8; +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/invalid-enum-default-initialization.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/invalid-enum-default-initialization.md index fcbfce751828d..7ab9e51bbdc91 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/invalid-enum-default-initialization.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/invalid-enum-default-initialization.md @@ -1,84 +1,82 @@ -.. title:: clang-tidy - bugprone-invalid-enum-default-initialization +```{title} clang-tidy - bugprone-invalid-enum-default-initialization +``` -bugprone-invalid-enum-default-initialization -============================================ +# bugprone-invalid-enum-default-initialization -Detects default initialization (to 0) of variables with ``enum`` type where +Detects default initialization (to 0) of variables with `enum` type where the enum has no enumerator with value of 0. In C++ a default initialization is performed if a variable is initialized with initializer list or in other implicit ways, and no value is specified at the initialization. In such cases the value 0 is used for the initialization. This also applies to enumerations even if it does not have an enumerator with -value 0. In this way a variable with the ``enum`` type may contain initially an +value 0. In this way a variable with the `enum` type may contain initially an invalid value (if the program expects that it contains only the listed enumerator values). -The check emits a warning only if an ``enum`` variable is default-initialized -(contrary to not initialized) and the ``enum`` does not have an enumerator with -value of 0. The type can be a scoped or non-scoped ``enum``. Unions are not +The check emits a warning only if an `enum` variable is default-initialized +(contrary to not initialized) and the `enum` does not have an enumerator with +value of 0. The type can be a scoped or non-scoped `enum`. Unions are not handled by the check (if it contains a member of enumeration type). -Note that the ``enum`` ``std::errc`` is always ignored because it is expected +Note that the `enum` `std::errc` is always ignored because it is expected to be default initialized, despite not defining an enumerator with the value 0. -.. code-block:: c++ - - enum class Enum1: int { - A = 1, - B - }; - - enum class Enum0: int { - A = 0, - B - }; - - void f() { - Enum1 X1{}; // warn: 'X1' is initialized to 0 - Enum1 X2 = Enum1(); // warn: 'X2' is initialized to 0 - Enum1 X3; // no warning: 'X3' is not initialized - Enum0 X4{}; // no warning: type has an enumerator with value of 0 - } - - struct S1 { - Enum1 A; - S(): A() {} // warn: 'A' is initialized to 0 - }; - - struct S2 { - int A; - Enum1 B; - }; - - S2 VarS2{}; // warn: member 'B' is initialized to 0 +```c++ +enum class Enum1: int { + A = 1, + B +}; + +enum class Enum0: int { + A = 0, + B +}; + +void f() { + Enum1 X1{}; // warn: 'X1' is initialized to 0 + Enum1 X2 = Enum1(); // warn: 'X2' is initialized to 0 + Enum1 X3; // no warning: 'X3' is not initialized + Enum0 X4{}; // no warning: type has an enumerator with value of 0 +} + +struct S1 { + Enum1 A; + S(): A() {} // warn: 'A' is initialized to 0 +}; + +struct S2 { + int A; + Enum1 B; +}; + +S2 VarS2{}; // warn: member 'B' is initialized to 0 +``` The check applies to initialization of arrays or structures with initialization lists in C code too. In these cases elements not specified in the list (and have enum type) are set to 0. -.. code-block:: c - - enum Enum1 { - Enum1_A = 1, - Enum1_B - }; - struct Struct1 { - int a; - enum Enum1 b; - }; - - enum Enum1 Array1[2] = {Enum1_A}; // warn: omitted elements are initialized to 0 - enum Enum1 Array2[2][2] = {{Enum1_A}, {Enum1_A}}; // warn: last element of both nested arrays is initialized to 0 - enum Enum1 Array3[2][2] = {{Enum1_A, Enum1_A}}; // warn: elements of second array are initialized to 0 - - struct Struct1 S1 = {1}; // warn: element 'b' is initialized to 0 - - -Options -------- - -.. option:: IgnoredEnums - - Semicolon-separated list of regexes specifying enums for which this check won't be - enforced. Default is `::std::errc`. +```c +enum Enum1 { + Enum1_A = 1, + Enum1_B +}; +struct Struct1 { + int a; + enum Enum1 b; +}; + +enum Enum1 Array1[2] = {Enum1_A}; // warn: omitted elements are initialized to 0 +enum Enum1 Array2[2][2] = {{Enum1_A}, {Enum1_A}}; // warn: last element of both nested arrays is initialized to 0 +enum Enum1 Array3[2][2] = {{Enum1_A, Enum1_A}}; // warn: elements of second array are initialized to 0 + +struct Struct1 S1 = {1}; // warn: element 'b' is initialized to 0 +``` + +## Options + +```{option} IgnoredEnums +Semicolon-separated list of regexes specifying enums for which this check won't be +enforced. Default is `::std::errc`. +``` diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.md b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.md index e9cbf2b46b2bc..47d49206e14da 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.md +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.md @@ -1,35 +1,38 @@ -.. title:: clang-tidy - bugprone-lambda-function-name +```{title} clang-tidy - bugprone-lambda-function-name +``` -bugprone-lambda-function-name -============================= +# bugprone-lambda-function-name Checks for attempts to get the name of a function from within a lambda -expression. The name of a lambda is always something like ``operator()``, which +expression. The name of a lambda is always something like `operator()`, which is almost never what was intended. Example: -.. code-block:: c++ +```c++ +void FancyFunction() { + [] { printf("Called from %s\n", __func__); }(); + [] { printf("Now called from %s\n", __FUNCTION__); }(); +} +``` - void Fa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/214419 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
