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 }; 16 17 18 void regularImplicitConversionIntegerToBoolIsNotIgnored() { 19 int integer = 0; 20 functionTaking<bool>(integer); 21 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool [readability-implicit-bool-conversion] 22 // CHECK-FIXES: functionTaking<bool>(integer != 0); 23 } 24 25 void implicitConversionIntegerToBoolInConditionalsIsAllowed() { 26 Struct s = {}; 27 if (s.member) {} 28 if (!s.member) {} 29 if (s.bitfield) {} 30 if (!s.bitfield) {} 31 if (functionReturningInt()) {} 32 if (!functionReturningInt()) {} 33 if (functionReturningInt() && functionReturningPointer()) {} 34 if (!functionReturningInt() && !functionReturningPointer()) {} 35 for (; functionReturningInt(); ) {} 36 for (; functionReturningPointer(); ) {} 37 for (; functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer()); ) {} 38 while (functionReturningInt()) {} 39 while (functionReturningPointer()) {} 40 while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())) {} 41 do {} while (functionReturningInt()); 42 do {} while (functionReturningPointer()); 43 do {} while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())); 44 int value1 = functionReturningInt() ? 1 : 2; 45 int value2 = !functionReturningInt() ? 1 : 2; 46 int value3 = (functionReturningInt() && functionReturningPointer() || !functionReturningInt()) ? 1 : 2; 47 int value4 = functionReturningInt() ?: value3; 48 int *p1 = functionReturningPointer() ?: &value3; 49 } 50 51 void regularImplicitConversionPointerToBoolIsNotIgnored() { 52 int* pointer = nullptr; 53 functionTaking<bool>(pointer); 54 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool 55 // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); 56 57 int Struct::* memberPointer = &Struct::member; 58 functionTaking<bool>(memberPointer); 59 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool 60 // CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr); 61 } 62 63 void implicitConversionPointerToBoolInConditionalsIsAllowed() { 64 if (functionReturningPointer()) {} 65 if (not functionReturningPointer()) {} 66 int value1 = functionReturningPointer() ? 1 : 2; 67 int value2 = (not functionReturningPointer()) ? 1 : 2; 68 69 int Struct::* memberPointer = &Struct::member; 70 if (memberPointer) {} 71 if (memberPointer) {} 72 int value3 = memberPointer ? 1 : 2; 73 int value4 = (not memberPointer) ? 1 : 2; 74 } 75