xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp (revision b45527da23ed64a503cc0fd18f63692eb3589748)
1 // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t
2 // RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
3 // RUN:     -config='{CheckOptions: { \
4 // RUN:         readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
5 // RUN:     }}'
6 
7 // We need NULL macro, but some buildbots don't like including <cstddef> header
8 // This is a portable way of getting it to work
9 #undef NULL
10 #define NULL 0L
11 
12 template<typename T>
13 void functionTaking(T);
14 
15 struct Struct {
16   int member;
17 };
18 
19 
20 ////////// Implicit conversion from bool.
21 
22 void implicitConversionFromBoolSimpleCases() {
23   bool boolean = true;
24 
25   functionTaking<bool>(boolean);
26 
27   functionTaking<int>(boolean);
28   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion]
29   // CHECK-FIXES: functionTaking<int>(static_cast<int>(boolean));
30 
31   functionTaking<unsigned long>(boolean);
32   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'unsigned long'
33   // CHECK-FIXES: functionTaking<unsigned long>(static_cast<unsigned long>(boolean));
34 
35   functionTaking<char>(boolean);
36   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'char'
37   // CHECK-FIXES: functionTaking<char>(static_cast<char>(boolean));
38 
39   functionTaking<float>(boolean);
40   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'bool' -> 'float'
41   // CHECK-FIXES: functionTaking<float>(static_cast<float>(boolean));
42 
43   functionTaking<double>(boolean);
44   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double'
45   // CHECK-FIXES: functionTaking<double>(static_cast<double>(boolean));
46 }
47 
48 float implicitConversionFromBoolInReturnValue() {
49   bool boolean = false;
50   return boolean;
51   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'bool' -> 'float'
52   // CHECK-FIXES: return static_cast<float>(boolean);
53 }
54 
55 void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) {
56   bool boolean = true;
57   boolean = b1 ^ b2;
58   boolean = b1 && b2;
59   boolean |= !b1 || !b2;
60   boolean &= b1;
61   boolean = b1 == true;
62   boolean = b2 != false;
63 
64   int integer = boolean - 3;
65   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int'
66   // CHECK-FIXES: int integer = static_cast<int>(boolean) - 3;
67 
68   float floating = boolean / 0.3f;
69   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float'
70   // CHECK-FIXES: float floating = static_cast<float>(boolean) / 0.3f;
71 
72   char character = boolean;
73   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'char'
74   // CHECK-FIXES: char character = static_cast<char>(boolean);
75 }
76 
77 void implicitConversionFromBoollInComplexBoolExpressions() {
78   bool boolean = true;
79   bool anotherBoolean = false;
80 
81   int integer = boolean && anotherBoolean;
82   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int'
83   // CHECK-FIXES: int integer = static_cast<int>(boolean && anotherBoolean);
84 
85   unsigned long unsignedLong = (! boolean) + 4ul;
86   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'bool' -> 'unsigned long'
87   // CHECK-FIXES: unsigned long unsignedLong = static_cast<unsigned long>(! boolean) + 4ul;
88 
89   float floating = (boolean || anotherBoolean) * 0.3f;
90   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float'
91   // CHECK-FIXES: float floating = static_cast<float>(boolean || anotherBoolean) * 0.3f;
92 
93   double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3;
94   // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'bool' -> 'double'
95   // CHECK-FIXES: double doubleFloating = static_cast<double>(boolean && (anotherBoolean || boolean)) * 0.3;
96 }
97 
98 void implicitConversionFromBoolLiterals() {
99   functionTaking<int>(true);
100   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'int'
101   // CHECK-FIXES: functionTaking<int>(1);
102 
103   functionTaking<unsigned long>(false);
104   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'unsigned long'
105   // CHECK-FIXES: functionTaking<unsigned long>(0u);
106   // CHECK-FIXES-UPPER-CASE: functionTaking<unsigned long>(0U);
107 
108   functionTaking<signed char>(true);
109   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit conversion 'bool' -> 'signed char'
110   // CHECK-FIXES: functionTaking<signed char>(1);
111 
112   functionTaking<float>(false);
113   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'bool' -> 'float'
114   // CHECK-FIXES: functionTaking<float>(0.0f);
115   // CHECK-FIXES-UPPER-CASE: functionTaking<float>(0.0F);
116 
117   functionTaking<double>(true);
118   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double'
119   // CHECK-FIXES: functionTaking<double>(1.0);
120 }
121 
122 void implicitConversionFromBoolInComparisons() {
123   bool boolean = true;
124   int integer = 0;
125 
126   functionTaking<bool>(boolean == integer);
127   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'int'
128   // CHECK-FIXES: functionTaking<bool>(static_cast<int>(boolean) == integer);
129 
130   functionTaking<bool>(integer != boolean);
131   // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit conversion 'bool' -> 'int'
132   // CHECK-FIXES: functionTaking<bool>(integer != static_cast<int>(boolean));
133 }
134 
135 void ignoreBoolComparisons() {
136   bool boolean = true;
137   bool anotherBoolean = false;
138 
139   functionTaking<bool>(boolean == anotherBoolean);
140   functionTaking<bool>(boolean != anotherBoolean);
141 }
142 
143 void ignoreExplicitCastsFromBool() {
144   bool boolean = true;
145 
146   int integer = static_cast<int>(boolean) + 3;
147   float floating = static_cast<float>(boolean) * 0.3f;
148   char character = static_cast<char>(boolean);
149 }
150 
151 void ignoreImplicitConversionFromBoolInMacroExpansions() {
152   bool boolean = true;
153 
154   #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3
155   int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY;
156 
157   #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3
158   int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean);
159 }
160 
161 namespace ignoreImplicitConversionFromBoolInTemplateInstantiations {
162 
163 template<typename T>
164 void templateFunction() {
165   bool boolean = true;
166   T uknownType = boolean + 3;
167 }
168 
169 void useOfTemplateFunction() {
170   templateFunction<int>();
171 }
172 
173 } // namespace ignoreImplicitConversionFromBoolInTemplateInstantiations
174 
175 ////////// Implicit conversions to bool.
176 
177 void implicitConversionToBoolSimpleCases() {
178   int integer = 10;
179   functionTaking<bool>(integer);
180   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
181   // CHECK-FIXES: functionTaking<bool>(integer != 0);
182 
183   unsigned long unsignedLong = 10;
184   functionTaking<bool>(unsignedLong);
185   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> 'bool'
186   // CHECK-FIXES: functionTaking<bool>(unsignedLong != 0u);
187   // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(unsignedLong != 0U);
188 
189   float floating = 0.0f;
190   functionTaking<bool>(floating);
191   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
192   // CHECK-FIXES: functionTaking<bool>(floating != 0.0f);
193   // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(floating != 0.0F);
194 
195   double doubleFloating = 1.0f;
196   functionTaking<bool>(doubleFloating);
197   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool'
198   // CHECK-FIXES: functionTaking<bool>(doubleFloating != 0.0);
199 
200   signed char character = 'a';
201   functionTaking<bool>(character);
202   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> 'bool'
203   // CHECK-FIXES: functionTaking<bool>(character != 0);
204 
205   int* pointer = nullptr;
206   functionTaking<bool>(pointer);
207   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool'
208   // CHECK-FIXES: functionTaking<bool>(pointer != nullptr);
209 
210   auto pointerToMember = &Struct::member;
211   functionTaking<bool>(pointerToMember);
212   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool'
213   // CHECK-FIXES: functionTaking<bool>(pointerToMember != nullptr);
214 }
215 
216 void implicitConversionToBoolInSingleExpressions() {
217   int integer = 10;
218   bool boolComingFromInt = integer;
219   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'int' -> 'bool'
220   // CHECK-FIXES: bool boolComingFromInt = integer != 0;
221 
222   float floating = 10.0f;
223   bool boolComingFromFloat = floating;
224   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'float' -> 'bool'
225   // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f;
226   // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloat = floating != 0.0F;
227 
228   signed char character = 'a';
229   bool boolComingFromChar = character;
230   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit conversion 'signed char' -> 'bool'
231   // CHECK-FIXES: bool boolComingFromChar = character != 0;
232 
233   int* pointer = nullptr;
234   bool boolComingFromPointer = pointer;
235   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int *' -> 'bool'
236   // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr;
237 }
238 
239 void implicitConversionToBoolInComplexExpressions() {
240   bool boolean = true;
241 
242   int integer = 10;
243   int anotherInteger = 20;
244   bool boolComingFromInteger = integer + anotherInteger;
245   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int' -> 'bool'
246   // CHECK-FIXES: bool boolComingFromInteger = (integer + anotherInteger) != 0;
247 
248   float floating = 0.2f;
249   bool boolComingFromFloating = floating - 0.3f || boolean;
250   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'float' -> 'bool'
251   // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean;
252   // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloating = ((floating - 0.3f) != 0.0F) || boolean;
253 
254   double doubleFloating = 0.3;
255   bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean;
256   // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'double' -> 'bool'
257   // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean;
258 }
259 
260 void implicitConversionInNegationExpressions() {
261   int integer = 10;
262   bool boolComingFromNegatedInt = !integer;
263   // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit conversion 'int' -> 'bool'
264   // CHECK-FIXES: bool boolComingFromNegatedInt = integer == 0;
265 
266   float floating = 10.0f;
267   bool boolComingFromNegatedFloat = ! floating;
268   // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'float' -> 'bool'
269   // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f;
270   // CHECK-FIXES-UPPER-CASE: bool boolComingFromNegatedFloat = floating == 0.0F;
271 
272   signed char character = 'a';
273   bool boolComingFromNegatedChar = (! character);
274   // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'signed char' -> 'bool'
275   // CHECK-FIXES: bool boolComingFromNegatedChar = (character == 0);
276 
277   int* pointer = nullptr;
278   bool boolComingFromNegatedPointer = not pointer;
279   // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit conversion 'int *' -> 'bool'
280   // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr;
281 }
282 
283 void implicitConversionToBoolInControlStatements() {
284   int integer = 10;
285   if (integer) {}
286   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit conversion 'int' -> 'bool'
287   // CHECK-FIXES: if (integer != 0) {}
288 
289   long int longInteger = 0.2f;
290   for (;longInteger;) {}
291   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'long' -> 'bool'
292   // CHECK-FIXES: for (;longInteger != 0;) {}
293 
294   float floating = 0.3f;
295   while (floating) {}
296   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
297   // CHECK-FIXES: while (floating != 0.0f) {}
298   // CHECK-FIXES-UPPER-CASE: while (floating != 0.0F) {}
299 
300   double doubleFloating = 0.4;
301   do {} while (doubleFloating);
302   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit conversion 'double' -> 'bool'
303   // CHECK-FIXES: do {} while (doubleFloating != 0.0);
304 }
305 
306 bool implicitConversionToBoolInReturnValue() {
307   float floating = 1.0f;
308   return floating;
309   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
310   // CHECK-FIXES: return floating != 0.0f;
311   // CHECK-FIXES-UPPER-CASE: return floating != 0.0F;
312 }
313 
314 void implicitConversionToBoolFromLiterals() {
315   functionTaking<bool>(0);
316   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
317   // CHECK-FIXES: functionTaking<bool>(false);
318 
319   functionTaking<bool>(1);
320   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
321   // CHECK-FIXES: functionTaking<bool>(true);
322 
323   functionTaking<bool>(2ul);
324   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> 'bool'
325   // CHECK-FIXES: functionTaking<bool>(true);
326 
327 
328   functionTaking<bool>(0.0f);
329   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
330   // CHECK-FIXES: functionTaking<bool>(false);
331 
332   functionTaking<bool>(1.0f);
333   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
334   // CHECK-FIXES: functionTaking<bool>(true);
335 
336   functionTaking<bool>(2.0);
337   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool'
338   // CHECK-FIXES: functionTaking<bool>(true);
339 
340 
341   functionTaking<bool>('\0');
342   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> 'bool'
343   // CHECK-FIXES: functionTaking<bool>(false);
344 
345   functionTaking<bool>('a');
346   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> 'bool'
347   // CHECK-FIXES: functionTaking<bool>(true);
348 
349 
350   functionTaking<bool>("");
351   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> 'bool'
352   // CHECK-FIXES: functionTaking<bool>(true);
353 
354   functionTaking<bool>("abc");
355   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> 'bool'
356   // CHECK-FIXES: functionTaking<bool>(true);
357 
358   functionTaking<bool>(NULL);
359   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> 'bool'
360   // CHECK-FIXES: functionTaking<bool>(false);
361 }
362 
363 void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
364   functionTaking<bool>(-0);
365   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
366   // CHECK-FIXES: functionTaking<bool>((-0) != 0);
367 
368   functionTaking<bool>(-0.0f);
369   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
370   // CHECK-FIXES: functionTaking<bool>((-0.0f) != 0.0f);
371   // CHECK-FIXES-UPPER-CASE: functionTaking<bool>((-0.0f) != 0.0F);
372 
373   functionTaking<bool>(-0.0);
374   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool'
375   // CHECK-FIXES: functionTaking<bool>((-0.0) != 0.0);
376 }
377 
378 void implicitConversionToBoolInWithOverloadedOperators() {
379   struct UserStruct {
380     int operator()(int x) { return x; }
381     int operator+(int y) { return y; }
382   };
383 
384   UserStruct s;
385 
386   functionTaking<bool>(s(0));
387   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
388   // CHECK-FIXES: functionTaking<bool>(s(0) != 0);
389 
390   functionTaking<bool>(s + 2);
391   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
392   // CHECK-FIXES: functionTaking<bool>((s + 2) != 0);
393 }
394 
395 int functionReturningInt();
396 int* functionReturningPointer();
397 
398 void ignoreImplicitConversionToBoolWhenDeclaringVariableInControlStatements() {
399   if (int integer = functionReturningInt()) {}
400 
401   while (int* pointer = functionReturningPointer()) {}
402 }
403 
404 void ignoreExplicitCastsToBool() {
405   int integer = 10;
406   bool boolComingFromInt = static_cast<bool>(integer);
407 
408   float floating = 10.0f;
409   bool boolComingFromFloat = static_cast<bool>(floating);
410 
411   char character = 'a';
412   bool boolComingFromChar = static_cast<bool>(character);
413 
414   int* pointer = nullptr;
415   bool booleanComingFromPointer = static_cast<bool>(pointer);
416 }
417 
418 void ignoreImplicitConversionToBoolInMacroExpansions() {
419   int integer = 3;
420 
421   #define CAST_TO_BOOL_IN_MACRO_BODY integer && false
422   bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY;
423 
424   #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true
425   bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer);
426 }
427 
428 namespace ignoreImplicitConversionToBoolInTemplateInstantiations {
429 
430 template<typename T>
431 void templateFunction() {
432   T unknownType = 0;
433   bool boolean = unknownType;
434 }
435 
436 void useOfTemplateFunction() {
437   templateFunction<int>();
438 }
439 
440 } // namespace ignoreImplicitConversionToBoolInTemplateInstantiations
441 
442 namespace ignoreUserDefinedConversionOperator {
443 
444 struct StructWithUserConversion {
445   operator bool();
446 };
447 
448 void useOfUserConversion() {
449   StructWithUserConversion structure;
450   functionTaking<bool>(structure);
451 }
452 
453 } // namespace ignoreUserDefinedConversionOperator
454 
455 namespace ignore_1bit_bitfields {
456 
457 struct S {
458   int a;
459   int b : 1;
460   int c : 2;
461 
462   S(bool a, bool b, bool c) : a(a), b(b), c(c) {}
463   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int'
464   // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion 'bool' -> 'int'
465   // CHECK-FIXES: S(bool a, bool b, bool c) : a(static_cast<int>(a)), b(b), c(static_cast<int>(c)) {}
466 };
467 
468 bool f(S& s) {
469   functionTaking<bool>(s.a);
470   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
471   // CHECK-FIXES: functionTaking<bool>(s.a != 0);
472   functionTaking<bool>(s.b);
473   // CHECK-FIXES: functionTaking<bool>(s.b);
474   s.a = true;
475   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int'
476   // CHECK-FIXES: s.a = 1;
477   s.b = true;
478   // CHECK-FIXES: s.b = true;
479   s.c = true;
480   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int'
481   // CHECK-FIXES: s.c = 1;
482   functionTaking<bool>(s.c);
483   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool'
484   // CHECK-FIXES: functionTaking<bool>(s.c != 0);
485 }
486 
487 } // namespace ignore_1bit_bitfields
488 
489 int implicitConversionReturnInt()
490 {
491     return true;
492     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
493     // CHECK-FIXES: return 1
494 }
495 
496 int implicitConversionReturnIntWithParens()
497 {
498     return (true);
499     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
500     // CHECK-FIXES: return 1
501 }
502 
503 
504 bool implicitConversionReturnBool()
505 {
506     return 1;
507     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
508     // CHECK-FIXES: return true
509 }
510 
511 bool implicitConversionReturnBoolWithParens()
512 {
513     return (1);
514     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
515     // CHECK-FIXES: return true
516 }
517 
518 
519 namespace PR47000 {
520   int to_int(bool x) { return int{x}; }
521 
522   using IntType = int;
523   int to_int2(bool x) { return IntType{x}; }
524 }
525 
526 namespace PR71867 {
527   bool foo(bool x) {
528     return x ? 1 : false;
529     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
530     // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: implicit conversion 'bool' -> 'int'
531     // CHECK-FIXES: return (x ? 1 : 0) != 0;
532   }
533 
534   bool boo(bool x) {
535     return x ? true : 0;
536     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
537     // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: implicit conversion 'bool' -> 'int'
538     // CHECK-FIXES: return (x ? 1 : 0) != 0;
539   }
540 }
541 
542 namespace PR71848 {
543   int fun() {
544     bool foo = false;
545     return( foo );
546 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion]
547 // CHECK-FIXES: return static_cast<int>( foo );
548   }
549 }
550