Index: clang-tidy/modernize/UseBoolLiteralsCheck.cpp =================================================================== --- clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -29,10 +29,31 @@ unless(isInTemplateInstantiation()), anyOf(hasParent(explicitCastExpr().bind("cast")), anything())), this); + + Finder->addMatcher( + conditionalOperator( + hasParent(implicitCastExpr( + hasImplicitDestinationType(qualType(booleanType())), + unless(isInTemplateInstantiation()))), + eachOf( + // anyOf() is not evaluating second argument if first is evaluated + // as + // 'true'. We'd like to bind both literals if they are presents. + // Thus, + // using anyOf(BINDLITERAL(), anything()). + anyOf(hasTrueExpression(ignoringParenImpCasts( + integerLiteral().bind("literal"))), + anything()), + anyOf(hasFalseExpression(ignoringParenImpCasts( + integerLiteral().bind("literal"))), + anything()))), + this); } void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) { const auto *Literal = Result.Nodes.getNodeAs("literal"); + if (!Literal) + return; const auto *Cast = Result.Nodes.getNodeAs("cast"); bool LiteralBooleanValue = Literal->getValue().getBoolValue(); Index: docs/clang-tidy/checks/modernize-use-bool-literals.rst =================================================================== --- docs/clang-tidy/checks/modernize-use-bool-literals.rst +++ docs/clang-tidy/checks/modernize-use-bool-literals.rst @@ -10,9 +10,11 @@ bool p = 1; bool f = static_cast(1); std::ios_base::sync_with_stdio(0); + bool x = p ? 1 : 0; // transforms to bool p = true; bool f = true; std::ios_base::sync_with_stdio(false); + bool x = p ? true : false; Index: test/clang-tidy/modernize-use-bool-literals.cpp =================================================================== --- test/clang-tidy/modernize-use-bool-literals.cpp +++ test/clang-tidy/modernize-use-bool-literals.cpp @@ -116,3 +116,33 @@ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} // CHECK-FIXES: {{^ *}}IntToTrue = true;{{$}} } + +static int Value = 1; + +bool Function1() { + bool Result = Value == 1 ? 1 : 0; + // CHECK-MESSAGES: :[[@LINE-1]]:30: {{.*}} + // CHECK-MESSAGES: :[[@LINE-2]]:34: {{.*}} + // CHECK-FIXES: {{^ *}}bool Result = Value == 1 ? true : false;{{$}} + return Result; +} + +bool Function2() { + return Value == 1 ? 1 : 0; + // CHECK-MESSAGES: :[[@LINE-1]]:23: {{.*}} + // CHECK-MESSAGES: :[[@LINE-2]]:27: {{.*}} + // CHECK-FIXES: {{^ *}}return Value == 1 ? true : false;{{$}} +} + +void foo() { + bool Result; + Result = Value == 1 ? true : 0; + // CHECK-MESSAGES: :[[@LINE-1]]:32: {{.*}} + // CHECK-FIXES: {{^ *}}Result = Value == 1 ? true : false;{{$}} + Result = Value == 1 ? false : bool(0); + // CHECK-MESSAGES: :[[@LINE-1]]:33: {{.*}} + // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}} + Result = Value == 1 ? (bool)0 : false; + // CHECK-MESSAGES: :[[@LINE-1]]:25: {{.*}} + // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}} +}