staronj updated the summary for this revision.
staronj updated this revision to Diff 53984.
staronj added a comment.

Check now finds implicit and explicit conversions from integer literal to bool.


http://reviews.llvm.org/D18745

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/UseBoolLiteralsCheck.cpp
  clang-tidy/modernize/UseBoolLiteralsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-use-bool-literals.rst
  test/clang-tidy/modernize-use-bool-literals.cpp

Index: test/clang-tidy/modernize-use-bool-literals.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/modernize-use-bool-literals.cpp
@@ -0,0 +1,118 @@
+// RUN: %check_clang_tidy %s modernize-use-bool-literals %t
+
+bool IntToTrue = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]
+// CHECK-FIXES: {{^}}bool IntToTrue = true;{{$}}
+
+bool IntToFalse(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool IntToFalse(false);{{$}}
+
+bool LongLongToTrue{0x1LL};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool LongLongToTrue{true};{{$}}
+
+bool ExplicitCStyleIntToFalse = (bool)0;
+// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool ExplicitCStyleIntToFalse = false;{{$}}
+
+bool ExplicitFunctionalIntToFalse = bool(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool ExplicitFunctionalIntToFalse = false;{{$}}
+
+bool ExplicitStaticIntToFalse = static_cast<bool>(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:51: warning: {{.*}}
+// 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 inside a macro, use bool literal instead [modernize-use-bool-literals]
+// CHECK-FIXES: {{^}}bool MacroIntToTrue = TRUE_MACRO;{{$}}
+
+#define FALSE_MACRO bool(0)
+// CHECK-FIXES: {{^}}#define FALSE_MACRO bool(0){{$}}
+
+
+bool TrueBool = true; // OK
+
+bool FalseBool = FALSE_MACRO;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool FalseBool = FALSE_MACRO;{{$}}
+
+void boolFunction(bool bar) {
+
+}
+
+char Character = 0; // OK
+
+unsigned long long LongInteger = 1; // OK
+
+#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x)
+// CHECK-FIXES: {{^}}#define MACRO_DEPENDENT_CAST(x) static_cast<bool>(x){{$}}
+
+bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: {{.*}}
+// CHECK-FIXES: {{^}}bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);{{$}}
+
+class FooClass {
+  public:
+  FooClass() : JustBool(0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}FooClass() : JustBool(false) {}{{$}}
+  FooClass(int) : JustBool{0} {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}FooClass(int) : JustBool{false} {}{{$}}
+  private:
+  bool JustBool;
+  bool BoolWithBraces{0};
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}bool BoolWithBraces{false};{{$}}
+  bool BoolFromInt = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}bool BoolFromInt = false;{{$}}
+  bool SimpleBool = true; // OK
+};
+
+template<typename type>
+void templateFunction(type) {
+  type TemplateType = 0;
+  // CHECK-FIXES: {{^ *}}type TemplateType = 0;{{$}}
+  return;
+}
+
+template<int c>
+void valueDependentTemplateFunction() {
+  bool Boolean = c;
+  // CHECK-FIXES: {{^ *}}bool Boolean = c;{{$}}
+  return;
+}
+
+template<typename type>
+void anotherTemplateFunction(type) {
+  bool JustBool = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}bool JustBool = false;{{$}}
+  return;
+}
+
+int main() {
+  boolFunction(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}boolFunction(true);{{$}}
+
+  boolFunction(false);
+
+  templateFunction(0);
+
+  templateFunction(false);
+
+  valueDependentTemplateFunction<1>();
+
+  anotherTemplateFunction(1);
+
+  IntToTrue = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}
+  // CHECK-FIXES: {{^ *}}IntToTrue = true;{{$}}
+}
Index: docs/clang-tidy/checks/modernize-use-bool-literals.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/modernize-use-bool-literals.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - modernize-use-bool-literals
+
+modernize-use-bool-literals
+===========================
+
+Finds integer literals which are cast to bool.
+
+.. code-block:: c++
+
+  bool p = 1;
+  bool f = static_cast<bool>(1);
+  std::ios_base::sync_with_stdio(0);
+
+  // transforms to
+
+  bool p = true;
+  bool f = true;
+  std::ios_base::sync_with_stdio(false);
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -31,9 +31,9 @@
    google-build-using-namespace
    google-explicit-constructor
    google-global-names-in-headers
-   google-readability-braces-around-statements (redirects to readability-braces-around-statements) <readability-braces-around-statements>
+   google-readability-braces-around-statements (redirects to readability-braces-around-statements) <google-readability-braces-around-statements>
    google-readability-casting
-   google-readability-function-size (redirects to readability-function-size) <readability-function-size>
+   google-readability-function-size (redirects to readability-function-size) <google-readability-function-size>
    google-readability-namespace-comments
    google-readability-redundant-smartptr-get
    google-readability-todo
@@ -85,6 +85,7 @@
    modernize-replace-auto-ptr
    modernize-shrink-to-fit
    modernize-use-auto
+   modernize-use-bool-literals
    modernize-use-default
    modernize-use-nullptr
    modernize-use-override
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -119,6 +119,11 @@
   Selectively replaces string literals containing escaped characters with raw
   string literals.
 
+- New `modernize-use-bool-literals
+  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-bool-literals.html>`_ check
+
+  Finds integer literals which are cast to bool.
+
 - New `performance-faster-string-find
   <http://clang.llvm.org/extra/clang-tidy/checks/performance-faster-string-find.html>`_ check
 
Index: clang-tidy/modernize/UseBoolLiteralsCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/modernize/UseBoolLiteralsCheck.h
@@ -0,0 +1,35 @@
+//===--- UseBoolLiteralsCheck.h - clang-tidy---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_BOOL_LITERALS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_BOOL_LITERALS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Finds integer literals which are cast to bool.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-bool-literals.html
+class UseBoolLiteralsCheck : public ClangTidyCheck {
+public:
+  UseBoolLiteralsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_BOOL_LITERALS_H
Index: clang-tidy/modernize/UseBoolLiteralsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/modernize/UseBoolLiteralsCheck.cpp
@@ -0,0 +1,73 @@
+//===--- UseBoolLiteralsCheck.cpp - clang-tidy-----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseBoolLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  auto hasIntegerLiteralCastToBool =
+      allOf(has(integerLiteral().bind("literal")),
+            hasImplicitDestinationType(qualType(booleanType())),
+            unless(isInTemplateInstantiation()));
+
+  Finder->addMatcher(implicitCastExpr(hasIntegerLiteralCastToBool,
+                                      unless(hasParent(explicitCastExpr()))),
+                     this);
+
+  Finder->addMatcher(
+      implicitCastExpr(hasIntegerLiteralCastToBool,
+                       hasParent(explicitCastExpr().bind("cast"))),
+      this);
+}
+
+/// \brief Checks, if  \p Statement is preprocessor dependent.
+/// If \p Statement is nullptr returns false.
+static bool isPreprocessorDependent(const Stmt *Statement) {
+  return Statement != nullptr && Statement->getLocStart().isMacroID();
+}
+
+void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Literal = Result.Nodes.getNodeAs<IntegerLiteral>("literal");
+  const auto *Cast = Result.Nodes.getNodeAs<ExplicitCastExpr>("cast");
+  bool LiteralBooleanValue = Literal->getValue().getBoolValue();
+
+  if (Literal->isInstantiationDependent())
+    return;
+
+  auto Diag = diag(Literal->getLocation(),
+                   "converting integer literal to "
+                   "bool%select{| inside a macro}0, use bool literal instead");
+
+  if (isPreprocessorDependent(Literal) || isPreprocessorDependent(Cast)) {
+    Diag << 1;
+  } else if (Cast != nullptr) {
+    Diag << 0
+         << FixItHint::CreateReplacement(
+                Cast->getSourceRange(), LiteralBooleanValue ? "true" : "false");
+  } else {
+    Diag << 0 << FixItHint::CreateReplacement(Literal->getSourceRange(),
+                                              LiteralBooleanValue ? "true"
+                                                                  : "false");
+  }
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/modernize/ModernizeTidyModule.cpp
===================================================================
--- clang-tidy/modernize/ModernizeTidyModule.cpp
+++ clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -19,6 +19,7 @@
 #include "ReplaceAutoPtrCheck.h"
 #include "ShrinkToFitCheck.h"
 #include "UseAutoCheck.h"
+#include "UseBoolLiteralsCheck.h"
 #include "UseDefaultCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
@@ -45,6 +46,8 @@
         "modernize-replace-auto-ptr");
     CheckFactories.registerCheck<ShrinkToFitCheck>("modernize-shrink-to-fit");
     CheckFactories.registerCheck<UseAutoCheck>("modernize-use-auto");
+    CheckFactories.registerCheck<UseBoolLiteralsCheck>(
+        "modernize-use-bool-literals");
     CheckFactories.registerCheck<UseDefaultCheck>("modernize-use-default");
     CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr");
     CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
Index: clang-tidy/modernize/CMakeLists.txt
===================================================================
--- clang-tidy/modernize/CMakeLists.txt
+++ clang-tidy/modernize/CMakeLists.txt
@@ -12,6 +12,7 @@
   ReplaceAutoPtrCheck.cpp
   ShrinkToFitCheck.cpp
   UseAutoCheck.cpp
+  UseBoolLiteralsCheck.cpp
   UseDefaultCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to