Prazek updated this revision to Diff 53113.
Prazek marked 2 inline comments as done.

http://reviews.llvm.org/D18821

Files:
  clang-tidy/modernize/BoolToIntegerConversionCheck.cpp
  clang-tidy/modernize/BoolToIntegerConversionCheck.h
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-bool-to-integer-conversion.rst
  test/clang-tidy/modernize-bool-to-integer-conversion.cpp

Index: test/clang-tidy/modernize-bool-to-integer-conversion.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/modernize-bool-to-integer-conversion.cpp
@@ -0,0 +1,58 @@
+// RUN: %check_clang_tidy %s modernize-bool-to-integer-conversion %t
+
+const int is42Answer = true;
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicitly converting bool literal to 'int'; use integer literal instead [modernize-bool-to-integer-conversion]
+// CHECK-FIXES: const int is42Answer = 1;{{$}}
+
+volatile int noItsNot = false;
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicitly converting bool literal to 'int'; {{..}}
+// CHECK-FIXES: volatile int noItsNot = 0;{{$}}
+int a = 42;
+int az = a;
+
+long long ll = true;
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicitly converting bool literal to 'long long';{{..}}
+// CHECK-FIXES: long long ll = 1;{{$}}
+
+void fun(int) {}
+#define ONE true
+
+// No fixup for macros.
+int one = ONE;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: implicitly converting bool literal to 'int' inside a macro; use integer literal instead [modernize-bool-to-integer-conversion]
+
+void test() {
+  fun(ONE);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicitly converting bool{{..}}
+
+  fun(42);
+  fun(true);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicitly {{..}}
+// CHECK-FIXES: fun(1);{{$}}
+}
+
+char c = true;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicitly {{..}}
+// CHECK-FIXES: char c = 1;
+
+float f = false;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: implicitly converting bool literal to 'float';{{..}}
+// CHECK-FIXES: float f = 0;
+
+struct Blah {
+  Blah(int blah) { }
+};
+
+const int &ref = false;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicitly converting bool literal to 'int'{{..}}
+// CHECK-FIXES: const int &ref = 0;
+
+Blah bla = true;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicitly converting bool literal to 'int'{{..}}
+// CHECK-FIXES: Blah bla = 1;
+
+Blah bla2 = 1;
+
+char c2 = 1;
+char c3 = '0';
+bool b = true;
Index: docs/clang-tidy/checks/modernize-bool-to-integer-conversion.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/modernize-bool-to-integer-conversion.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - modernize-bool-to-integer-conversion
+
+modernize-bool-to-integer-conversion
+====================================
+
+This check looks for implicit conversion from bool literals to integer types
+
+.. code-block:: C++
+
+  int a = false;
+  vector<bool> v(true); // Makes vector of one element
+
+  // Changes it to
+  int a = 0;
+  vector<bool> v(1); // Makes vector of one element
+
+
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
@@ -76,6 +76,7 @@
    misc-unused-parameters
    misc-unused-raii
    misc-virtual-near-miss
+   modernize-bool-to-integer-conversion
    modernize-deprecated-headers
    modernize-loop-convert
    modernize-make-unique
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -113,6 +113,11 @@
 
   Replaces C standard library headers with their C++ alternatives.
 
+- New `modernize-bool-to-integer-conversion
+  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-bool-to-integer-conversion.html>`_ check
+
+  Replaces bool literals which are being implicitly cast to integers with integer literals.
+
 - New `modernize-raw-string-literal
   <http://clang.llvm.org/extra/clang-tidy/checks/modernize-raw-string-literal.html>`_ check
 
Index: clang-tidy/modernize/ModernizeTidyModule.cpp
===================================================================
--- clang-tidy/modernize/ModernizeTidyModule.cpp
+++ clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "BoolToIntegerConversionCheck.h"
 #include "DeprecatedHeadersCheck.h"
 #include "LoopConvertCheck.h"
 #include "MakeUniqueCheck.h"
@@ -32,6 +33,8 @@
 class ModernizeModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<BoolToIntegerConversionCheck>(
+        "modernize-bool-to-integer-conversion");
     CheckFactories.registerCheck<DeprecatedHeadersCheck>(
         "modernize-deprecated-headers");
     CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert");
Index: clang-tidy/modernize/CMakeLists.txt
===================================================================
--- clang-tidy/modernize/CMakeLists.txt
+++ clang-tidy/modernize/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS support)
 
 add_clang_library(clangTidyModernizeModule
+  BoolToIntegerConversionCheck.cpp
   DeprecatedHeadersCheck.cpp
   LoopConvertCheck.cpp
   LoopConvertUtils.cpp
Index: clang-tidy/modernize/BoolToIntegerConversionCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/modernize/BoolToIntegerConversionCheck.h
@@ -0,0 +1,36 @@
+//===--- BoolToIntegerConversionCheck.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_BOOL_TO_INTEGER_CONVERSION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_BOOL_TO_INTEGER_CONVERSION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Finds implicit casts of bool literal to integer types like int a = true,
+/// and replaces it with integer literals like int a = 1
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-bool-to-integer-conversion.html
+class BoolToIntegerConversionCheck : public ClangTidyCheck {
+public:
+  BoolToIntegerConversionCheck(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_BOOL_TO_INTEGER_CONVERSION_H
Index: clang-tidy/modernize/BoolToIntegerConversionCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/modernize/BoolToIntegerConversionCheck.cpp
@@ -0,0 +1,64 @@
+//===--- BoolToIntegerConversionCheck.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 "BoolToIntegerConversionCheck.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 {
+
+/// Checks, if integer \p Literal is preprocessor dependent
+static bool isPreprocessorIndependent(const CXXBoolLiteralExpr *Literal,
+                                      const MatchFinder::MatchResult &Result) {
+  const LangOptions &Opts = Result.Context->getLangOpts();
+  auto LiteralSource = Lexer::getSourceText(
+      CharSourceRange::getTokenRange(Literal->getSourceRange()),
+      *Result.SourceManager, Opts);
+
+  // If it's not 'true' of 'false', that means that it must be inside macro.
+  return LiteralSource == "true" || LiteralSource == "false";
+}
+
+void BoolToIntegerConversionCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  Finder->addMatcher(
+      implicitCastExpr(has(cxxBoolLiteral().bind("bool_literal"))).bind("cast"),
+      this);
+}
+
+void BoolToIntegerConversionCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *BoolLiteral =
+      Result.Nodes.getNodeAs<CXXBoolLiteralExpr>("bool_literal");
+  const auto *Cast = Result.Nodes.getNodeAs<ImplicitCastExpr>("cast");
+  const auto Type = Cast->getType().getLocalUnqualifiedType();
+
+  auto Diag = diag(BoolLiteral->getLocation(),
+                   "implicitly converting bool literal to %0%select{| inside a "
+                   "macro}1; use integer literal instead")
+              << Type;
+
+  if (isPreprocessorIndependent(BoolLiteral, Result))
+    Diag << 0
+         << FixItHint::CreateReplacement(BoolLiteral->getSourceRange(),
+                                         BoolLiteral->getValue() ? "1" : "0");
+  else
+    Diag << 1;
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to