189a1d03eSRichard // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t 2*b45527daSDa-Viper // RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \ 3*b45527daSDa-Viper // RUN: -config='{CheckOptions: { \ 4*b45527daSDa-Viper // RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \ 5*b45527daSDa-Viper // RUN: }}' 689a1d03eSRichard 789a1d03eSRichard // We need NULL macro, but some buildbots don't like including <cstddef> header 889a1d03eSRichard // This is a portable way of getting it to work 989a1d03eSRichard #undef NULL 1089a1d03eSRichard #define NULL 0L 1189a1d03eSRichard 1289a1d03eSRichard template<typename T> 1389a1d03eSRichard void functionTaking(T); 1489a1d03eSRichard 1589a1d03eSRichard struct Struct { 1689a1d03eSRichard int member; 1789a1d03eSRichard }; 1889a1d03eSRichard 1989a1d03eSRichard 2089a1d03eSRichard ////////// Implicit conversion from bool. 2189a1d03eSRichard 2289a1d03eSRichard void implicitConversionFromBoolSimpleCases() { 2389a1d03eSRichard bool boolean = true; 2489a1d03eSRichard 2589a1d03eSRichard functionTaking<bool>(boolean); 2689a1d03eSRichard 2789a1d03eSRichard functionTaking<int>(boolean); 28fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion] 2989a1d03eSRichard // CHECK-FIXES: functionTaking<int>(static_cast<int>(boolean)); 3089a1d03eSRichard 3189a1d03eSRichard functionTaking<unsigned long>(boolean); 32fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'unsigned long' 3389a1d03eSRichard // CHECK-FIXES: functionTaking<unsigned long>(static_cast<unsigned long>(boolean)); 3489a1d03eSRichard 3589a1d03eSRichard functionTaking<char>(boolean); 36fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'char' 3789a1d03eSRichard // CHECK-FIXES: functionTaking<char>(static_cast<char>(boolean)); 3889a1d03eSRichard 3989a1d03eSRichard functionTaking<float>(boolean); 40fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'bool' -> 'float' 4189a1d03eSRichard // CHECK-FIXES: functionTaking<float>(static_cast<float>(boolean)); 4289a1d03eSRichard 4389a1d03eSRichard functionTaking<double>(boolean); 44fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double' 4589a1d03eSRichard // CHECK-FIXES: functionTaking<double>(static_cast<double>(boolean)); 4689a1d03eSRichard } 4789a1d03eSRichard 4889a1d03eSRichard float implicitConversionFromBoolInReturnValue() { 4989a1d03eSRichard bool boolean = false; 5089a1d03eSRichard return boolean; 51fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'bool' -> 'float' 5289a1d03eSRichard // CHECK-FIXES: return static_cast<float>(boolean); 5389a1d03eSRichard } 5489a1d03eSRichard 5589a1d03eSRichard void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) { 5689a1d03eSRichard bool boolean = true; 5789a1d03eSRichard boolean = b1 ^ b2; 5889a1d03eSRichard boolean = b1 && b2; 5989a1d03eSRichard boolean |= !b1 || !b2; 6089a1d03eSRichard boolean &= b1; 6189a1d03eSRichard boolean = b1 == true; 6289a1d03eSRichard boolean = b2 != false; 6389a1d03eSRichard 6489a1d03eSRichard int integer = boolean - 3; 65fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int' 6689a1d03eSRichard // CHECK-FIXES: int integer = static_cast<int>(boolean) - 3; 6789a1d03eSRichard 6889a1d03eSRichard float floating = boolean / 0.3f; 69fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float' 7089a1d03eSRichard // CHECK-FIXES: float floating = static_cast<float>(boolean) / 0.3f; 7189a1d03eSRichard 7289a1d03eSRichard char character = boolean; 73fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'char' 7489a1d03eSRichard // CHECK-FIXES: char character = static_cast<char>(boolean); 7589a1d03eSRichard } 7689a1d03eSRichard 7789a1d03eSRichard void implicitConversionFromBoollInComplexBoolExpressions() { 7889a1d03eSRichard bool boolean = true; 7989a1d03eSRichard bool anotherBoolean = false; 8089a1d03eSRichard 8189a1d03eSRichard int integer = boolean && anotherBoolean; 82fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int' 8389a1d03eSRichard // CHECK-FIXES: int integer = static_cast<int>(boolean && anotherBoolean); 8489a1d03eSRichard 8589a1d03eSRichard unsigned long unsignedLong = (! boolean) + 4ul; 86fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'bool' -> 'unsigned long' 8789a1d03eSRichard // CHECK-FIXES: unsigned long unsignedLong = static_cast<unsigned long>(! boolean) + 4ul; 8889a1d03eSRichard 8989a1d03eSRichard float floating = (boolean || anotherBoolean) * 0.3f; 90fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float' 9189a1d03eSRichard // CHECK-FIXES: float floating = static_cast<float>(boolean || anotherBoolean) * 0.3f; 9289a1d03eSRichard 9389a1d03eSRichard double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3; 94fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'bool' -> 'double' 9589a1d03eSRichard // CHECK-FIXES: double doubleFloating = static_cast<double>(boolean && (anotherBoolean || boolean)) * 0.3; 9689a1d03eSRichard } 9789a1d03eSRichard 9889a1d03eSRichard void implicitConversionFromBoolLiterals() { 9989a1d03eSRichard functionTaking<int>(true); 100fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'int' 10189a1d03eSRichard // CHECK-FIXES: functionTaking<int>(1); 10289a1d03eSRichard 10389a1d03eSRichard functionTaking<unsigned long>(false); 104fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'unsigned long' 10589a1d03eSRichard // CHECK-FIXES: functionTaking<unsigned long>(0u); 106*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: functionTaking<unsigned long>(0U); 10789a1d03eSRichard 10889a1d03eSRichard functionTaking<signed char>(true); 109fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit conversion 'bool' -> 'signed char' 11089a1d03eSRichard // CHECK-FIXES: functionTaking<signed char>(1); 11189a1d03eSRichard 11289a1d03eSRichard functionTaking<float>(false); 113fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'bool' -> 'float' 11489a1d03eSRichard // CHECK-FIXES: functionTaking<float>(0.0f); 115*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: functionTaking<float>(0.0F); 11689a1d03eSRichard 11789a1d03eSRichard functionTaking<double>(true); 118fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double' 11989a1d03eSRichard // CHECK-FIXES: functionTaking<double>(1.0); 12089a1d03eSRichard } 12189a1d03eSRichard 12289a1d03eSRichard void implicitConversionFromBoolInComparisons() { 12389a1d03eSRichard bool boolean = true; 12489a1d03eSRichard int integer = 0; 12589a1d03eSRichard 12689a1d03eSRichard functionTaking<bool>(boolean == integer); 127fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'int' 12889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(static_cast<int>(boolean) == integer); 12989a1d03eSRichard 13089a1d03eSRichard functionTaking<bool>(integer != boolean); 131fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit conversion 'bool' -> 'int' 13289a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(integer != static_cast<int>(boolean)); 13389a1d03eSRichard } 13489a1d03eSRichard 13589a1d03eSRichard void ignoreBoolComparisons() { 13689a1d03eSRichard bool boolean = true; 13789a1d03eSRichard bool anotherBoolean = false; 13889a1d03eSRichard 13989a1d03eSRichard functionTaking<bool>(boolean == anotherBoolean); 14089a1d03eSRichard functionTaking<bool>(boolean != anotherBoolean); 14189a1d03eSRichard } 14289a1d03eSRichard 14389a1d03eSRichard void ignoreExplicitCastsFromBool() { 14489a1d03eSRichard bool boolean = true; 14589a1d03eSRichard 14689a1d03eSRichard int integer = static_cast<int>(boolean) + 3; 14789a1d03eSRichard float floating = static_cast<float>(boolean) * 0.3f; 14889a1d03eSRichard char character = static_cast<char>(boolean); 14989a1d03eSRichard } 15089a1d03eSRichard 15189a1d03eSRichard void ignoreImplicitConversionFromBoolInMacroExpansions() { 15289a1d03eSRichard bool boolean = true; 15389a1d03eSRichard 15489a1d03eSRichard #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3 15589a1d03eSRichard int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY; 15689a1d03eSRichard 15789a1d03eSRichard #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3 15889a1d03eSRichard int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean); 15989a1d03eSRichard } 16089a1d03eSRichard 16189a1d03eSRichard namespace ignoreImplicitConversionFromBoolInTemplateInstantiations { 16289a1d03eSRichard 16389a1d03eSRichard template<typename T> 16489a1d03eSRichard void templateFunction() { 16589a1d03eSRichard bool boolean = true; 16689a1d03eSRichard T uknownType = boolean + 3; 16789a1d03eSRichard } 16889a1d03eSRichard 16989a1d03eSRichard void useOfTemplateFunction() { 17089a1d03eSRichard templateFunction<int>(); 17189a1d03eSRichard } 17289a1d03eSRichard 17389a1d03eSRichard } // namespace ignoreImplicitConversionFromBoolInTemplateInstantiations 17489a1d03eSRichard 17589a1d03eSRichard ////////// Implicit conversions to bool. 17689a1d03eSRichard 17789a1d03eSRichard void implicitConversionToBoolSimpleCases() { 17889a1d03eSRichard int integer = 10; 17989a1d03eSRichard functionTaking<bool>(integer); 180fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 18189a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(integer != 0); 18289a1d03eSRichard 18389a1d03eSRichard unsigned long unsignedLong = 10; 18489a1d03eSRichard functionTaking<bool>(unsignedLong); 185fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> 'bool' 18689a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(unsignedLong != 0u); 187*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(unsignedLong != 0U); 18889a1d03eSRichard 18989a1d03eSRichard float floating = 0.0f; 19089a1d03eSRichard functionTaking<bool>(floating); 191fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool' 19289a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(floating != 0.0f); 193*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(floating != 0.0F); 19489a1d03eSRichard 19589a1d03eSRichard double doubleFloating = 1.0f; 19689a1d03eSRichard functionTaking<bool>(doubleFloating); 197fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool' 19889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(doubleFloating != 0.0); 19989a1d03eSRichard 20089a1d03eSRichard signed char character = 'a'; 20189a1d03eSRichard functionTaking<bool>(character); 202fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> 'bool' 20389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(character != 0); 20489a1d03eSRichard 20589a1d03eSRichard int* pointer = nullptr; 20689a1d03eSRichard functionTaking<bool>(pointer); 207fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool' 20889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); 20989a1d03eSRichard 21089a1d03eSRichard auto pointerToMember = &Struct::member; 21189a1d03eSRichard functionTaking<bool>(pointerToMember); 212fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool' 21389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(pointerToMember != nullptr); 21489a1d03eSRichard } 21589a1d03eSRichard 21689a1d03eSRichard void implicitConversionToBoolInSingleExpressions() { 21789a1d03eSRichard int integer = 10; 21889a1d03eSRichard bool boolComingFromInt = integer; 219fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'int' -> 'bool' 22089a1d03eSRichard // CHECK-FIXES: bool boolComingFromInt = integer != 0; 22189a1d03eSRichard 22289a1d03eSRichard float floating = 10.0f; 22389a1d03eSRichard bool boolComingFromFloat = floating; 224fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'float' -> 'bool' 22589a1d03eSRichard // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f; 226*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloat = floating != 0.0F; 22789a1d03eSRichard 22889a1d03eSRichard signed char character = 'a'; 22989a1d03eSRichard bool boolComingFromChar = character; 230fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit conversion 'signed char' -> 'bool' 23189a1d03eSRichard // CHECK-FIXES: bool boolComingFromChar = character != 0; 23289a1d03eSRichard 23389a1d03eSRichard int* pointer = nullptr; 23489a1d03eSRichard bool boolComingFromPointer = pointer; 235fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int *' -> 'bool' 23689a1d03eSRichard // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr; 23789a1d03eSRichard } 23889a1d03eSRichard 23989a1d03eSRichard void implicitConversionToBoolInComplexExpressions() { 24089a1d03eSRichard bool boolean = true; 24189a1d03eSRichard 24289a1d03eSRichard int integer = 10; 24389a1d03eSRichard int anotherInteger = 20; 24489a1d03eSRichard bool boolComingFromInteger = integer + anotherInteger; 245fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int' -> 'bool' 24689a1d03eSRichard // CHECK-FIXES: bool boolComingFromInteger = (integer + anotherInteger) != 0; 24789a1d03eSRichard 24889a1d03eSRichard float floating = 0.2f; 24989a1d03eSRichard bool boolComingFromFloating = floating - 0.3f || boolean; 250fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'float' -> 'bool' 25189a1d03eSRichard // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean; 252*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloating = ((floating - 0.3f) != 0.0F) || boolean; 25389a1d03eSRichard 25489a1d03eSRichard double doubleFloating = 0.3; 25589a1d03eSRichard bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean; 256fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'double' -> 'bool' 25789a1d03eSRichard // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean; 25889a1d03eSRichard } 25989a1d03eSRichard 26089a1d03eSRichard void implicitConversionInNegationExpressions() { 26189a1d03eSRichard int integer = 10; 26289a1d03eSRichard bool boolComingFromNegatedInt = !integer; 263fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit conversion 'int' -> 'bool' 26489a1d03eSRichard // CHECK-FIXES: bool boolComingFromNegatedInt = integer == 0; 26589a1d03eSRichard 26689a1d03eSRichard float floating = 10.0f; 26789a1d03eSRichard bool boolComingFromNegatedFloat = ! floating; 268fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'float' -> 'bool' 26989a1d03eSRichard // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f; 270*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: bool boolComingFromNegatedFloat = floating == 0.0F; 27189a1d03eSRichard 27289a1d03eSRichard signed char character = 'a'; 27389a1d03eSRichard bool boolComingFromNegatedChar = (! character); 274fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'signed char' -> 'bool' 27589a1d03eSRichard // CHECK-FIXES: bool boolComingFromNegatedChar = (character == 0); 27689a1d03eSRichard 27789a1d03eSRichard int* pointer = nullptr; 27889a1d03eSRichard bool boolComingFromNegatedPointer = not pointer; 279fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit conversion 'int *' -> 'bool' 28089a1d03eSRichard // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr; 28189a1d03eSRichard } 28289a1d03eSRichard 28389a1d03eSRichard void implicitConversionToBoolInControlStatements() { 28489a1d03eSRichard int integer = 10; 28589a1d03eSRichard if (integer) {} 286fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit conversion 'int' -> 'bool' 28789a1d03eSRichard // CHECK-FIXES: if (integer != 0) {} 28889a1d03eSRichard 28989a1d03eSRichard long int longInteger = 0.2f; 29089a1d03eSRichard for (;longInteger;) {} 291fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'long' -> 'bool' 29289a1d03eSRichard // CHECK-FIXES: for (;longInteger != 0;) {} 29389a1d03eSRichard 29489a1d03eSRichard float floating = 0.3f; 29589a1d03eSRichard while (floating) {} 296fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool' 29789a1d03eSRichard // CHECK-FIXES: while (floating != 0.0f) {} 298*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: while (floating != 0.0F) {} 29989a1d03eSRichard 30089a1d03eSRichard double doubleFloating = 0.4; 30189a1d03eSRichard do {} while (doubleFloating); 302fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit conversion 'double' -> 'bool' 30389a1d03eSRichard // CHECK-FIXES: do {} while (doubleFloating != 0.0); 30489a1d03eSRichard } 30589a1d03eSRichard 30689a1d03eSRichard bool implicitConversionToBoolInReturnValue() { 30789a1d03eSRichard float floating = 1.0f; 30889a1d03eSRichard return floating; 309fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool' 31089a1d03eSRichard // CHECK-FIXES: return floating != 0.0f; 311*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: return floating != 0.0F; 31289a1d03eSRichard } 31389a1d03eSRichard 31489a1d03eSRichard void implicitConversionToBoolFromLiterals() { 31589a1d03eSRichard functionTaking<bool>(0); 316fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 31789a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(false); 31889a1d03eSRichard 31989a1d03eSRichard functionTaking<bool>(1); 320fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 32189a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 32289a1d03eSRichard 32389a1d03eSRichard functionTaking<bool>(2ul); 324fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> 'bool' 32589a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 32689a1d03eSRichard 32789a1d03eSRichard 32889a1d03eSRichard functionTaking<bool>(0.0f); 329fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool' 33089a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(false); 33189a1d03eSRichard 33289a1d03eSRichard functionTaking<bool>(1.0f); 333fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool' 33489a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 33589a1d03eSRichard 33689a1d03eSRichard functionTaking<bool>(2.0); 337fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool' 33889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 33989a1d03eSRichard 34089a1d03eSRichard 34189a1d03eSRichard functionTaking<bool>('\0'); 342fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> 'bool' 34389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(false); 34489a1d03eSRichard 34589a1d03eSRichard functionTaking<bool>('a'); 346fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> 'bool' 34789a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 34889a1d03eSRichard 34989a1d03eSRichard 35089a1d03eSRichard functionTaking<bool>(""); 351fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> 'bool' 35289a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 35389a1d03eSRichard 35489a1d03eSRichard functionTaking<bool>("abc"); 355fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> 'bool' 35689a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(true); 35789a1d03eSRichard 35889a1d03eSRichard functionTaking<bool>(NULL); 359fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> 'bool' 36089a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(false); 36189a1d03eSRichard } 36289a1d03eSRichard 36389a1d03eSRichard void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() { 36489a1d03eSRichard functionTaking<bool>(-0); 365fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 36689a1d03eSRichard // CHECK-FIXES: functionTaking<bool>((-0) != 0); 36789a1d03eSRichard 36889a1d03eSRichard functionTaking<bool>(-0.0f); 369fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool' 37089a1d03eSRichard // CHECK-FIXES: functionTaking<bool>((-0.0f) != 0.0f); 371*b45527daSDa-Viper // CHECK-FIXES-UPPER-CASE: functionTaking<bool>((-0.0f) != 0.0F); 37289a1d03eSRichard 37389a1d03eSRichard functionTaking<bool>(-0.0); 374fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool' 37589a1d03eSRichard // CHECK-FIXES: functionTaking<bool>((-0.0) != 0.0); 37689a1d03eSRichard } 37789a1d03eSRichard 37889a1d03eSRichard void implicitConversionToBoolInWithOverloadedOperators() { 37989a1d03eSRichard struct UserStruct { 38089a1d03eSRichard int operator()(int x) { return x; } 38189a1d03eSRichard int operator+(int y) { return y; } 38289a1d03eSRichard }; 38389a1d03eSRichard 38489a1d03eSRichard UserStruct s; 38589a1d03eSRichard 38689a1d03eSRichard functionTaking<bool>(s(0)); 387fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 38889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(s(0) != 0); 38989a1d03eSRichard 39089a1d03eSRichard functionTaking<bool>(s + 2); 391fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 39289a1d03eSRichard // CHECK-FIXES: functionTaking<bool>((s + 2) != 0); 39389a1d03eSRichard } 39489a1d03eSRichard 39589a1d03eSRichard int functionReturningInt(); 39689a1d03eSRichard int* functionReturningPointer(); 39789a1d03eSRichard 39889a1d03eSRichard void ignoreImplicitConversionToBoolWhenDeclaringVariableInControlStatements() { 39989a1d03eSRichard if (int integer = functionReturningInt()) {} 40089a1d03eSRichard 40189a1d03eSRichard while (int* pointer = functionReturningPointer()) {} 40289a1d03eSRichard } 40389a1d03eSRichard 40489a1d03eSRichard void ignoreExplicitCastsToBool() { 40589a1d03eSRichard int integer = 10; 40689a1d03eSRichard bool boolComingFromInt = static_cast<bool>(integer); 40789a1d03eSRichard 40889a1d03eSRichard float floating = 10.0f; 40989a1d03eSRichard bool boolComingFromFloat = static_cast<bool>(floating); 41089a1d03eSRichard 41189a1d03eSRichard char character = 'a'; 41289a1d03eSRichard bool boolComingFromChar = static_cast<bool>(character); 41389a1d03eSRichard 41489a1d03eSRichard int* pointer = nullptr; 41589a1d03eSRichard bool booleanComingFromPointer = static_cast<bool>(pointer); 41689a1d03eSRichard } 41789a1d03eSRichard 41889a1d03eSRichard void ignoreImplicitConversionToBoolInMacroExpansions() { 41989a1d03eSRichard int integer = 3; 42089a1d03eSRichard 42189a1d03eSRichard #define CAST_TO_BOOL_IN_MACRO_BODY integer && false 42289a1d03eSRichard bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY; 42389a1d03eSRichard 42489a1d03eSRichard #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true 42589a1d03eSRichard bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer); 42689a1d03eSRichard } 42789a1d03eSRichard 42889a1d03eSRichard namespace ignoreImplicitConversionToBoolInTemplateInstantiations { 42989a1d03eSRichard 43089a1d03eSRichard template<typename T> 43189a1d03eSRichard void templateFunction() { 43289a1d03eSRichard T unknownType = 0; 43389a1d03eSRichard bool boolean = unknownType; 43489a1d03eSRichard } 43589a1d03eSRichard 43689a1d03eSRichard void useOfTemplateFunction() { 43789a1d03eSRichard templateFunction<int>(); 43889a1d03eSRichard } 43989a1d03eSRichard 44089a1d03eSRichard } // namespace ignoreImplicitConversionToBoolInTemplateInstantiations 44189a1d03eSRichard 44289a1d03eSRichard namespace ignoreUserDefinedConversionOperator { 44389a1d03eSRichard 44489a1d03eSRichard struct StructWithUserConversion { 44589a1d03eSRichard operator bool(); 44689a1d03eSRichard }; 44789a1d03eSRichard 44889a1d03eSRichard void useOfUserConversion() { 44989a1d03eSRichard StructWithUserConversion structure; 45089a1d03eSRichard functionTaking<bool>(structure); 45189a1d03eSRichard } 45289a1d03eSRichard 45389a1d03eSRichard } // namespace ignoreUserDefinedConversionOperator 45489a1d03eSRichard 45589a1d03eSRichard namespace ignore_1bit_bitfields { 45689a1d03eSRichard 45789a1d03eSRichard struct S { 45889a1d03eSRichard int a; 45989a1d03eSRichard int b : 1; 46089a1d03eSRichard int c : 2; 46189a1d03eSRichard 46289a1d03eSRichard S(bool a, bool b, bool c) : a(a), b(b), c(c) {} 463fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int' 464fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion 'bool' -> 'int' 46589a1d03eSRichard // CHECK-FIXES: S(bool a, bool b, bool c) : a(static_cast<int>(a)), b(b), c(static_cast<int>(c)) {} 46689a1d03eSRichard }; 46789a1d03eSRichard 46889a1d03eSRichard bool f(S& s) { 46989a1d03eSRichard functionTaking<bool>(s.a); 470fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 47189a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(s.a != 0); 47289a1d03eSRichard functionTaking<bool>(s.b); 47389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(s.b); 47489a1d03eSRichard s.a = true; 475fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' 47689a1d03eSRichard // CHECK-FIXES: s.a = 1; 47789a1d03eSRichard s.b = true; 47889a1d03eSRichard // CHECK-FIXES: s.b = true; 47989a1d03eSRichard s.c = true; 480fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' 48189a1d03eSRichard // CHECK-FIXES: s.c = 1; 48289a1d03eSRichard functionTaking<bool>(s.c); 483fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' 48489a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(s.c != 0); 48589a1d03eSRichard } 48689a1d03eSRichard 48789a1d03eSRichard } // namespace ignore_1bit_bitfields 488dfa8f5b1SPiotr Zegar 4892602d888SFélix-Antoine Constantin int implicitConversionReturnInt() 4902602d888SFélix-Antoine Constantin { 4912602d888SFélix-Antoine Constantin return true; 492fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' 4932602d888SFélix-Antoine Constantin // CHECK-FIXES: return 1 4942602d888SFélix-Antoine Constantin } 4952602d888SFélix-Antoine Constantin 4962602d888SFélix-Antoine Constantin int implicitConversionReturnIntWithParens() 4972602d888SFélix-Antoine Constantin { 4982602d888SFélix-Antoine Constantin return (true); 499fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' 5002602d888SFélix-Antoine Constantin // CHECK-FIXES: return 1 5012602d888SFélix-Antoine Constantin } 5022602d888SFélix-Antoine Constantin 5032602d888SFélix-Antoine Constantin 5042602d888SFélix-Antoine Constantin bool implicitConversionReturnBool() 5052602d888SFélix-Antoine Constantin { 5062602d888SFélix-Antoine Constantin return 1; 507fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' 5082602d888SFélix-Antoine Constantin // CHECK-FIXES: return true 5092602d888SFélix-Antoine Constantin } 5102602d888SFélix-Antoine Constantin 5112602d888SFélix-Antoine Constantin bool implicitConversionReturnBoolWithParens() 5122602d888SFélix-Antoine Constantin { 5132602d888SFélix-Antoine Constantin return (1); 514fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' 5152602d888SFélix-Antoine Constantin // CHECK-FIXES: return true 5162602d888SFélix-Antoine Constantin } 5172602d888SFélix-Antoine Constantin 5182602d888SFélix-Antoine Constantin 519dfa8f5b1SPiotr Zegar namespace PR47000 { 520dfa8f5b1SPiotr Zegar int to_int(bool x) { return int{x}; } 521dfa8f5b1SPiotr Zegar 522dfa8f5b1SPiotr Zegar using IntType = int; 523dfa8f5b1SPiotr Zegar int to_int2(bool x) { return IntType{x}; } 524dfa8f5b1SPiotr Zegar } 525fd0e06d1SPiotr Zegar 526fd0e06d1SPiotr Zegar namespace PR71867 { 527fd0e06d1SPiotr Zegar bool foo(bool x) { 528fd0e06d1SPiotr Zegar return x ? 1 : false; 529fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' 530fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: implicit conversion 'bool' -> 'int' 531fd0e06d1SPiotr Zegar // CHECK-FIXES: return (x ? 1 : 0) != 0; 532fd0e06d1SPiotr Zegar } 533fd0e06d1SPiotr Zegar 534fd0e06d1SPiotr Zegar bool boo(bool x) { 535fd0e06d1SPiotr Zegar return x ? true : 0; 536fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' 537fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: implicit conversion 'bool' -> 'int' 538fd0e06d1SPiotr Zegar // CHECK-FIXES: return (x ? 1 : 0) != 0; 539fd0e06d1SPiotr Zegar } 540fd0e06d1SPiotr Zegar } 5413496927eSPiotr Zegar 5423496927eSPiotr Zegar namespace PR71848 { 5433496927eSPiotr Zegar int fun() { 5443496927eSPiotr Zegar bool foo = false; 5453496927eSPiotr Zegar return( foo ); 5463496927eSPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion] 5473496927eSPiotr Zegar // CHECK-FIXES: return static_cast<int>( foo ); 5483496927eSPiotr Zegar } 5493496927eSPiotr Zegar } 550