Index: clang-tidy/performance/CMakeLists.txt =================================================================== --- clang-tidy/performance/CMakeLists.txt +++ clang-tidy/performance/CMakeLists.txt @@ -3,7 +3,7 @@ add_clang_library(clangTidyPerformanceModule FasterStringFindCheck.cpp ForRangeCopyCheck.cpp - ImplicitCastInLoopCheck.cpp + ImplicitConversionInLoopCheck.cpp InefficientStringConcatenationCheck.cpp InefficientVectorOperationCheck.cpp PerformanceTidyModule.cpp Index: clang-tidy/performance/ImplicitConversionInLoopCheck.h =================================================================== --- clang-tidy/performance/ImplicitConversionInLoopCheck.h +++ clang-tidy/performance/ImplicitConversionInLoopCheck.h @@ -1,4 +1,4 @@ -//===--- ImplicitCastInLoopCheck.h - clang-tidy------------------*- C++ -*-===// +//===--- ImplicitConversionInLoopCheck.h - clang-tidy------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CAST_IN_LOOP_CHECK_H_ -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CAST_IN_LOOP_CHECK_H_ +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CONVERSION_IN_LOOP_CHECK_H_ +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CONVERSION_IN_LOOP_CHECK_H_ #include "../ClangTidy.h" @@ -19,9 +19,9 @@ // Checks that in a for range loop, if the provided type is a reference, then // the underlying type is the one returned by the iterator (i.e. that there // isn't any implicit conversion). -class ImplicitCastInLoopCheck : public ClangTidyCheck { +class ImplicitConversionInLoopCheck : public ClangTidyCheck { public: - ImplicitCastInLoopCheck(StringRef Name, ClangTidyContext *Context) + ImplicitConversionInLoopCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; @@ -35,4 +35,4 @@ } // namespace tidy } // namespace clang -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CAST_IN_LOOP_CHECK_H_ +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CONVERSION_IN_LOOP_CHECK_H_ Index: clang-tidy/performance/ImplicitConversionInLoopCheck.cpp =================================================================== --- clang-tidy/performance/ImplicitConversionInLoopCheck.cpp +++ clang-tidy/performance/ImplicitConversionInLoopCheck.cpp @@ -1,4 +1,4 @@ -//===--- ImplicitCastInLoopCheck.cpp - clang-tidy--------------------------===// +//===--- ImplicitConversionInLoopCheck.cpp - clang-tidy--------------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "ImplicitCastInLoopCheck.h" +#include "ImplicitConversionInLoopCheck.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" @@ -21,30 +21,30 @@ namespace tidy { namespace performance { -namespace { // Checks if the stmt is a ImplicitCastExpr with a CastKind that is not a NoOp. // The subtelty is that in some cases (user defined conversions), we can // get to ImplicitCastExpr inside each other, with the outer one a NoOp. In this // case we skip the first cast expr. -bool IsNonTrivialImplicitCast(const Stmt *ST) { +static bool IsNonTrivialImplicitCast(const Stmt *ST) { if (const auto *ICE = dyn_cast(ST)) { return (ICE->getCastKind() != CK_NoOp) || IsNonTrivialImplicitCast(ICE->getSubExpr()); } return false; } -} // namespace -void ImplicitCastInLoopCheck::registerMatchers(MatchFinder *Finder) { +void ImplicitConversionInLoopCheck::registerMatchers(MatchFinder *Finder) { // We look for const ref loop variables that (optionally inside an - // ExprWithCleanup) materialize a temporary, and contain a implicit cast. The - // check on the implicit cast is done in check() because we can't access - // implicit cast subnode via matchers: has() skips casts and materialize! - // We also bind on the call to operator* to get the proper type in the - // diagnostic message. - // Note that when the implicit cast is done through a user defined cast - // operator, the node is a CXXMemberCallExpr, not a CXXOperatorCallExpr, so - // it should not get caught by the cxxOperatorCallExpr() matcher. + // ExprWithCleanup) materialize a temporary, and contain a implicit + // conversion. The check on the implicit conversion is done in check() because + // we can't access implicit conversion subnode via matchers: has() skips casts + // and materialize! We also bind on the call to operator* to get the proper + // type in the diagnostic message. + // + // Note that when the implicit conversion is done through a user defined + // conversion operator, the node is a CXXMemberCallExpr, not a + // CXXOperatorCallExpr, so it should not get caught by the + // cxxOperatorCallExpr() matcher. Finder->addMatcher( cxxForRangeStmt(hasLoopVariable( varDecl(hasType(qualType(references(qualType(isConstQualified())))), @@ -55,7 +55,8 @@ this); } -void ImplicitCastInLoopCheck::check(const MatchFinder::MatchResult &Result) { +void ImplicitConversionInLoopCheck::check( + const MatchFinder::MatchResult &Result) { const auto *VD = Result.Nodes.getNodeAs("faulty-var"); const auto *Init = Result.Nodes.getNodeAs("init"); const auto *OperatorCall = @@ -76,7 +77,7 @@ ReportAndFix(Result.Context, VD, OperatorCall); } -void ImplicitCastInLoopCheck::ReportAndFix( +void ImplicitConversionInLoopCheck::ReportAndFix( const ASTContext *Context, const VarDecl *VD, const CXXOperatorCallExpr *OperatorCall) { // We only match on const ref, so we should print a const ref version of the @@ -85,8 +86,8 @@ QualType ConstRefType = Context->getLValueReferenceType(ConstType); const char Message[] = "the type of the loop variable %0 is different from the one returned " - "by the iterator and generates an implicit cast; you can either " - "change the type to the correct one (%1 but 'const auto&' is always a " + "by the iterator and generates an implicit conversion; you can either " + "change the type to the matching one (%1 but 'const auto&' is always a " "valid option) or remove the reference to make it explicit that you are " "creating a new value"; diag(VD->getLocStart(), Message) << VD << ConstRefType; Index: clang-tidy/performance/PerformanceTidyModule.cpp =================================================================== --- clang-tidy/performance/PerformanceTidyModule.cpp +++ clang-tidy/performance/PerformanceTidyModule.cpp @@ -12,7 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "FasterStringFindCheck.h" #include "ForRangeCopyCheck.h" -#include "ImplicitCastInLoopCheck.h" +#include "ImplicitConversionInLoopCheck.h" #include "InefficientStringConcatenationCheck.h" #include "InefficientVectorOperationCheck.h" #include "TypePromotionInMathFnCheck.h" @@ -30,8 +30,8 @@ "performance-faster-string-find"); CheckFactories.registerCheck( "performance-for-range-copy"); - CheckFactories.registerCheck( - "performance-implicit-cast-in-loop"); + CheckFactories.registerCheck( + "performance-implicit-conversion-in-loop"); CheckFactories.registerCheck( "performance-inefficient-string-concatenation"); CheckFactories.registerCheck( Index: clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tidy/readability/CMakeLists.txt +++ clang-tidy/readability/CMakeLists.txt @@ -9,7 +9,7 @@ ElseAfterReturnCheck.cpp FunctionSizeCheck.cpp IdentifierNamingCheck.cpp - ImplicitBoolCastCheck.cpp + ImplicitBoolConversionCheck.cpp InconsistentDeclarationParameterNameCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp Index: clang-tidy/readability/ImplicitBoolConversionCheck.h =================================================================== --- clang-tidy/readability/ImplicitBoolConversionCheck.h +++ clang-tidy/readability/ImplicitBoolConversionCheck.h @@ -1,4 +1,4 @@ -//===--- ImplicitBoolCastCheck.h - clang-tidy--------------------*- C++ -*-===// +//===--- ImplicitBoolConversionCheck.h - clang-tidy--------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CAST_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CAST_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H #include "../ClangTidy.h" @@ -16,13 +16,13 @@ namespace tidy { namespace readability { -/// \brief Checks for use of implicit bool casts in expressions. +/// \brief Checks for use of implicit bool conversions in expressions. /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/readability-implicit-bool-cast.html -class ImplicitBoolCastCheck : public ClangTidyCheck { +/// http://clang.llvm.org/extra/clang-tidy/checks/readability-implicit-bool-conversion.html +class ImplicitBoolConversionCheck : public ClangTidyCheck { public: - ImplicitBoolCastCheck(StringRef Name, ClangTidyContext *Context); + ImplicitBoolConversionCheck(StringRef Name, ClangTidyContext *Context); void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; @@ -35,12 +35,12 @@ const ImplicitCastExpr *FurtherImplicitCastExpression, ASTContext &Context); - bool AllowConditionalIntegerCasts; - bool AllowConditionalPointerCasts; + const bool AllowIntegerConditions; + const bool AllowPointerConditions; }; } // namespace readability } // namespace tidy } // namespace clang -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CAST_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H Index: clang-tidy/readability/ImplicitBoolConversionCheck.cpp =================================================================== --- clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -1,4 +1,4 @@ -//===--- ImplicitBoolCastCheck.cpp - clang-tidy----------------------------===// +//===--- ImplicitBoolConversionCheck.cpp - clang-tidy----------------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "ImplicitBoolCastCheck.h" +#include "ImplicitBoolConversionCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" @@ -218,7 +218,7 @@ return BoolLiteral->getValue() ? "1" : "0"; } -bool isAllowedConditionalCast(const ImplicitCastExpr *Cast, +bool isCastAllowedInCondition(const ImplicitCastExpr *Cast, ASTContext &Context) { std::queue Q; Q.push(Cast); @@ -245,22 +245,19 @@ } // anonymous namespace -ImplicitBoolCastCheck::ImplicitBoolCastCheck(StringRef Name, - ClangTidyContext *Context) +ImplicitBoolConversionCheck::ImplicitBoolConversionCheck( + StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - AllowConditionalIntegerCasts( - Options.get("AllowConditionalIntegerCasts", false)), - AllowConditionalPointerCasts( - Options.get("AllowConditionalPointerCasts", false)) {} - -void ImplicitBoolCastCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "AllowConditionalIntegerCasts", - AllowConditionalIntegerCasts); - Options.store(Opts, "AllowConditionalPointerCasts", - AllowConditionalPointerCasts); + AllowIntegerConditions(Options.get("AllowIntegerConditions", false)), + AllowPointerConditions(Options.get("AllowPointerConditions", false)) {} + +void ImplicitBoolConversionCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "AllowIntegerConditions", AllowIntegerConditions); + Options.store(Opts, "AllowPointerConditions", AllowPointerConditions); } -void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) { +void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { // This check doesn't make much sense if we run it on language without // built-in bool support. if (!getLangOpts().Bool) { @@ -326,7 +323,8 @@ this); } -void ImplicitBoolCastCheck::check(const MatchFinder::MatchResult &Result) { +void ImplicitBoolConversionCheck::check( + const MatchFinder::MatchResult &Result) { if (const auto *CastToBool = Result.Nodes.getNodeAs("implicitCastToBool")) { const auto *Parent = Result.Nodes.getNodeAs("parentStmt"); @@ -341,23 +339,22 @@ } } -void ImplicitBoolCastCheck::handleCastToBool(const ImplicitCastExpr *Cast, - const Stmt *Parent, - ASTContext &Context) { - if (AllowConditionalPointerCasts && +void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast, + const Stmt *Parent, + ASTContext &Context) { + if (AllowPointerConditions && (Cast->getCastKind() == CK_PointerToBoolean || Cast->getCastKind() == CK_MemberPointerToBoolean) && - isAllowedConditionalCast(Cast, Context)) { + isCastAllowedInCondition(Cast, Context)) { return; } - if (AllowConditionalIntegerCasts && - Cast->getCastKind() == CK_IntegralToBoolean && - isAllowedConditionalCast(Cast, Context)) { + if (AllowIntegerConditions && Cast->getCastKind() == CK_IntegralToBoolean && + isCastAllowedInCondition(Cast, Context)) { return; } - auto Diag = diag(Cast->getLocStart(), "implicit cast %0 -> bool") + auto Diag = diag(Cast->getLocStart(), "implicit conversion %0 -> bool") << Cast->getSubExpr()->getType(); StringRef EquivalentLiteral = @@ -369,12 +366,13 @@ } } -void ImplicitBoolCastCheck::handleCastFromBool( +void ImplicitBoolConversionCheck::handleCastFromBool( const ImplicitCastExpr *Cast, const ImplicitCastExpr *NextImplicitCast, ASTContext &Context) { QualType DestType = NextImplicitCast ? NextImplicitCast->getType() : Cast->getType(); - auto Diag = diag(Cast->getLocStart(), "implicit cast bool -> %0") << DestType; + auto Diag = diag(Cast->getLocStart(), "implicit conversion bool -> %0") + << DestType; if (const auto *BoolLiteral = dyn_cast(Cast->getSubExpr())) { Index: clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tidy/readability/ReadabilityTidyModule.cpp @@ -18,7 +18,7 @@ #include "ElseAfterReturnCheck.h" #include "FunctionSizeCheck.h" #include "IdentifierNamingCheck.h" -#include "ImplicitBoolCastCheck.h" +#include "ImplicitBoolConversionCheck.h" #include "InconsistentDeclarationParameterNameCheck.h" #include "MisleadingIndentationCheck.h" #include "MisplacedArrayIndexCheck.h" @@ -58,8 +58,8 @@ "readability-function-size"); CheckFactories.registerCheck( "readability-identifier-naming"); - CheckFactories.registerCheck( - "readability-implicit-bool-cast"); + CheckFactories.registerCheck( + "readability-implicit-bool-conversion"); CheckFactories.registerCheck( "readability-inconsistent-declaration-parameter-name"); CheckFactories.registerCheck( Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -57,7 +57,19 @@ Improvements to clang-tidy -------------------------- -The improvements are... +* Renamed checks to use correct term "implicit conversion" instead of "implicit + cast" and modified messages and option names accordingly: + + - **performance-implicit-cast-in-loop** was renamed to + `performance-implicit-conversion-in-loop + `_ + - **readability-implicit-bool-cast** was renamed to + `readability-implicit-bool-conversion + `_; + the check's options were renamed as follows: + ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``, + ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``. + Improvements to include-fixer ----------------------------- Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -150,7 +150,7 @@ mpi-type-mismatch performance-faster-string-find performance-for-range-copy - performance-implicit-cast-in-loop + performance-implicit-conversion-in-loop performance-inefficient-string-concatenation performance-inefficient-vector-operation performance-type-promotion-in-math-fn @@ -164,7 +164,7 @@ readability-else-after-return readability-function-size readability-identifier-naming - readability-implicit-bool-cast + readability-implicit-bool-conversion readability-inconsistent-declaration-parameter-name readability-misleading-indentation readability-misplaced-array-index Index: docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst =================================================================== --- docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst +++ docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst @@ -1,21 +1,12 @@ +:orphan: + .. title:: clang-tidy - performance-implicit-cast-in-loop +.. meta:: + :http-equiv=refresh: 5;URL=performance-implicit-conversion-in-loop.html performance-implicit-cast-in-loop ================================= -This warning appears in a range-based loop with a loop variable of const ref -type where the type of the variable does not match the one returned by the -iterator. This means that an implicit cast has been added, which can for example -result in expensive deep copies. - -Example: - -.. code-block:: c++ - - map> my_map; - for (const pair>& p : my_map) {} - // The iterator type is in fact pair>, which means - // that the compiler added a cast, resulting in a copy of the vectors. +This check has been renamed to `performance-implicit-conversion-in-loop +`_. -The easiest solution is usually to use ``const auto&`` instead of writing the type -manually. Index: docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst =================================================================== --- docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst +++ docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst @@ -1,11 +1,11 @@ -.. title:: clang-tidy - performance-implicit-cast-in-loop +.. title:: clang-tidy - performance-implicit-conversion-in-loop -performance-implicit-cast-in-loop -================================= +performance-implicit-conversion-in-loop +======================================= This warning appears in a range-based loop with a loop variable of const ref type where the type of the variable does not match the one returned by the -iterator. This means that an implicit cast has been added, which can for example +iterator. This means that an implicit conversion happens, which can for example result in expensive deep copies. Example: @@ -15,7 +15,7 @@ map> my_map; for (const pair>& p : my_map) {} // The iterator type is in fact pair>, which means - // that the compiler added a cast, resulting in a copy of the vectors. + // that the compiler added a conversion, resulting in a copy of the vectors. -The easiest solution is usually to use ``const auto&`` instead of writing the type -manually. +The easiest solution is usually to use ``const auto&`` instead of writing the +type manually. Index: docs/clang-tidy/checks/readability-implicit-bool-cast.rst =================================================================== --- docs/clang-tidy/checks/readability-implicit-bool-cast.rst +++ docs/clang-tidy/checks/readability-implicit-bool-cast.rst @@ -1,130 +1,11 @@ +:orphan: + .. title:: clang-tidy - readability-implicit-bool-cast +.. meta:: + :http-equiv=refresh: 5;URL=readability-implicit-bool-conversion.html readability-implicit-bool-cast ============================== -This check can be used to find implicit conversions between built-in types and -booleans. Depending on use case, it may simply help with readability of the code, -or in some cases, point to potential bugs which remain unnoticed due to implicit -conversions. - -The following is a real-world example of bug which was hiding behind implicit -``bool`` cast: - -.. code-block:: c++ - - class Foo { - int m_foo; - - public: - void setFoo(bool foo) { m_foo = foo; } // warning: implicit cast bool -> int - int getFoo() { return m_foo; } - }; - - void use(Foo& foo) { - bool value = foo.getFoo(); // warning: implicit cast int -> bool - } - -This code is the result of unsuccessful refactoring, where type of ``m_foo`` -changed from ``bool`` to ``int``. The programmer forgot to change all -occurrences of ``bool``, and the remaining code is no longer correct, yet it -still compiles without any visible warnings. - -In addition to issuing warnings, fix-it hints are provided to help solve the -reported issues. This can be used for improving readability of code, for -example: - -.. code-block:: c++ - - void conversionsToBool() { - float floating; - bool boolean = floating; - // ^ propose replacement: bool boolean = floating != 0.0f; - - int integer; - if (integer) {} - // ^ propose replacement: if (integer != 0) {} - - int* pointer; - if (!pointer) {} - // ^ propose replacement: if (pointer == nullptr) {} - - while (1) {} - // ^ propose replacement: while (true) {} - } - - void functionTakingInt(int param); - - void conversionsFromBool() { - bool boolean; - functionTakingInt(boolean); - // ^ propose replacement: functionTakingInt(static_cast(boolean)); - - functionTakingInt(true); - // ^ propose replacement: functionTakingInt(1); - } - -In general, the following cast types are checked: - -- integer expression/literal to boolean, - -- floating expression/literal to boolean, - -- pointer/pointer to member/``nullptr``/``NULL`` to boolean, - -- boolean expression/literal to integer, - -- boolean expression/literal to floating. - -The rules for generating fix-it hints are: - -- in case of casts from other built-in type to bool, an explicit comparison - is proposed to make it clear what exaclty is being compared: - - - ``bool boolean = floating;`` is changed to - ``bool boolean = floating == 0.0f;``, - - - for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``, - ``0.0``, ``nullptr``), - -- in case of negated expressions cast to bool, the proposed replacement with - comparison is simplified: - - - ``if (!pointer)`` is changed to ``if (pointer == nullptr)``, - -- in case of casts from bool to other built-in types, an explicit ``static_cast`` - is proposed to make it clear that a cast is taking place: - - - ``int integer = boolean;`` is changed to - ``int integer = static_cast(boolean);``, - -- if the cast is performed on type literals, an equivalent literal is proposed, - according to what type is actually expected, for example: - - - ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``, - - - ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``, - - - for other types, appropriate literals are used (``false``, ``true``, ``0``, - ``1``, ``0u``, ``1u``, ``0.0f``, ``1.0f``, ``0.0``, ``1.0f``). - -Some additional accommodations are made for pre-C++11 dialects: - -- ``false`` literal cast to pointer is detected, - -- instead of ``nullptr`` literal, ``0`` is proposed as replacement. - -Occurrences of implicit casts inside macros and template instantiations are -deliberately ignored, as it is not clear how to deal with such cases. - -Options -------- - -.. option:: AllowConditionalIntegerCasts - - When non-zero, the check will allow conditional integer casts. Default is - `0`. - -.. option:: AllowConditionalPointerCasts - - When non-zero, the check will allow conditional pointer casts. Default is `0`. +This check has been renamed to `readability-implicit-bool-conversion +`_. Index: docs/clang-tidy/checks/readability-implicit-bool-conversion.rst =================================================================== --- docs/clang-tidy/checks/readability-implicit-bool-conversion.rst +++ docs/clang-tidy/checks/readability-implicit-bool-conversion.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - readability-implicit-bool-cast +.. title:: clang-tidy - readability-implicit-bool-conversion -readability-implicit-bool-cast -============================== +readability-implicit-bool-conversion +==================================== This check can be used to find implicit conversions between built-in types and booleans. Depending on use case, it may simply help with readability of the code, @@ -9,7 +9,7 @@ conversions. The following is a real-world example of bug which was hiding behind implicit -``bool`` cast: +``bool`` conversion: .. code-block:: c++ @@ -17,12 +17,12 @@ int m_foo; public: - void setFoo(bool foo) { m_foo = foo; } // warning: implicit cast bool -> int + void setFoo(bool foo) { m_foo = foo; } // warning: implicit conversion bool -> int int getFoo() { return m_foo; } }; void use(Foo& foo) { - bool value = foo.getFoo(); // warning: implicit cast int -> bool + bool value = foo.getFoo(); // warning: implicit conversion int -> bool } This code is the result of unsuccessful refactoring, where type of ``m_foo`` @@ -64,7 +64,7 @@ // ^ propose replacement: functionTakingInt(1); } -In general, the following cast types are checked: +In general, the following conversion types are checked: - integer expression/literal to boolean, @@ -78,8 +78,8 @@ The rules for generating fix-it hints are: -- in case of casts from other built-in type to bool, an explicit comparison - is proposed to make it clear what exaclty is being compared: +- in case of conversions from other built-in type to bool, an explicit + comparison is proposed to make it clear what exaclty is being compared: - ``bool boolean = floating;`` is changed to ``bool boolean = floating == 0.0f;``, @@ -87,19 +87,20 @@ - for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``, ``0.0``, ``nullptr``), -- in case of negated expressions cast to bool, the proposed replacement with - comparison is simplified: +- in case of negated expressions conversion to bool, the proposed replacement + with comparison is simplified: - ``if (!pointer)`` is changed to ``if (pointer == nullptr)``, -- in case of casts from bool to other built-in types, an explicit ``static_cast`` - is proposed to make it clear that a cast is taking place: +- in case of conversions from bool to other built-in types, an explicit + ``static_cast`` is proposed to make it clear that a conversion is taking + place: - ``int integer = boolean;`` is changed to ``int integer = static_cast(boolean);``, -- if the cast is performed on type literals, an equivalent literal is proposed, - according to what type is actually expected, for example: +- if the conversion is performed on type literals, an equivalent literal is + proposed, according to what type is actually expected, for example: - ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``, @@ -110,21 +111,22 @@ Some additional accommodations are made for pre-C++11 dialects: -- ``false`` literal cast to pointer is detected, +- ``false`` literal conversion to pointer is detected, - instead of ``nullptr`` literal, ``0`` is proposed as replacement. -Occurrences of implicit casts inside macros and template instantiations are -deliberately ignored, as it is not clear how to deal with such cases. +Occurrences of implicit conversions inside macros and template instantiations +are deliberately ignored, as it is not clear how to deal with such cases. Options ------- -.. option:: AllowConditionalIntegerCasts +.. option:: AllowIntegerConditions - When non-zero, the check will allow conditional integer casts. Default is - `0`. + When non-zero, the check will allow conditional integer conversions. Default + is `0`. -.. option:: AllowConditionalPointerCasts +.. option:: AllowPointerConditions - When non-zero, the check will allow conditional pointer casts. Default is `0`. + When non-zero, the check will allow conditional pointer conversions. Default + is `0`. Index: test/clang-tidy/performance-implicit-conversion-in-loop.cpp =================================================================== --- test/clang-tidy/performance-implicit-conversion-in-loop.cpp +++ test/clang-tidy/performance-implicit-conversion-in-loop.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s performance-implicit-cast-in-loop %t +// RUN: %check_clang_tidy %s performance-implicit-conversion-in-loop %t // ---------- Classes used in the tests ---------- @@ -26,8 +26,8 @@ T end(); }; -// With this class, the implicit cast is a call to the (implicit) constructor of -// the class. +// With this class, the implicit conversion is a call to the (implicit) +// constructor of the class. template class ImplicitWrapper { public: @@ -35,8 +35,8 @@ ImplicitWrapper(const T& t); }; -// With this class, the implicit cast is a call to the conversion operators of -// SimpleClass and ComplexClass. +// With this class, the implicit conversion is a call to the conversion +// operators of SimpleClass and ComplexClass. template class OperatorWrapper { public: @@ -98,7 +98,7 @@ void ImplicitSimpleClassIterator() { for (const ImplicitWrapper& foo : SimpleView()) {} - // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the loop variable 'foo' is different from the one returned by the iterator and generates an implicit cast; you can either change the type to the correct one ('const SimpleClass &' but 'const auto&' is always a valid option) or remove the reference to make it explicit that you are creating a new value [performance-implicit-cast-in-loop] + // CHECK-MESSAGES: [[@LINE-1]]:{{[0-9]*}}: warning: the type of the loop variable 'foo' is different from the one returned by the iterator and generates an implicit conversion; you can either change the type to the matching one ('const SimpleClass &' but 'const auto&' is always a valid option) or remove the reference to make it explicit that you are creating a new value [performance-implicit-conversion-in-loop] // for (ImplicitWrapper& foo : SimpleView()) {} for (const ImplicitWrapper foo : SimpleView()) {} for (ImplicitWrapperfoo : SimpleView()) {} Index: test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp =================================================================== --- test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp +++ test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp @@ -1,7 +1,7 @@ -// RUN: %check_clang_tidy %s readability-implicit-bool-cast %t \ +// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \ // RUN: -config='{CheckOptions: \ -// RUN: [{key: readability-implicit-bool-cast.AllowConditionalIntegerCasts, value: 1}, \ -// RUN: {key: readability-implicit-bool-cast.AllowConditionalPointerCasts, value: 1}]}' \ +// RUN: [{key: readability-implicit-bool-conversion.AllowIntegerConditions, value: 1}, \ +// RUN: {key: readability-implicit-bool-conversion.AllowPointerConditions, value: 1}]}' \ // RUN: -- -std=c++11 template @@ -15,14 +15,14 @@ }; -void regularImplicitCastIntegerToBoolIsNotIgnored() { +void regularImplicitConversionIntegerToBoolIsNotIgnored() { int integer = 0; functionTaking(integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool [readability-implicit-bool-cast] + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool [readability-implicit-bool-conversion] // CHECK-FIXES: functionTaking(integer != 0); } -void implicitCastIntegerToBoolInConditionalsIsAllowed() { +void implicitConversionIntegerToBoolInConditionalsIsAllowed() { if (functionReturningInt()) {} if (!functionReturningInt()) {} if (functionReturningInt() && functionReturningPointer()) {} @@ -40,19 +40,19 @@ int *p1 = functionReturningPointer() ?: &value3; } -void regularImplicitCastPointerToBoolIsNotIgnored() { +void regularImplicitConversionPointerToBoolIsNotIgnored() { int* pointer = nullptr; functionTaking(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: functionTaking(pointer != nullptr); int Struct::* memberPointer = &Struct::member; functionTaking(memberPointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int Struct::*' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool // CHECK-FIXES: functionTaking(memberPointer != nullptr); } -void implicitCastPointerToBoolInConditionalsIsAllowed() { +void implicitConversionPointerToBoolInConditionalsIsAllowed() { if (functionReturningPointer()) {} if (not functionReturningPointer()) {} int value1 = functionReturningPointer() ? 1 : 2; Index: test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp =================================================================== --- test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp +++ test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s readability-implicit-bool-cast %t -- -- -std=c++98 +// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t -- -- -std=c++98 // We need NULL macro, but some buildbots don't like including header // This is a portable way of getting it to work @@ -15,31 +15,31 @@ void useOldNullMacroInReplacements() { int* pointer = NULL; functionTaking(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool [readability-implicit-bool-cast] + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool [readability-implicit-bool-conversion] // CHECK-FIXES: functionTaking(pointer != 0); int Struct::* memberPointer = NULL; functionTaking(!memberPointer); - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast 'int Struct::*' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'int Struct::*' -> bool // CHECK-FIXES: functionTaking(memberPointer == 0); } void fixFalseLiteralConvertingToNullPointer() { functionTaking(false); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'int *' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int *' // CHECK-FIXES: functionTaking(0); int* pointer = NULL; if (pointer == false) {} - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicit cast bool -> 'int *' + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: implicit conversion bool -> 'int *' // CHECK-FIXES: if (pointer == 0) {} functionTaking(false); - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast bool -> 'int Struct::*' + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int Struct::*' // CHECK-FIXES: functionTaking(0); int Struct::* memberPointer = NULL; if (memberPointer != false) {} - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'int Struct::*' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int Struct::*' // CHECK-FIXES: if (memberPointer != 0) {} } Index: test/clang-tidy/readability-implicit-bool-conversion.cpp =================================================================== --- test/clang-tidy/readability-implicit-bool-conversion.cpp +++ test/clang-tidy/readability-implicit-bool-conversion.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s readability-implicit-bool-cast %t +// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t // We need NULL macro, but some buildbots don't like including header // This is a portable way of getting it to work @@ -13,42 +13,42 @@ }; -////////// Implicit cast from bool. +////////// Implicit conversion from bool. -void implicitCastFromBoolSimpleCases() { +void implicitConversionFromBoolSimpleCases() { bool boolean = true; functionTaking(boolean); functionTaking(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit cast bool -> 'int' [readability-implicit-bool-cast] + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int' [readability-implicit-bool-conversion] // CHECK-FIXES: functionTaking(static_cast(boolean)); functionTaking(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast bool -> 'unsigned long' + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'unsigned long' // CHECK-FIXES: functionTaking(static_cast(boolean)); functionTaking(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'char' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'char' // CHECK-FIXES: functionTaking(static_cast(boolean)); functionTaking(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float' // CHECK-FIXES: functionTaking(static_cast(boolean)); functionTaking(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double' // CHECK-FIXES: functionTaking(static_cast(boolean)); } -float implicitCastFromBoolInReturnValue() { +float implicitConversionFromBoolInReturnValue() { bool boolean = false; return boolean; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion bool -> 'float' // CHECK-FIXES: return static_cast(boolean); } -void implicitCastFromBoolInSingleBoolExpressions(bool b1, bool b2) { +void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) { bool boolean = true; boolean = b1 ^ b2; boolean = b1 && b2; @@ -58,71 +58,71 @@ boolean = b2 != false; int integer = boolean - 3; - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion bool -> 'int' // CHECK-FIXES: int integer = static_cast(boolean) - 3; float floating = boolean / 0.3f; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'float' // CHECK-FIXES: float floating = static_cast(boolean) / 0.3f; char character = boolean; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'char' + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'char' // CHECK-FIXES: char character = static_cast(boolean); } -void implicitCastFromBoollInComplexBoolExpressions() { +void implicitConversionFromBoollInComplexBoolExpressions() { bool boolean = true; bool anotherBoolean = false; int integer = boolean && anotherBoolean; - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion bool -> 'int' // CHECK-FIXES: int integer = static_cast(boolean && anotherBoolean); unsigned long unsignedLong = (! boolean) + 4ul; - // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast bool -> 'unsigned long' + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion bool -> 'unsigned long' // CHECK-FIXES: unsigned long unsignedLong = static_cast(! boolean) + 4ul; float floating = (boolean || anotherBoolean) * 0.3f; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion bool -> 'float' // CHECK-FIXES: float floating = static_cast(boolean || anotherBoolean) * 0.3f; double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3; - // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit cast bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion bool -> 'double' // CHECK-FIXES: double doubleFloating = static_cast(boolean && (anotherBoolean || boolean)) * 0.3; } -void implicitCastFromBoolLiterals() { +void implicitConversionFromBoolLiterals() { functionTaking(true); - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int' // CHECK-FIXES: functionTaking(1); functionTaking(false); - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast bool -> 'unsigned long' + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'unsigned long' // CHECK-FIXES: functionTaking(0u); functionTaking(true); - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit cast bool -> 'signed char' + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit conversion bool -> 'signed char' // CHECK-FIXES: functionTaking(1); functionTaking(false); - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float' // CHECK-FIXES: functionTaking(0.0f); functionTaking(true); - // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double' // CHECK-FIXES: functionTaking(1.0); } -void implicitCastFromBoolInComparisons() { +void implicitConversionFromBoolInComparisons() { bool boolean = true; int integer = 0; functionTaking(boolean == integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int' // CHECK-FIXES: functionTaking(static_cast(boolean) == integer); functionTaking(integer != boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit conversion bool -> 'int' // CHECK-FIXES: functionTaking(integer != static_cast(boolean)); } @@ -142,7 +142,7 @@ char character = static_cast(boolean); } -void ignoreImplicitCastFromBoolInMacroExpansions() { +void ignoreImplicitConversionFromBoolInMacroExpansions() { bool boolean = true; #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3 @@ -152,7 +152,7 @@ int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean); } -namespace ignoreImplicitCastFromBoolInTemplateInstantiations { +namespace ignoreImplicitConversionFromBoolInTemplateInstantiations { template void templateFunction() { @@ -164,204 +164,204 @@ templateFunction(); } -} // namespace ignoreImplicitCastFromBoolInTemplateInstantiations +} // namespace ignoreImplicitConversionFromBoolInTemplateInstantiations -////////// Implicit cast to bool. +////////// Implicit conversions to bool. -void implicitCastToBoolSimpleCases() { +void implicitConversionToBoolSimpleCases() { int integer = 10; functionTaking(integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking(integer != 0); unsigned long unsignedLong = 10; functionTaking(unsignedLong); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'unsigned long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> bool // CHECK-FIXES: functionTaking(unsignedLong != 0u); float floating = 0.0f; functionTaking(floating); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool // CHECK-FIXES: functionTaking(floating != 0.0f); double doubleFloating = 1.0f; functionTaking(doubleFloating); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool // CHECK-FIXES: functionTaking(doubleFloating != 0.0); signed char character = 'a'; functionTaking(character); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'signed char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> bool // CHECK-FIXES: functionTaking(character != 0); int* pointer = nullptr; functionTaking(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: functionTaking(pointer != nullptr); auto pointerToMember = &Struct::member; functionTaking(pointerToMember); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int Struct::*' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> bool // CHECK-FIXES: functionTaking(pointerToMember != nullptr); } -void implicitCastToBoolInSingleExpressions() { +void implicitConversionToBoolInSingleExpressions() { int integer = 10; bool boolComingFromInt = integer; - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'int' -> bool // CHECK-FIXES: bool boolComingFromInt = integer != 0; float floating = 10.0f; bool boolComingFromFloat = floating; - // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'float' -> bool // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f; signed char character = 'a'; bool boolComingFromChar = character; - // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit cast 'signed char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: implicit conversion 'signed char' -> bool // CHECK-FIXES: bool boolComingFromChar = character != 0; int* pointer = nullptr; bool boolComingFromPointer = pointer; - // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr; } -void implicitCastToBoolInComplexExpressions() { +void implicitConversionToBoolInComplexExpressions() { bool boolean = true; int integer = 10; int anotherInteger = 20; bool boolComingFromInteger = integer + anotherInteger; - // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int' -> bool // CHECK-FIXES: bool boolComingFromInteger = (integer + anotherInteger) != 0; float floating = 0.2f; bool boolComingFromFloating = floating - 0.3f || boolean; - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'float' -> bool // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean; double doubleFloating = 0.3; bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean; - // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'double' -> bool // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean; } -void implicitCastInNegationExpressions() { +void implicitConversionInNegationExpressions() { int integer = 10; bool boolComingFromNegatedInt = !integer; - // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit conversion 'int' -> bool // CHECK-FIXES: bool boolComingFromNegatedInt = integer == 0; float floating = 10.0f; bool boolComingFromNegatedFloat = ! floating; - // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'float' -> bool // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f; signed char character = 'a'; bool boolComingFromNegatedChar = (! character); - // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit cast 'signed char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'signed char' -> bool // CHECK-FIXES: bool boolComingFromNegatedChar = (character == 0); int* pointer = nullptr; bool boolComingFromNegatedPointer = not pointer; - // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr; } -void implicitCastToBoolInControlStatements() { +void implicitConversionToBoolInControlStatements() { int integer = 10; if (integer) {} - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit conversion 'int' -> bool // CHECK-FIXES: if (integer != 0) {} long int longInteger = 0.2f; for (;longInteger;) {} - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit cast 'long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'long' -> bool // CHECK-FIXES: for (;longInteger != 0;) {} float floating = 0.3f; while (floating) {} - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> bool // CHECK-FIXES: while (floating != 0.0f) {} double doubleFloating = 0.4; do {} while (doubleFloating); - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit conversion 'double' -> bool // CHECK-FIXES: do {} while (doubleFloating != 0.0); } -bool implicitCastToBoolInReturnValue() { +bool implicitConversionToBoolInReturnValue() { float floating = 1.0f; return floating; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> bool // CHECK-FIXES: return floating != 0.0f; } -void implicitCastToBoolFromLiterals() { +void implicitConversionToBoolFromLiterals() { functionTaking(0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking(false); functionTaking(1); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking(true); functionTaking(2ul); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'unsigned long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> bool // CHECK-FIXES: functionTaking(true); functionTaking(0.0f); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool // CHECK-FIXES: functionTaking(false); functionTaking(1.0f); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool // CHECK-FIXES: functionTaking(true); functionTaking(2.0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool // CHECK-FIXES: functionTaking(true); functionTaking('\0'); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool // CHECK-FIXES: functionTaking(false); functionTaking('a'); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool // CHECK-FIXES: functionTaking(true); functionTaking(""); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'const char *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> bool // CHECK-FIXES: functionTaking(true); functionTaking("abc"); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'const char *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'const char *' -> bool // CHECK-FIXES: functionTaking(true); functionTaking(NULL); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> bool // CHECK-FIXES: functionTaking(false); } -void implicitCastToBoolFromUnaryMinusAndZeroLiterals() { +void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() { functionTaking(-0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking((-0) != 0); functionTaking(-0.0f); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool // CHECK-FIXES: functionTaking((-0.0f) != 0.0f); functionTaking(-0.0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool // CHECK-FIXES: functionTaking((-0.0) != 0.0); } -void implicitCastToBoolInWithOverloadedOperators() { +void implicitConversionToBoolInWithOverloadedOperators() { struct UserStruct { int operator()(int x) { return x; } int operator+(int y) { return y; } @@ -370,18 +370,18 @@ UserStruct s; functionTaking(s(0)); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking(s(0) != 0); functionTaking(s + 2); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking((s + 2) != 0); } int functionReturningInt(); int* functionReturningPointer(); -void ignoreImplicitCastToBoolWhenDeclaringVariableInControlStatements() { +void ignoreImplicitConversionToBoolWhenDeclaringVariableInControlStatements() { if (int integer = functionReturningInt()) {} while (int* pointer = functionReturningPointer()) {} @@ -401,7 +401,7 @@ bool booleanComingFromPointer = static_cast(pointer); } -void ignoreImplicitCastToBoolInMacroExpansions() { +void ignoreImplicitConversionToBoolInMacroExpansions() { int integer = 3; #define CAST_TO_BOOL_IN_MACRO_BODY integer && false @@ -411,7 +411,7 @@ bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer); } -namespace ignoreImplicitCastToBoolInTemplateInstantiations { +namespace ignoreImplicitConversionToBoolInTemplateInstantiations { template void templateFunction() { @@ -423,7 +423,7 @@ templateFunction(); } -} // namespace ignoreImplicitCastToBoolInTemplateInstantiations +} // namespace ignoreImplicitConversionToBoolInTemplateInstantiations namespace ignoreUserDefinedConversionOperator {