brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 3a37b25 Raw
150 lines · plain
1.. title:: clang-tidy - readability-implicit-bool-conversion2 3readability-implicit-bool-conversion4====================================5 6This check can be used to find implicit conversions between built-in types and7booleans. Depending on use case, it may simply help with readability of the8code, or in some cases, point to potential bugs which remain unnoticed due to9implicit conversions.10 11The following is a real-world example of bug which was hiding behind implicit12``bool`` conversion:13 14.. code-block:: c++15 16  class Foo {17    int m_foo;18 19  public:20    void setFoo(bool foo) { m_foo = foo; } // warning: implicit conversion bool -> int21    int getFoo() { return m_foo; }22  };23 24  void use(Foo& foo) {25    bool value = foo.getFoo(); // warning: implicit conversion int -> bool26  }27 28This code is the result of unsuccessful refactoring, where type of ``m_foo``29changed from ``bool`` to ``int``. The programmer forgot to change all30occurrences of ``bool``, and the remaining code is no longer correct, yet it31still compiles without any visible warnings.32 33In addition to issuing warnings, fix-it hints are provided to help solve the34reported issues. This can be used for improving readability of code, for35example:36 37.. code-block:: c++38 39  void conversionsToBool() {40    float floating;41    bool boolean = floating;42    // ^ propose replacement: bool boolean = floating != 0.0f;43 44    int integer;45    if (integer) {}46    // ^ propose replacement: if (integer != 0) {}47 48    int* pointer;49    if (!pointer) {}50    // ^ propose replacement: if (pointer == nullptr) {}51 52    while (1) {}53    // ^ propose replacement: while (true) {}54  }55 56  void functionTakingInt(int param);57 58  void conversionsFromBool() {59    bool boolean;60    functionTakingInt(boolean);61    // ^ propose replacement: functionTakingInt(static_cast<int>(boolean));62 63    functionTakingInt(true);64    // ^ propose replacement: functionTakingInt(1);65  }66 67In general, the following conversion types are checked:68 69- integer expression/literal to boolean (conversion from a single bit bitfield70  to boolean is explicitly allowed, since there's no ambiguity / information71  loss in this case),72 73- floating expression/literal to boolean,74 75- pointer/pointer to member/``nullptr``/``NULL`` to boolean,76 77- boolean expression/literal to integer (conversion from boolean to a single78  bit bitfield is explicitly allowed),79 80- boolean expression/literal to floating.81 82The rules for generating fix-it hints are:83 84- in case of conversions from other built-in type to bool, an explicit85  comparison is proposed to make it clear what exactly is being compared:86 87  - ``bool boolean = floating;`` is changed to88    ``bool boolean = floating == 0.0f;``,89 90  - for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``,91    ``0.0``, ``nullptr``),92 93- in case of negated expressions conversion to bool, the proposed replacement94  with comparison is simplified:95 96  - ``if (!pointer)`` is changed to ``if (pointer == nullptr)``,97 98- in case of conversions from bool to other built-in types, an explicit99  ``static_cast`` (or a C-style cast since C23) is proposed to make it clear100  that a conversion is taking place:101 102  - ``int integer = boolean;`` is changed to103    ``int integer = static_cast<int>(boolean);``,104 105- if the conversion is performed on type literals, an equivalent literal is106  proposed, according to what type is actually expected, for example:107 108  - ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``,109 110  - ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``,111 112  - for other types, appropriate literals are used (``false``, ``true``, ``0``,113    ``1``, ``0u``, ``1u``, ``0.0f``, ``1.0f``, ``0.0``, ``1.0f``).114 115Some additional accommodations are made for pre-C++11 dialects:116 117- ``false`` literal conversion to pointer is detected,118 119- instead of ``nullptr`` literal, ``0`` is proposed as replacement.120 121Occurrences of implicit conversions inside macros and template instantiations122are deliberately ignored, as it is not clear how to deal with such cases.123 124Options125-------126 127.. option::  AllowIntegerConditions128 129   When `true`, the check will allow conditional integer conversions. Default130   is `false`.131 132.. option::  AllowPointerConditions133 134   When `true`, the check will allow conditional pointer conversions. Default135   is `false`.136 137.. option::  UseUpperCaseLiteralSuffix138 139   When `true`, the replacements will use an uppercase literal suffix in the140   provided fixes. Default is `false`.141 142    Example143 144    .. code-block:: c++145 146      uint32_t foo;147      if (foo) {}148      // ^ propose replacement default: if (foo != 0u) {}149      // ^ propose replacement with option `UseUpperCaseLiteralSuffix`: if (foo != 0U) {}150