| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 1 | // RUN: %check_clang_tidy %s readability-implicit-bool-cast %t | 
|  | 2 |  | 
| Piotr Dziwinski | db9d130 | 2015-10-25 15:47:21 +0000 | [diff] [blame] | 3 | // We need NULL macro, but some buildbots don't like including <cstddef> header | 
|  | 4 | // This is a portable way of getting it to work | 
|  | 5 | #undef NULL | 
|  | 6 | #define NULL 0L | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 7 |  | 
|  | 8 | template<typename T> | 
|  | 9 | void functionTaking(T); | 
|  | 10 |  | 
|  | 11 | struct Struct { | 
|  | 12 | int member; | 
|  | 13 | }; | 
|  | 14 |  | 
|  | 15 |  | 
|  | 16 | ////////// Implicit cast from bool. | 
|  | 17 |  | 
|  | 18 | void implicitCastFromBoolSimpleCases() { | 
|  | 19 | bool boolean = true; | 
|  | 20 |  | 
|  | 21 | functionTaking<bool>(boolean); | 
|  | 22 |  | 
|  | 23 | functionTaking<int>(boolean); | 
|  | 24 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit cast bool -> 'int' [readability-implicit-bool-cast] | 
|  | 25 | // CHECK-FIXES: functionTaking<int>(static_cast<int>(boolean)); | 
|  | 26 |  | 
|  | 27 | functionTaking<unsigned long>(boolean); | 
|  | 28 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast bool -> 'unsigned long' | 
|  | 29 | // CHECK-FIXES: functionTaking<unsigned long>(static_cast<unsigned long>(boolean)); | 
|  | 30 |  | 
|  | 31 | functionTaking<char>(boolean); | 
|  | 32 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'char' | 
|  | 33 | // CHECK-FIXES: functionTaking<char>(static_cast<char>(boolean)); | 
|  | 34 |  | 
|  | 35 | functionTaking<float>(boolean); | 
|  | 36 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' | 
|  | 37 | // CHECK-FIXES: functionTaking<float>(static_cast<float>(boolean)); | 
|  | 38 |  | 
|  | 39 | functionTaking<double>(boolean); | 
|  | 40 | // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' | 
|  | 41 | // CHECK-FIXES: functionTaking<double>(static_cast<double>(boolean)); | 
|  | 42 | } | 
|  | 43 |  | 
|  | 44 | float implicitCastFromBoolInReturnValue() { | 
|  | 45 | bool boolean = false; | 
|  | 46 | return boolean; | 
|  | 47 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast bool -> 'float' | 
|  | 48 | // CHECK-FIXES: return static_cast<float>(boolean); | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | void implicitCastFromBoolInSingleBoolExpressions() { | 
|  | 52 | bool boolean = true; | 
|  | 53 |  | 
|  | 54 | int integer = boolean - 3; | 
|  | 55 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int' | 
|  | 56 | // CHECK-FIXES: int integer = static_cast<int>(boolean) - 3; | 
|  | 57 |  | 
|  | 58 | float floating = boolean / 0.3f; | 
|  | 59 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'float' | 
|  | 60 | // CHECK-FIXES: float floating = static_cast<float>(boolean) / 0.3f; | 
|  | 61 |  | 
|  | 62 | char character = boolean; | 
|  | 63 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'char' | 
|  | 64 | // CHECK-FIXES: char character = static_cast<char>(boolean); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | void implicitCastFromBoollInComplexBoolExpressions() { | 
|  | 68 | bool boolean = true; | 
|  | 69 | bool anotherBoolean = false; | 
|  | 70 |  | 
|  | 71 | int integer = boolean && anotherBoolean; | 
|  | 72 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int' | 
|  | 73 | // CHECK-FIXES: int integer = static_cast<int>(boolean && anotherBoolean); | 
|  | 74 |  | 
|  | 75 | unsigned long unsignedLong = (! boolean) + 4ul; | 
|  | 76 | // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast bool -> 'unsigned long' | 
|  | 77 | // CHECK-FIXES: unsigned long unsignedLong = static_cast<unsigned long>(! boolean) + 4ul; | 
|  | 78 |  | 
|  | 79 | float floating = (boolean || anotherBoolean) * 0.3f; | 
|  | 80 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'float' | 
|  | 81 | // CHECK-FIXES: float floating = static_cast<float>(boolean || anotherBoolean) * 0.3f; | 
|  | 82 |  | 
|  | 83 | double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3; | 
|  | 84 | // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit cast bool -> 'double' | 
|  | 85 | // CHECK-FIXES: double doubleFloating = static_cast<double>(boolean && (anotherBoolean || boolean)) * 0.3; | 
|  | 86 | } | 
|  | 87 |  | 
|  | 88 | void implicitCastFromBoolLiterals() { | 
|  | 89 | functionTaking<int>(true); | 
|  | 90 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit cast bool -> 'int' | 
|  | 91 | // CHECK-FIXES: functionTaking<int>(1); | 
|  | 92 |  | 
|  | 93 | functionTaking<unsigned long>(false); | 
|  | 94 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast bool -> 'unsigned long' | 
|  | 95 | // CHECK-FIXES: functionTaking<unsigned long>(0u); | 
|  | 96 |  | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 97 | functionTaking<signed char>(true); | 
|  | 98 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit cast bool -> 'signed char' | 
|  | 99 | // CHECK-FIXES: functionTaking<signed char>(1); | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 100 |  | 
|  | 101 | functionTaking<float>(false); | 
|  | 102 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' | 
|  | 103 | // CHECK-FIXES: functionTaking<float>(0.0f); | 
|  | 104 |  | 
|  | 105 | functionTaking<double>(true); | 
|  | 106 | // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' | 
|  | 107 | // CHECK-FIXES: functionTaking<double>(1.0); | 
|  | 108 | } | 
|  | 109 |  | 
|  | 110 | void implicitCastFromBoolInComparisons() { | 
|  | 111 | bool boolean = true; | 
|  | 112 | int integer = 0; | 
|  | 113 |  | 
|  | 114 | functionTaking<bool>(boolean == integer); | 
|  | 115 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'int' | 
|  | 116 | // CHECK-FIXES: functionTaking<bool>(static_cast<int>(boolean) == integer); | 
|  | 117 |  | 
|  | 118 | functionTaking<bool>(integer != boolean); | 
|  | 119 | // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit cast bool -> 'int' | 
|  | 120 | // CHECK-FIXES: functionTaking<bool>(integer != static_cast<int>(boolean)); | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | void ignoreBoolComparisons() { | 
|  | 124 | bool boolean = true; | 
|  | 125 | bool anotherBoolean = false; | 
|  | 126 |  | 
|  | 127 | functionTaking<bool>(boolean == anotherBoolean); | 
|  | 128 | functionTaking<bool>(boolean != anotherBoolean); | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | void ignoreExplicitCastsFromBool() { | 
|  | 132 | bool boolean = true; | 
|  | 133 |  | 
|  | 134 | int integer = static_cast<int>(boolean) + 3; | 
|  | 135 | float floating = static_cast<float>(boolean) * 0.3f; | 
|  | 136 | char character = static_cast<char>(boolean); | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | void ignoreImplicitCastFromBoolInMacroExpansions() { | 
|  | 140 | bool boolean = true; | 
|  | 141 |  | 
|  | 142 | #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3 | 
|  | 143 | int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY; | 
|  | 144 |  | 
|  | 145 | #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3 | 
|  | 146 | int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean); | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | namespace ignoreImplicitCastFromBoolInTemplateInstantiations { | 
|  | 150 |  | 
|  | 151 | template<typename T> | 
|  | 152 | void templateFunction() { | 
|  | 153 | bool boolean = true; | 
|  | 154 | T uknownType = boolean + 3; | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | void useOfTemplateFunction() { | 
|  | 158 | templateFunction<int>(); | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | } // namespace ignoreImplicitCastFromBoolInTemplateInstantiations | 
|  | 162 |  | 
|  | 163 | ////////// Implicit cast to bool. | 
|  | 164 |  | 
|  | 165 | void implicitCastToBoolSimpleCases() { | 
|  | 166 | int integer = 10; | 
|  | 167 | functionTaking<bool>(integer); | 
|  | 168 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 169 | // CHECK-FIXES: functionTaking<bool>(integer != 0); | 
|  | 170 |  | 
|  | 171 | unsigned long unsignedLong = 10; | 
|  | 172 | functionTaking<bool>(unsignedLong); | 
|  | 173 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'unsigned long' -> bool | 
|  | 174 | // CHECK-FIXES: functionTaking<bool>(unsignedLong != 0u); | 
|  | 175 |  | 
|  | 176 | float floating = 0.0f; | 
|  | 177 | functionTaking<bool>(floating); | 
|  | 178 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool | 
|  | 179 | // CHECK-FIXES: functionTaking<bool>(floating != 0.0f); | 
|  | 180 |  | 
|  | 181 | double doubleFloating = 1.0f; | 
|  | 182 | functionTaking<bool>(doubleFloating); | 
|  | 183 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool | 
|  | 184 | // CHECK-FIXES: functionTaking<bool>(doubleFloating != 0.0); | 
|  | 185 |  | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 186 | signed char character = 'a'; | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 187 | functionTaking<bool>(character); | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 188 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'signed char' -> bool | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 189 | // CHECK-FIXES: functionTaking<bool>(character != 0); | 
|  | 190 |  | 
|  | 191 | int* pointer = nullptr; | 
|  | 192 | functionTaking<bool>(pointer); | 
|  | 193 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool | 
|  | 194 | // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); | 
|  | 195 |  | 
|  | 196 | auto pointerToMember = &Struct::member; | 
|  | 197 | functionTaking<bool>(pointerToMember); | 
| Alexander Kornienko | cbe8d16 | 2017-05-04 15:34:23 +0000 | [diff] [blame^] | 198 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int Struct::*' -> bool | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 199 | // CHECK-FIXES: functionTaking<bool>(pointerToMember != nullptr); | 
|  | 200 | } | 
|  | 201 |  | 
|  | 202 | void implicitCastToBoolInSingleExpressions() { | 
|  | 203 | int integer = 10; | 
|  | 204 | bool boolComingFromInt = integer; | 
|  | 205 | // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit cast 'int' -> bool | 
|  | 206 | // CHECK-FIXES: bool boolComingFromInt = integer != 0; | 
|  | 207 |  | 
|  | 208 | float floating = 10.0f; | 
|  | 209 | bool boolComingFromFloat = floating; | 
|  | 210 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit cast 'float' -> bool | 
|  | 211 | // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f; | 
|  | 212 |  | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 213 | signed char character = 'a'; | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 214 | bool boolComingFromChar = character; | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 215 | // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit cast 'signed char' -> bool | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 216 | // CHECK-FIXES: bool boolComingFromChar = character != 0; | 
|  | 217 |  | 
|  | 218 | int* pointer = nullptr; | 
|  | 219 | bool boolComingFromPointer = pointer; | 
|  | 220 | // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast 'int *' -> bool | 
|  | 221 | // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr; | 
|  | 222 | } | 
|  | 223 |  | 
|  | 224 | void implicitCastToBoolInComplexExpressions() { | 
|  | 225 | bool boolean = true; | 
|  | 226 |  | 
|  | 227 | int integer = 10; | 
|  | 228 | int anotherInteger = 20; | 
|  | 229 | bool boolComingFromInteger = integer + anotherInteger; | 
|  | 230 | // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast 'int' -> bool | 
|  | 231 | // CHECK-FIXES: bool boolComingFromInteger = (integer + anotherInteger) != 0; | 
|  | 232 |  | 
|  | 233 | float floating = 0.2f; | 
|  | 234 | bool boolComingFromFloating = floating - 0.3f || boolean; | 
|  | 235 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast 'float' -> bool | 
|  | 236 | // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean; | 
|  | 237 |  | 
|  | 238 | double doubleFloating = 0.3; | 
|  | 239 | bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean; | 
|  | 240 | // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'double' -> bool | 
|  | 241 | // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean; | 
|  | 242 | } | 
|  | 243 |  | 
|  | 244 | void implicitCastInNegationExpressions() { | 
|  | 245 | int integer = 10; | 
|  | 246 | bool boolComingFromNegatedInt = !integer; | 
|  | 247 | // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit cast 'int' -> bool | 
|  | 248 | // CHECK-FIXES: bool boolComingFromNegatedInt = integer == 0; | 
|  | 249 |  | 
|  | 250 | float floating = 10.0f; | 
|  | 251 | bool boolComingFromNegatedFloat = ! floating; | 
|  | 252 | // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'float' -> bool | 
|  | 253 | // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f; | 
|  | 254 |  | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 255 | signed char character = 'a'; | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 256 | bool boolComingFromNegatedChar = (! character); | 
| Piotr Dziwinski | 9c5c7a6 | 2015-10-25 17:11:13 +0000 | [diff] [blame] | 257 | // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'signed char' -> bool | 
| Piotr Dziwinski | 7f1b509 | 2015-10-25 15:31:25 +0000 | [diff] [blame] | 258 | // CHECK-FIXES: bool boolComingFromNegatedChar = (character == 0); | 
|  | 259 |  | 
|  | 260 | int* pointer = nullptr; | 
|  | 261 | bool boolComingFromNegatedPointer = not pointer; | 
|  | 262 | // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit cast 'int *' -> bool | 
|  | 263 | // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr; | 
|  | 264 | } | 
|  | 265 |  | 
|  | 266 | void implicitCastToBoolInControlStatements() { | 
|  | 267 | int integer = 10; | 
|  | 268 | if (integer) {} | 
|  | 269 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit cast 'int' -> bool | 
|  | 270 | // CHECK-FIXES: if (integer != 0) {} | 
|  | 271 |  | 
|  | 272 | long int longInteger = 0.2f; | 
|  | 273 | for (;longInteger;) {} | 
|  | 274 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit cast 'long' -> bool | 
|  | 275 | // CHECK-FIXES: for (;longInteger != 0;) {} | 
|  | 276 |  | 
|  | 277 | float floating = 0.3f; | 
|  | 278 | while (floating) {} | 
|  | 279 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast 'float' -> bool | 
|  | 280 | // CHECK-FIXES: while (floating != 0.0f) {} | 
|  | 281 |  | 
|  | 282 | double doubleFloating = 0.4; | 
|  | 283 | do {} while (doubleFloating); | 
|  | 284 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit cast 'double' -> bool | 
|  | 285 | // CHECK-FIXES: do {} while (doubleFloating != 0.0); | 
|  | 286 | } | 
|  | 287 |  | 
|  | 288 | bool implicitCastToBoolInReturnValue() { | 
|  | 289 | float floating = 1.0f; | 
|  | 290 | return floating; | 
|  | 291 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast 'float' -> bool | 
|  | 292 | // CHECK-FIXES: return floating != 0.0f; | 
|  | 293 | } | 
|  | 294 |  | 
|  | 295 | void implicitCastToBoolFromLiterals() { | 
|  | 296 | functionTaking<bool>(0); | 
|  | 297 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 298 | // CHECK-FIXES: functionTaking<bool>(false); | 
|  | 299 |  | 
|  | 300 | functionTaking<bool>(1); | 
|  | 301 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 302 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 303 |  | 
|  | 304 | functionTaking<bool>(2ul); | 
|  | 305 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'unsigned long' -> bool | 
|  | 306 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 307 |  | 
|  | 308 |  | 
|  | 309 | functionTaking<bool>(0.0f); | 
|  | 310 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool | 
|  | 311 | // CHECK-FIXES: functionTaking<bool>(false); | 
|  | 312 |  | 
|  | 313 | functionTaking<bool>(1.0f); | 
|  | 314 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool | 
|  | 315 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 316 |  | 
|  | 317 | functionTaking<bool>(2.0); | 
|  | 318 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool | 
|  | 319 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 320 |  | 
|  | 321 |  | 
|  | 322 | functionTaking<bool>('\0'); | 
|  | 323 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool | 
|  | 324 | // CHECK-FIXES: functionTaking<bool>(false); | 
|  | 325 |  | 
|  | 326 | functionTaking<bool>('a'); | 
|  | 327 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool | 
|  | 328 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 329 |  | 
|  | 330 |  | 
|  | 331 | functionTaking<bool>(""); | 
|  | 332 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'const char *' -> bool | 
|  | 333 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 334 |  | 
|  | 335 | functionTaking<bool>("abc"); | 
|  | 336 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'const char *' -> bool | 
|  | 337 | // CHECK-FIXES: functionTaking<bool>(true); | 
|  | 338 |  | 
|  | 339 | functionTaking<bool>(NULL); | 
|  | 340 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'long' -> bool | 
|  | 341 | // CHECK-FIXES: functionTaking<bool>(false); | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | void implicitCastToBoolFromUnaryMinusAndZeroLiterals() { | 
|  | 345 | functionTaking<bool>(-0); | 
|  | 346 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 347 | // CHECK-FIXES: functionTaking<bool>((-0) != 0); | 
|  | 348 |  | 
|  | 349 | functionTaking<bool>(-0.0f); | 
|  | 350 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool | 
|  | 351 | // CHECK-FIXES: functionTaking<bool>((-0.0f) != 0.0f); | 
|  | 352 |  | 
|  | 353 | functionTaking<bool>(-0.0); | 
|  | 354 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool | 
|  | 355 | // CHECK-FIXES: functionTaking<bool>((-0.0) != 0.0); | 
|  | 356 | } | 
|  | 357 |  | 
|  | 358 | void implicitCastToBoolInWithOverloadedOperators() { | 
|  | 359 | struct UserStruct { | 
|  | 360 | int operator()(int x) { return x; } | 
|  | 361 | int operator+(int y) { return y; } | 
|  | 362 | }; | 
|  | 363 |  | 
|  | 364 | UserStruct s; | 
|  | 365 |  | 
|  | 366 | functionTaking<bool>(s(0)); | 
|  | 367 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 368 | // CHECK-FIXES: functionTaking<bool>(s(0) != 0); | 
|  | 369 |  | 
|  | 370 | functionTaking<bool>(s + 2); | 
|  | 371 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool | 
|  | 372 | // CHECK-FIXES: functionTaking<bool>((s + 2) != 0); | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | int functionReturningInt(); | 
|  | 376 | int* functionReturningPointer(); | 
|  | 377 |  | 
|  | 378 | void ignoreImplicitCastToBoolWhenDeclaringVariableInControlStatements() { | 
|  | 379 | if (int integer = functionReturningInt()) {} | 
|  | 380 |  | 
|  | 381 | while (int* pointer = functionReturningPointer()) {} | 
|  | 382 | } | 
|  | 383 |  | 
|  | 384 | void ignoreExplicitCastsToBool() { | 
|  | 385 | int integer = 10; | 
|  | 386 | bool boolComingFromInt = static_cast<bool>(integer); | 
|  | 387 |  | 
|  | 388 | float floating = 10.0f; | 
|  | 389 | bool boolComingFromFloat = static_cast<bool>(floating); | 
|  | 390 |  | 
|  | 391 | char character = 'a'; | 
|  | 392 | bool boolComingFromChar = static_cast<bool>(character); | 
|  | 393 |  | 
|  | 394 | int* pointer = nullptr; | 
|  | 395 | bool booleanComingFromPointer = static_cast<bool>(pointer); | 
|  | 396 | } | 
|  | 397 |  | 
|  | 398 | void ignoreImplicitCastToBoolInMacroExpansions() { | 
|  | 399 | int integer = 3; | 
|  | 400 |  | 
|  | 401 | #define CAST_TO_BOOL_IN_MACRO_BODY integer && false | 
|  | 402 | bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY; | 
|  | 403 |  | 
|  | 404 | #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true | 
|  | 405 | bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer); | 
|  | 406 | } | 
|  | 407 |  | 
|  | 408 | namespace ignoreImplicitCastToBoolInTemplateInstantiations { | 
|  | 409 |  | 
|  | 410 | template<typename T> | 
|  | 411 | void templateFunction() { | 
|  | 412 | T unknownType = 0; | 
|  | 413 | bool boolean = unknownType; | 
|  | 414 | } | 
|  | 415 |  | 
|  | 416 | void useOfTemplateFunction() { | 
|  | 417 | templateFunction<int>(); | 
|  | 418 | } | 
|  | 419 |  | 
|  | 420 | } // namespace ignoreImplicitCastToBoolInTemplateInstantiations | 
|  | 421 |  | 
|  | 422 | namespace ignoreUserDefinedConversionOperator { | 
|  | 423 |  | 
|  | 424 | struct StructWithUserConversion { | 
|  | 425 | operator bool(); | 
|  | 426 | }; | 
|  | 427 |  | 
|  | 428 | void useOfUserConversion() { | 
|  | 429 | StructWithUserConversion structure; | 
|  | 430 | functionTaking<bool>(structure); | 
|  | 431 | } | 
|  | 432 |  | 
|  | 433 | } // namespace ignoreUserDefinedConversionOperator |