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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits