Prazek retitled this revision from "Add modernize-bool-to-integer-conversion" 
to "Add bugprone-bool-to-integer-conversion".
Prazek updated this revision to Diff 56138.
Prazek added a comment.

It seems that it works right now.
The other funny thing that the check found is cases like

bool b;
if (b == true)

I will update the llvm/clang changes today.
Do you want to see only the changes that clang-tidy made, or do you want to see 
it after some changing that I will do?


http://reviews.llvm.org/D18821

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/bugprone/BoolToIntegerConversionCheck.cpp
  clang-tidy/bugprone/BoolToIntegerConversionCheck.h
  clang-tidy/bugprone/BugProneModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-bool-to-integer-conversion.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/bugprone-bool-to-integer-conversion.cpp

Index: test/clang-tidy/bugprone-bool-to-integer-conversion.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/bugprone-bool-to-integer-conversion.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s bugprone-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 [bugprone-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 [bugprone-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;
+
+// Don't warn of bitfields of size 1. Unfortunately we can't just
+// change type of flag to bool, because some compilers like MSVC doesn't
+// pack bitfields of different types.
+struct BitFields {
+  BitFields() : a(true), flag(false) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: implicitly converting
+// CHECK-FIXES: BitFields() : a(1), flag(false) {}
+
+  unsigned a : 3;
+  unsigned flag : 1;
+};
+
+void testBitFields() {
+  BitFields b;
+  b.flag = true;
+  b.a = true;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicitly converting
+// CHECK-FIXES: b.a = 1;
+}
+
Index: docs/clang-tidy/index.rst
===================================================================
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -67,7 +67,9 @@
 
 * Clang static analyzer checks are named starting with ``clang-analyzer-``.
 
-* Checks related to Boost library starts with ``boost-``. 
+* Checks related to Boost library starts with ``boost-``.
+
+* The ``bugprone-*`` checks target code that have some potential bugs.
   
 Clang diagnostics are treated in a similar way as check diagnostics. Clang
 diagnostics are displayed by clang-tidy and can be filtered out using
@@ -347,6 +349,8 @@
 
 * `C++ Core Guidelines
   <http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/>`_
+* potential `bugprone code
+  <http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/bugprone/>`_
 * `CERT Secure Coding Standards
   <http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/cert/>`_
 * `Google Style Guide
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -90,6 +90,7 @@
    misc-unused-raii
    misc-unused-using-decls
    misc-virtual-near-miss
+   modernize-bool-to-integer-conversion
    modernize-deprecated-headers
    modernize-loop-convert
    modernize-make-shared
Index: docs/clang-tidy/checks/bugprone-bool-to-integer-conversion.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/bugprone-bool-to-integer-conversion.rst
@@ -0,0 +1,47 @@
+.. title:: clang-tidy - bugprone-bool-to-integer-conversion
+
+bugprone-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
+
+Because bitfields packing are compiler dependent, check treats single-bit
+bitfields as bools
+
+.. code-block:: C++
+
+  struct BitFields {
+    BitFields() : notAFlag(true), b(false) {}
+    unsigned notAFlag : 3;
+    unsigned flag : 1;
+  };
+
+  // Changes to
+  struct BitFields {
+    BitFields() : notAFlag(1), b(false) {}
+    unsigned notAFlag : 3;
+    unsigned flag : 1;
+  };
+
+Note: be aware that check will fire for code:
+
+.. code-block:: C++
+
+    bool p;
+    auto z = p == true;
+    //            ^
+
+This is because z and ``true`` will be implicitly converted to int by promotion.
+To get rid of this case use
+`readability-simplify-boolean-expr
+<http://clang.llvm.org/extra/clang-tidy/checks/readability-simplify-boolean-expr.html>`_.
+
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -63,6 +63,13 @@
 explain them more clearly, and provide more accurate fix-its for the issues
 identified.  The improvements since the 3.8 release include:
 
+- New bugprone module containing checks looking for bugprone code.
+
+- New `bugprone-bool-to-integer-conversion
+  <http://clang.llvm.org/extra/clang-tidy/checks/bugprone-bool-to-integer-conversion.html>`_ check
+
+  Replaces bool literals which are being implicitly cast to integers with integer literals.
+
 - New Boost module containing checks for issues with Boost library.
 
 - New `boost-use-to-string 
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -413,6 +413,11 @@
   return 0;
 }
 
+// This anchor is used to force the linker to link the BugProneModule.
+extern volatile int BugProneModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED BugProneModuleAnchorDestination =
+    BugProneModuleAnchorSource;
+
 // This anchor is used to force the linker to link the CERTModule.
 extern volatile int CERTModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED CERTModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===================================================================
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -10,6 +10,7 @@
   clangASTMatchers
   clangBasic
   clangTidy
+  clangTidyBugProneModule
   clangTidyBoostModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
Index: clang-tidy/plugin/CMakeLists.txt
===================================================================
--- clang-tidy/plugin/CMakeLists.txt
+++ clang-tidy/plugin/CMakeLists.txt
@@ -8,6 +8,7 @@
   clangFrontend
   clangSema
   clangTidy
+  clangTidyBugProneModule
   clangTidyBoostModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
Index: clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyBugProneModule
+  BugProneModule.cpp
+  BoolToIntegerConversionCheck.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )
Index: clang-tidy/bugprone/BugProneModule.cpp
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/BugProneModule.cpp
@@ -0,0 +1,40 @@
+//===------- BugProneTidyModule.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 "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+#include "BoolToIntegerConversionCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+class BugProneModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<BoolToIntegerConversionCheck>(
+      "bugprone-bool-to-integer-conversion");
+  }
+};
+
+// Register the BoostModule using this statically initialized variable.
+static ClangTidyModuleRegistry::Add<BugProneModule> X("bugprone-module",
+                                                   "Add bugprone checks.");
+
+} // namespace bugprone
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the BoostModule.
+volatile int BugProneModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/bugprone/BoolToIntegerConversionCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/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 bugprone {
+
+/// 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 bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_BOOL_TO_INTEGER_CONVERSION_H
Index: clang-tidy/bugprone/BoolToIntegerConversionCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/bugprone/BoolToIntegerConversionCheck.cpp
@@ -0,0 +1,71 @@
+//===--- 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 bugprone {
+
+AST_MATCHER(FieldDecl, isOneBitBitField) {
+  return Node.isBitField() &&
+         Node.getBitWidthValue(Finder->getASTContext()) == 1;
+}
+
+void BoolToIntegerConversionCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  auto convertingToOneBitBitfieldInInitializer = hasAncestor(
+      cxxConstructorDecl(hasAnyConstructorInitializer(cxxCtorInitializer(
+          forField(isOneBitBitField()),
+          withInitializer(implicitCastExpr(equalsBoundNode("cast")))))));
+
+  auto convertingToOneBitBitfieldByOperator =
+      hasParent(binaryOperator(hasLHS(memberExpr(
+          hasDeclaration(fieldDecl(isOneBitBitField()).bind("bitfield"))))));
+
+  Finder->addMatcher(
+      stmt(allOf(implicitCastExpr(has(cxxBoolLiteral().bind("bool_literal")))
+                     .bind("cast"),
+                 unless(anyOf(convertingToOneBitBitfieldByOperator,
+                              convertingToOneBitBitfieldInInitializer)))),
+      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 Location = BoolLiteral->getLocation();
+
+  auto Diag = diag(Location,
+                   "implicitly converting bool literal to %0%select{| inside a "
+                   "macro}1; use integer literal instead")
+              << Type;
+
+  if (Location.isMacroID())
+    Diag << 1;
+  else
+    Diag << 0
+         << FixItHint::CreateReplacement(BoolLiteral->getSourceRange(),
+                                         BoolLiteral->getValue() ? "1" : "0");
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/CMakeLists.txt
===================================================================
--- clang-tidy/CMakeLists.txt
+++ clang-tidy/CMakeLists.txt
@@ -27,6 +27,7 @@
 
 add_subdirectory(tool)
 add_subdirectory(plugin)
+add_subdirectory(bugprone)
 add_subdirectory(boost)
 add_subdirectory(cert)
 add_subdirectory(llvm)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to