xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp (revision b45527da23ed64a503cc0fd18f63692eb3589748)
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