diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp index 193bb61f5b43..ece8cd5860e0 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -18,6 +18,11 @@ namespace clang { namespace tidy { namespace modernize { +UseBoolLiteralsCheck::UseBoolLiteralsCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} + void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; @@ -52,11 +57,16 @@ void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) { const Expr *Expression = Cast ? Cast : Literal; + bool InMacro = Expression->getLocStart().isMacroID(); + + if (InMacro && IgnoreMacros) + return; + auto Diag = diag(Expression->getExprLoc(), "converting integer literal to bool, use bool literal instead"); - if (!Expression->getLocStart().isMacroID()) + if (!InMacro) Diag << FixItHint::CreateReplacement( Expression->getSourceRange(), LiteralBooleanValue ? "true" : "false"); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h index 46d787995427..c9c736349a08 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h @@ -22,10 +22,12 @@ namespace modernize { /// 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) {} + UseBoolLiteralsCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool IgnoreMacros; }; } // namespace modernize diff --git a/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp new file mode 100644 index 000000000000..cf8f72c97644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals-ignore-macros.cpp @@ -0,0 +1,148 @@ +// RUN: %check_clang_tidy %s modernize-use-bool-literals %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: modernize-use-bool-literals.IgnoreMacros, \ +// RUN: value: 1}]}" \ +// RUN: -- -std=c++11 + +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: converting integer literal to bool +// CHECK-FIXES: {{^}}bool IntToFalse(false);{{$}} + +bool LongLongToTrue{0x1LL}; +// 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: converting integer literal to bool +// CHECK-FIXES: {{^}}bool ExplicitCStyleIntToFalse = false;{{$}} + +bool ExplicitFunctionalIntToFalse = bool(0); +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: converting integer literal to bool +// CHECK-FIXES: {{^}}bool ExplicitFunctionalIntToFalse = false;{{$}} + +bool ExplicitStaticIntToFalse = static_cast(0); +// 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-FIXES: {{^}}bool MacroIntToTrue = TRUE_MACRO;{{$}} + +#define FALSE_MACRO bool(0) +// CHECK-FIXES: {{^}}#define FALSE_MACRO bool(0){{$}} + +bool TrueBool = true; // OK + +bool FalseBool = bool(FALSE_MACRO); +// CHECK-FIXES: {{^}}bool FalseBool = bool(FALSE_MACRO);{{$}} + +void boolFunction(bool bar) { + +} + +char Character = 0; // OK + +unsigned long long LongInteger = 1; // OK + +#define MACRO_DEPENDENT_CAST(x) static_cast(x) +// CHECK-FIXES: {{^}}#define MACRO_DEPENDENT_CAST(x) static_cast(x){{$}} + +bool MacroDependentBool = MACRO_DEPENDENT_CAST(0); +// CHECK-FIXES: {{^}}bool MacroDependentBool = MACRO_DEPENDENT_CAST(0);{{$}} + +bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO); +// CHECK-FIXES: {{^}}bool ManyMacrosDependent = MACRO_DEPENDENT_CAST(FALSE_MACRO);{{$}} + +class FooClass { + public: + FooClass() : JustBool(0) {} + // 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: converting integer literal to bool + // CHECK-FIXES: {{^ *}}FooClass(int) : JustBool{false} {}{{$}} + private: + bool JustBool; + bool BoolWithBraces{0}; + // 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: converting integer literal to bool + // CHECK-FIXES: {{^ *}}bool BoolFromInt = false;{{$}} + bool SimpleBool = true; // OK +}; + +template +void templateFunction(type) { + type TemplateType = 0; + // CHECK-FIXES: {{^ *}}type TemplateType = 0;{{$}} +} + +template +void valueDependentTemplateFunction() { + bool Boolean = c; + // CHECK-FIXES: {{^ *}}bool Boolean = c;{{$}} +} + +template +void anotherTemplateFunction(type) { + bool JustBool = 0; + // 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: converting integer literal to bool + // CHECK-FIXES: {{^ *}}boolFunction(true);{{$}} + + boolFunction(false); + + templateFunction(0); + + templateFunction(false); + + valueDependentTemplateFunction<1>(); + + anotherTemplateFunction(1); + + IntToTrue = 1; + // 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;{{$}} +} diff --git a/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp b/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp index 35c3ec45d278..f2ab9ce438ae 100644 --- a/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp +++ b/clang-tools-extra/test/clang-tidy/modernize-use-bool-literals.cpp @@ -1,4 +1,8 @@ -// RUN: %check_clang_tidy %s modernize-use-bool-literals %t +// RUN: %check_clang_tidy %s modernize-use-bool-literals %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: modernize-use-bool-literals.IgnoreMacros, \ +// RUN: value: 0}]}" \ +// RUN: -- -std=c++11 bool IntToTrue = 1; // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]