1 // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \ 2 // RUN: -config='{CheckOptions: \ 3 // RUN: {readability-implicit-bool-conversion.AllowIntegerConditions: true, \ 4 // RUN: readability-implicit-bool-conversion.AllowPointerConditions: true}}' 5 6 template<typename T> 7 void functionTaking(T); 8 9 int functionReturningInt(); 10 int* functionReturningPointer(); 11 12 struct Struct { 13 int member; 14 unsigned bitfield : 1; 15 bool boolfield : 1; 16 }; 17 18 regularImplicitConversionIntegerToBoolIsNotIgnored()19void regularImplicitConversionIntegerToBoolIsNotIgnored() { 20 int integer = 0; 21 functionTaking<bool>(integer); 22 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion] 23 // CHECK-FIXES: functionTaking<bool>(integer != 0); 24 } 25 implicitConversionIntegerToBoolInConditionalsIsAllowed()26void implicitConversionIntegerToBoolInConditionalsIsAllowed() { 27 Struct s = {}; 28 if (s.member) {} 29 if (!s.member) {} 30 if (s.bitfield) {} 31 if (!s.bitfield) {} 32 if (s.boolfield == true) {} 33 if (s.boolfield != true) {} 34 if (functionReturningInt()) {} 35 if (!functionReturningInt()) {} 36 if (functionReturningInt() && functionReturningPointer()) {} 37 if (!functionReturningInt() && !functionReturningPointer()) {} 38 for (; functionReturningInt(); ) {} 39 for (; functionReturningPointer(); ) {} 40 for (; functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer()); ) {} 41 while (functionReturningInt()) {} 42 while (functionReturningPointer()) {} 43 while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())) {} 44 do {} while (functionReturningInt()); 45 do {} while (functionReturningPointer()); 46 do {} while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())); 47 int value1 = functionReturningInt() ? 1 : 2; 48 int value2 = !functionReturningInt() ? 1 : 2; 49 int value3 = (functionReturningInt() && functionReturningPointer() || !functionReturningInt()) ? 1 : 2; 50 int value4 = functionReturningInt() ?: value3; 51 int *p1 = functionReturningPointer() ?: &value3; 52 } 53 regularImplicitConversionPointerToBoolIsNotIgnored()54void regularImplicitConversionPointerToBoolIsNotIgnored() { 55 int* pointer = nullptr; 56 functionTaking<bool>(pointer); 57 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool' 58 // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); 59 60 int Struct::* memberPointer = &Struct::member; 61 functionTaking<bool>(memberPointer); 62 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool' 63 // CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr); 64 } 65 implicitConversionPointerToBoolInConditionalsIsAllowed()66void implicitConversionPointerToBoolInConditionalsIsAllowed() { 67 if (functionReturningPointer()) {} 68 if (not functionReturningPointer()) {} 69 int value1 = functionReturningPointer() ? 1 : 2; 70 int value2 = (not functionReturningPointer()) ? 1 : 2; 71 72 int Struct::* memberPointer = &Struct::member; 73 if (memberPointer) {} 74 if (memberPointer) {} 75 int value3 = memberPointer ? 1 : 2; 76 int value4 = (not memberPointer) ? 1 : 2; 77 } 78