[clang-tidy] enhance modernize-use-bool-literals to check ternary operator
authorKirill Bobyrev <omtcyfz@gmail.com>
Mon, 8 Aug 2016 17:11:56 +0000 (17:11 +0000)
committerKirill Bobyrev <omtcyfz@gmail.com>
Mon, 8 Aug 2016 17:11:56 +0000 (17:11 +0000)
modernize-use-bool-literals doesn't checks operands in ternary operator.

For example:

``` c++
static int Value = 1;

bool foo() {
  bool Result = Value == 1 ? 1 : 0;
  return Result;
}

bool boo() {
  return Value == 1 ? 1 : 0;
}
```

This issue was reported in bug 28854. The patch fixes it.

Reviewers: alexfh, aaron.ballman, Prazek

Subscribers: Prazek, Eugene.Zelenko

Differential Revision: https://reviews.llvm.org/D23243

llvm-svn: 278022

clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
clang-tools-extra/docs/clang-tidy/checks/modernize-use-bool-literals.rst
clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp

index ccb3e8f..193bb61 100644 (file)
@@ -29,6 +29,17 @@ void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
           unless(isInTemplateInstantiation()),
           anyOf(hasParent(explicitCastExpr().bind("cast")), anything())),
       this);
+
+  Finder->addMatcher(
+      conditionalOperator(
+          hasParent(implicitCastExpr(
+              hasImplicitDestinationType(qualType(booleanType())),
+              unless(isInTemplateInstantiation()))),
+          eachOf(hasTrueExpression(
+                     ignoringParenImpCasts(integerLiteral().bind("literal"))),
+                 hasFalseExpression(
+                     ignoringParenImpCasts(integerLiteral().bind("literal"))))),
+      this);
 }
 
 void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) {
index d547af5..7ce048f 100644 (file)
@@ -10,9 +10,11 @@ Finds integer literals which are cast to ``bool``.
   bool p = 1;
   bool f = static_cast<bool>(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 8ba516d..35c3ec4 100644 (file)
@@ -5,30 +5,30 @@ bool IntToTrue = 1;
 // CHECK-FIXES: {{^}}bool IntToTrue = true;{{$}}
 
 bool IntToFalse(0);
-// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool IntToFalse(false);{{$}}
 
 bool LongLongToTrue{0x1LL};
-// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool LongLongToTrue{true};{{$}}
 
 bool ExplicitCStyleIntToFalse = (bool)0;
-// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool ExplicitCStyleIntToFalse = false;{{$}}
 
 bool ExplicitFunctionalIntToFalse = bool(0);
-// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool ExplicitFunctionalIntToFalse = false;{{$}}
 
 bool ExplicitStaticIntToFalse = static_cast<bool>(0);
-// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool ExplicitStaticIntToFalse = false;{{$}}
 
 #define TRUE_MACRO 1
 // CHECK-FIXES: {{^}}#define TRUE_MACRO 1{{$}}
 
 bool MacroIntToTrue = TRUE_MACRO;
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool MacroIntToTrue = TRUE_MACRO;{{$}}
 
 #define FALSE_MACRO bool(0)
@@ -37,7 +37,7 @@ bool MacroIntToTrue = TRUE_MACRO;
 bool TrueBool = true; // OK
 
 bool FalseBool = bool(FALSE_MACRO);
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool FalseBool = bool(FALSE_MACRO);{{$}}
 
 void boolFunction(bool bar) {
@@ -52,28 +52,28 @@ unsigned long long LongInteger = 1; // OK
 // CHECK-FIXES: {{^}}#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x){{$}}
 
 bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);
-// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);{{$}}
 
 bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);
-// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: {{.*}}
+// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: converting integer literal to bool
 // CHECK-FIXES: {{^}}bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);{{$}}
 
 class FooClass {
   public:
   FooClass() : JustBool(0) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}FooClass() : JustBool(false) {}{{$}}
   FooClass(int) : JustBool{0} {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}FooClass(int) : JustBool{false} {}{{$}}
   private:
   bool JustBool;
   bool BoolWithBraces{0};
-  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}bool BoolWithBraces{false};{{$}}
   bool BoolFromInt = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}bool BoolFromInt = false;{{$}}
   bool SimpleBool = true; // OK
 };
@@ -93,13 +93,13 @@ void valueDependentTemplateFunction() {
 template<typename type>
 void anotherTemplateFunction(type) {
   bool JustBool = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}bool JustBool = false;{{$}}
 }
 
 int main() {
   boolFunction(1);
-  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}boolFunction(true);{{$}}
 
   boolFunction(false);
@@ -113,6 +113,36 @@ int main() {
   anotherTemplateFunction(1);
 
   IntToTrue = 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: converting integer literal to bool
   // CHECK-FIXES: {{^ *}}IntToTrue = true;{{$}}
 }
+
+static int Value = 1;
+
+bool Function1() {
+  bool Result = Value == 1 ? 1 : 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: converting integer literal to bool
+  // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: converting integer literal to bool
+  // CHECK-FIXES: {{^ *}}bool Result = Value == 1 ? true : false;{{$}}
+  return Result;
+}
+
+bool Function2() {
+  return Value == 1 ? 1 : 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: converting integer literal to bool
+  // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: converting integer literal to bool
+  // CHECK-FIXES: {{^ *}}return Value == 1 ? true : false;{{$}}
+}
+
+void foo() {
+  bool Result;
+  Result = Value == 1 ? true : 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: converting integer literal to bool
+  // CHECK-FIXES: {{^ *}}Result = Value == 1 ? true : false;{{$}}
+  Result = Value == 1 ? false : bool(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: converting integer literal to bool
+  // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+  Result = Value == 1 ? (bool)0 : false;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: converting integer literal to bool
+  // CHECK-FIXES: {{^ *}}Result = Value == 1 ? false : false;{{$}}
+}