189a1d03eSRichard // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \ 289a1d03eSRichard // RUN: -config='{CheckOptions: \ 3e8a3ddafSNathan James // RUN: {readability-implicit-bool-conversion.AllowIntegerConditions: true, \ 4e8a3ddafSNathan James // RUN: readability-implicit-bool-conversion.AllowPointerConditions: true}}' 589a1d03eSRichard 689a1d03eSRichard template<typename T> 789a1d03eSRichard void functionTaking(T); 889a1d03eSRichard 989a1d03eSRichard int functionReturningInt(); 1089a1d03eSRichard int* functionReturningPointer(); 1189a1d03eSRichard 1289a1d03eSRichard struct Struct { 1389a1d03eSRichard int member; 1489a1d03eSRichard unsigned bitfield : 1; 15332be179SCongcong Cai bool boolfield : 1; 1689a1d03eSRichard }; 1789a1d03eSRichard 1889a1d03eSRichard regularImplicitConversionIntegerToBoolIsNotIgnored()1989a1d03eSRichardvoid regularImplicitConversionIntegerToBoolIsNotIgnored() { 2089a1d03eSRichard int integer = 0; 2189a1d03eSRichard functionTaking<bool>(integer); 22*fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion] 2389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(integer != 0); 2489a1d03eSRichard } 2589a1d03eSRichard implicitConversionIntegerToBoolInConditionalsIsAllowed()2689a1d03eSRichardvoid implicitConversionIntegerToBoolInConditionalsIsAllowed() { 2789a1d03eSRichard Struct s = {}; 2889a1d03eSRichard if (s.member) {} 2989a1d03eSRichard if (!s.member) {} 3089a1d03eSRichard if (s.bitfield) {} 3189a1d03eSRichard if (!s.bitfield) {} 32332be179SCongcong Cai if (s.boolfield == true) {} 33332be179SCongcong Cai if (s.boolfield != true) {} 3489a1d03eSRichard if (functionReturningInt()) {} 3589a1d03eSRichard if (!functionReturningInt()) {} 3689a1d03eSRichard if (functionReturningInt() && functionReturningPointer()) {} 3789a1d03eSRichard if (!functionReturningInt() && !functionReturningPointer()) {} 3889a1d03eSRichard for (; functionReturningInt(); ) {} 3989a1d03eSRichard for (; functionReturningPointer(); ) {} 4089a1d03eSRichard for (; functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer()); ) {} 4189a1d03eSRichard while (functionReturningInt()) {} 4289a1d03eSRichard while (functionReturningPointer()) {} 4389a1d03eSRichard while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())) {} 44f263f45bSFabian Wolff do {} while (functionReturningInt()); 45f263f45bSFabian Wolff do {} while (functionReturningPointer()); 46f263f45bSFabian Wolff do {} while (functionReturningInt() && !functionReturningPointer() || (!functionReturningInt() && functionReturningPointer())); 4789a1d03eSRichard int value1 = functionReturningInt() ? 1 : 2; 4889a1d03eSRichard int value2 = !functionReturningInt() ? 1 : 2; 4989a1d03eSRichard int value3 = (functionReturningInt() && functionReturningPointer() || !functionReturningInt()) ? 1 : 2; 5089a1d03eSRichard int value4 = functionReturningInt() ?: value3; 5189a1d03eSRichard int *p1 = functionReturningPointer() ?: &value3; 5289a1d03eSRichard } 5389a1d03eSRichard regularImplicitConversionPointerToBoolIsNotIgnored()5489a1d03eSRichardvoid regularImplicitConversionPointerToBoolIsNotIgnored() { 5589a1d03eSRichard int* pointer = nullptr; 5689a1d03eSRichard functionTaking<bool>(pointer); 57*fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> 'bool' 5889a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); 5989a1d03eSRichard 6089a1d03eSRichard int Struct::* memberPointer = &Struct::member; 6189a1d03eSRichard functionTaking<bool>(memberPointer); 62*fd0e06d1SPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool' 6389a1d03eSRichard // CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr); 6489a1d03eSRichard } 6589a1d03eSRichard implicitConversionPointerToBoolInConditionalsIsAllowed()6689a1d03eSRichardvoid implicitConversionPointerToBoolInConditionalsIsAllowed() { 6789a1d03eSRichard if (functionReturningPointer()) {} 6889a1d03eSRichard if (not functionReturningPointer()) {} 6989a1d03eSRichard int value1 = functionReturningPointer() ? 1 : 2; 7089a1d03eSRichard int value2 = (not functionReturningPointer()) ? 1 : 2; 7189a1d03eSRichard 7289a1d03eSRichard int Struct::* memberPointer = &Struct::member; 7389a1d03eSRichard if (memberPointer) {} 7489a1d03eSRichard if (memberPointer) {} 7589a1d03eSRichard int value3 = memberPointer ? 1 : 2; 7689a1d03eSRichard int value4 = (not memberPointer) ? 1 : 2; 7789a1d03eSRichard } 78