diff options
author | Alexander Kornienko <alexfh@google.com> | 2017-08-08 14:53:52 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2017-08-08 14:53:52 +0000 |
commit | f1a6552a95ef359317405b6b905e452c0577d22c (patch) | |
tree | af10b95774e60b52b2270e32b9b11a7e868a0145 | |
parent | 64d31edef33097f3878a12285a6db4d1e9488454 (diff) | |
download | bcm5719-llvm-f1a6552a95ef359317405b6b905e452c0577d22c.tar.gz bcm5719-llvm-f1a6552a95ef359317405b6b905e452c0577d22c.zip |
[clang-tidy] 'implicit cast' -> 'implicit conversion'
Summary:
This patch renames checks, check options and changes messages to use correct
term "implicit conversion" instead of "implicit cast" (which has been in use in
Clang AST since ~10 years, but it's still technically incorrect w.r.t. C++
standard).
* performance-implicit-cast-in-loop -> performance-implicit-conversion-in-loop
* readability-implicit-bool-cast -> readability-implicit-bool-conversion
- readability-implicit-bool-cast.AllowConditionalIntegerCasts ->
readability-implicit-bool-conversion.AllowIntegerConditions
- readability-implicit-bool-cast.AllowConditionalPointerCasts ->
readability-implicit-bool-conversion.AllowPointerConditions
Reviewers: hokein, jdennett
Reviewed By: hokein
Subscribers: mgorny, JDevlieghere, xazax.hun, cfe-commits
Differential Revision: https://reviews.llvm.org/D36456
llvm-svn: 310366
18 files changed, 356 insertions, 320 deletions
diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt index 102e76eceaa..4b5541fdea1 100644 --- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyPerformanceModule FasterStringFindCheck.cpp ForRangeCopyCheck.cpp - ImplicitCastInLoopCheck.cpp + ImplicitConversionInLoopCheck.cpp InefficientStringConcatenationCheck.cpp InefficientVectorOperationCheck.cpp PerformanceTidyModule.cpp diff --git a/clang-tools-extra/clang-tidy/performance/ImplicitCastInLoopCheck.cpp b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp index 7bd3f8a303a..2acbca3456d 100644 --- a/clang-tools-extra/clang-tidy/performance/ImplicitCastInLoopCheck.cpp +++ b/clang-tools-extra/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 clang { 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<ImplicitCastExpr>(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 @@ void ImplicitCastInLoopCheck::registerMatchers(MatchFinder *Finder) { this); } -void ImplicitCastInLoopCheck::check(const MatchFinder::MatchResult &Result) { +void ImplicitConversionInLoopCheck::check( + const MatchFinder::MatchResult &Result) { const auto *VD = Result.Nodes.getNodeAs<VarDecl>("faulty-var"); const auto *Init = Result.Nodes.getNodeAs<Expr>("init"); const auto *OperatorCall = @@ -76,7 +77,7 @@ void ImplicitCastInLoopCheck::check(const MatchFinder::MatchResult &Result) { 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 @@ void ImplicitCastInLoopCheck::ReportAndFix( 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; diff --git a/clang-tools-extra/clang-tidy/performance/ImplicitCastInLoopCheck.h b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.h index 3a9659d6602..8a459ab0012 100644 --- a/clang-tools-extra/clang-tidy/performance/ImplicitCastInLoopCheck.h +++ b/clang-tools-extra/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 @@ namespace performance { // 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 @@ private: } // 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_ diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp index 072f817eedb..b4652509aee 100644 --- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp +++ b/clang-tools-extra/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 @@ public: "performance-faster-string-find"); CheckFactories.registerCheck<ForRangeCopyCheck>( "performance-for-range-copy"); - CheckFactories.registerCheck<ImplicitCastInLoopCheck>( - "performance-implicit-cast-in-loop"); + CheckFactories.registerCheck<ImplicitConversionInLoopCheck>( + "performance-implicit-conversion-in-loop"); CheckFactories.registerCheck<InefficientStringConcatenationCheck>( "performance-inefficient-string-concatenation"); CheckFactories.registerCheck<InefficientVectorOperationCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index bed728731ed..8e6c6581735 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -9,7 +9,7 @@ add_clang_library(clangTidyReadabilityModule ElseAfterReturnCheck.cpp FunctionSizeCheck.cpp IdentifierNamingCheck.cpp - ImplicitBoolCastCheck.cpp + ImplicitBoolConversionCheck.cpp InconsistentDeclarationParameterNameCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index 996219c8bd8..79022d4259a 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp +++ b/clang-tools-extra/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 @@ StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral, return BoolLiteral->getValue() ? "1" : "0"; } -bool isAllowedConditionalCast(const ImplicitCastExpr *Cast, +bool isCastAllowedInCondition(const ImplicitCastExpr *Cast, ASTContext &Context) { std::queue<const Stmt *> Q; Q.push(Cast); @@ -245,22 +245,19 @@ bool isAllowedConditionalCast(const ImplicitCastExpr *Cast, } // 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 @@ void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) { this); } -void ImplicitBoolCastCheck::check(const MatchFinder::MatchResult &Result) { +void ImplicitBoolConversionCheck::check( + const MatchFinder::MatchResult &Result) { if (const auto *CastToBool = Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) { const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt"); @@ -341,23 +339,22 @@ void ImplicitBoolCastCheck::check(const MatchFinder::MatchResult &Result) { } } -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::handleCastToBool(const ImplicitCastExpr *Cast, } } -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<CXXBoolLiteralExpr>(Cast->getSubExpr())) { diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h index cd8addfde64..bb062e02e05 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.h +++ b/clang-tools-extra/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 clang { 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 @@ private: 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 diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index dacea0d1e4d..81a9d6f3d00 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/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 @@ public: "readability-function-size"); CheckFactories.registerCheck<IdentifierNamingCheck>( "readability-identifier-naming"); - CheckFactories.registerCheck<ImplicitBoolCastCheck>( - "readability-implicit-bool-cast"); + CheckFactories.registerCheck<ImplicitBoolConversionCheck>( + "readability-implicit-bool-conversion"); CheckFactories.registerCheck<InconsistentDeclarationParameterNameCheck>( "readability-inconsistent-declaration-parameter-name"); CheckFactories.registerCheck<MisleadingIndentationCheck>( diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e46ed1700e6..434552fe809 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -57,7 +57,19 @@ The improvements are... 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 + <http://clang.llvm.org/extra/clang-tidy/checks/performance-implicit-conversion-in-loop.html>`_ + - **readability-implicit-bool-cast** was renamed to + `readability-implicit-bool-conversion + <http://clang.llvm.org/extra/clang-tidy/checks/readability-implicit-bool-conversion.html>`_; + the check's options were renamed as follows: + ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``, + ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``. + Improvements to include-fixer ----------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index cb68092d9fa..346612a09bc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -150,7 +150,7 @@ Clang-Tidy Checks 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 @@ Clang-Tidy Checks 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 diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst b/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst index 7a5cdf4193e..280e7c046f4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-cast-in-loop.rst +++ b/clang-tools-extra/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<int, vector<string>> my_map; - for (const pair<int, vector<string>>& p : my_map) {} - // The iterator type is in fact pair<const int, vector<string>>, 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 +<performance-implicit-conversion-in-loop.html>`_. -The easiest solution is usually to use ``const auto&`` instead of writing the type -manually. diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst b/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst new file mode 100644 index 00000000000..14e4d31f974 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/performance-implicit-conversion-in-loop.rst @@ -0,0 +1,21 @@ +.. title:: clang-tidy - performance-implicit-conversion-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 conversion happens, which can for example +result in expensive deep copies. + +Example: + +.. code-block:: c++ + + map<int, vector<string>> my_map; + for (const pair<int, vector<string>>& p : my_map) {} + // The iterator type is in fact pair<const int, vector<string>>, which means + // 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. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-cast.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-cast.rst index bcd23abf74d..a6a3492681d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-cast.rst +++ b/clang-tools-extra/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<int>(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<int>(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 +<readability-implicit-bool-conversion.html>`_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst new file mode 100644 index 00000000000..64f3f73673c --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-implicit-bool-conversion.rst @@ -0,0 +1,132 @@ +.. title:: clang-tidy - readability-implicit-bool-conversion + +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, +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`` conversion: + +.. code-block:: c++ + + class Foo { + int m_foo; + + public: + 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 conversion 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<int>(boolean)); + + functionTakingInt(true); + // ^ propose replacement: functionTakingInt(1); + } + +In general, the following conversion 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 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;``, + + - for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``, + ``0.0``, ``nullptr``), + +- 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 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<int>(boolean);``, + +- 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);``, + + - ``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 conversion to pointer is detected, + +- instead of ``nullptr`` literal, ``0`` is proposed as replacement. + +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:: AllowIntegerConditions + + When non-zero, the check will allow conditional integer conversions. Default + is `0`. + +.. option:: AllowPointerConditions + + When non-zero, the check will allow conditional pointer conversions. Default + is `0`. diff --git a/clang-tools-extra/test/clang-tidy/performance-implicit-cast-in-loop.cpp b/clang-tools-extra/test/clang-tidy/performance-implicit-conversion-in-loop.cpp index 788debe78ff..7b1ad3967f0 100644 --- a/clang-tools-extra/test/clang-tidy/performance-implicit-cast-in-loop.cpp +++ b/clang-tools-extra/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 @@ struct View { 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 <typename T> class ImplicitWrapper { public: @@ -35,8 +35,8 @@ class ImplicitWrapper { 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 <typename T> class OperatorWrapper { public: @@ -98,7 +98,7 @@ void ComplexClassRefIterator() { void ImplicitSimpleClassIterator() { for (const ImplicitWrapper<SimpleClass>& 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<SimpleClass>& foo : SimpleView()) {} for (const ImplicitWrapper<SimpleClass> foo : SimpleView()) {} for (ImplicitWrapper<SimpleClass>foo : SimpleView()) {} diff --git a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast-allow-conditional-casts.cpp b/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-allow-in-conditions.cpp index 19c08eca70d..13524de8383 100644 --- a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast-allow-conditional-casts.cpp +++ b/clang-tools-extra/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<typename T> @@ -15,14 +15,14 @@ struct Struct { }; -void regularImplicitCastIntegerToBoolIsNotIgnored() { +void regularImplicitConversionIntegerToBoolIsNotIgnored() { int integer = 0; functionTaking<bool>(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<bool>(integer != 0); } -void implicitCastIntegerToBoolInConditionalsIsAllowed() { +void implicitConversionIntegerToBoolInConditionalsIsAllowed() { if (functionReturningInt()) {} if (!functionReturningInt()) {} if (functionReturningInt() && functionReturningPointer()) {} @@ -40,19 +40,19 @@ void implicitCastIntegerToBoolInConditionalsIsAllowed() { int *p1 = functionReturningPointer() ?: &value3; } -void regularImplicitCastPointerToBoolIsNotIgnored() { +void regularImplicitConversionPointerToBoolIsNotIgnored() { int* pointer = nullptr; functionTaking<bool>(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); int Struct::* memberPointer = &Struct::member; functionTaking<bool>(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<bool>(memberPointer != nullptr); } -void implicitCastPointerToBoolInConditionalsIsAllowed() { +void implicitConversionPointerToBoolInConditionalsIsAllowed() { if (functionReturningPointer()) {} if (not functionReturningPointer()) {} int value1 = functionReturningPointer() ? 1 : 2; diff --git a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast-cxx98.cpp b/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion-cxx98.cpp index 791c7a1f3ca..587f7e259d7 100644 --- a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast-cxx98.cpp +++ b/clang-tools-extra/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 <cstddef> header // This is a portable way of getting it to work @@ -15,31 +15,31 @@ struct Struct { void useOldNullMacroInReplacements() { int* pointer = NULL; functionTaking<bool>(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<bool>(pointer != 0); int Struct::* memberPointer = NULL; functionTaking<bool>(!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<bool>(memberPointer == 0); } void fixFalseLiteralConvertingToNullPointer() { functionTaking<int*>(false); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'int *' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'int *' // CHECK-FIXES: functionTaking<int*>(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<int Struct::*>(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<int Struct::*>(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) {} } diff --git a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp b/clang-tools-extra/test/clang-tidy/readability-implicit-bool-conversion.cpp index 9e4aac7eb87..0bdd6703c61 100644 --- a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp +++ b/clang-tools-extra/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 <cstddef> header // This is a portable way of getting it to work @@ -13,42 +13,42 @@ struct Struct { }; -////////// Implicit cast from bool. +////////// Implicit conversion from bool. -void implicitCastFromBoolSimpleCases() { +void implicitConversionFromBoolSimpleCases() { bool boolean = true; functionTaking<bool>(boolean); functionTaking<int>(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<int>(static_cast<int>(boolean)); functionTaking<unsigned long>(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<unsigned long>(static_cast<unsigned long>(boolean)); functionTaking<char>(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast bool -> 'char' + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion bool -> 'char' // CHECK-FIXES: functionTaking<char>(static_cast<char>(boolean)); functionTaking<float>(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float' // CHECK-FIXES: functionTaking<float>(static_cast<float>(boolean)); functionTaking<double>(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double' // CHECK-FIXES: functionTaking<double>(static_cast<double>(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<float>(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 @@ void implicitCastFromBoolInSingleBoolExpressions(bool b1, bool b2) { 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<int>(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<float>(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<char>(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<int>(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<unsigned long>(! 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<float>(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<double>(boolean && (anotherBoolean || boolean)) * 0.3; } -void implicitCastFromBoolLiterals() { +void implicitConversionFromBoolLiterals() { functionTaking<int>(true); - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit cast bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int' // CHECK-FIXES: functionTaking<int>(1); functionTaking<unsigned long>(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<unsigned long>(0u); functionTaking<signed char>(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<signed char>(1); functionTaking<float>(false); - // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit cast bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion bool -> 'float' // CHECK-FIXES: functionTaking<float>(0.0f); functionTaking<double>(true); - // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit cast bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion bool -> 'double' // CHECK-FIXES: functionTaking<double>(1.0); } -void implicitCastFromBoolInComparisons() { +void implicitConversionFromBoolInComparisons() { bool boolean = true; int integer = 0; functionTaking<bool>(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<bool>(static_cast<int>(boolean) == integer); functionTaking<bool>(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<bool>(integer != static_cast<int>(boolean)); } @@ -142,7 +142,7 @@ void ignoreExplicitCastsFromBool() { char character = static_cast<char>(boolean); } -void ignoreImplicitCastFromBoolInMacroExpansions() { +void ignoreImplicitConversionFromBoolInMacroExpansions() { bool boolean = true; #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3 @@ -152,7 +152,7 @@ void ignoreImplicitCastFromBoolInMacroExpansions() { int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean); } -namespace ignoreImplicitCastFromBoolInTemplateInstantiations { +namespace ignoreImplicitConversionFromBoolInTemplateInstantiations { template<typename T> void templateFunction() { @@ -164,204 +164,204 @@ void useOfTemplateFunction() { templateFunction<int>(); } -} // namespace ignoreImplicitCastFromBoolInTemplateInstantiations +} // namespace ignoreImplicitConversionFromBoolInTemplateInstantiations -////////// Implicit cast to bool. +////////// Implicit conversions to bool. -void implicitCastToBoolSimpleCases() { +void implicitConversionToBoolSimpleCases() { int integer = 10; functionTaking<bool>(integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>(integer != 0); unsigned long unsignedLong = 10; functionTaking<bool>(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<bool>(unsignedLong != 0u); float floating = 0.0f; functionTaking<bool>(floating); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> bool // CHECK-FIXES: functionTaking<bool>(floating != 0.0f); double doubleFloating = 1.0f; functionTaking<bool>(doubleFloating); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> bool // CHECK-FIXES: functionTaking<bool>(doubleFloating != 0.0); signed char character = 'a'; functionTaking<bool>(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<bool>(character != 0); int* pointer = nullptr; functionTaking<bool>(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool // CHECK-FIXES: functionTaking<bool>(pointer != nullptr); auto pointerToMember = &Struct::member; functionTaking<bool>(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<bool>(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<bool>(0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>(false); functionTaking<bool>(1); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>(true); functionTaking<bool>(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<bool>(true); functionTaking<bool>(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<bool>(false); functionTaking<bool>(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<bool>(true); functionTaking<bool>(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<bool>(true); functionTaking<bool>('\0'); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool // CHECK-FIXES: functionTaking<bool>(false); functionTaking<bool>('a'); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'char' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'char' -> bool // CHECK-FIXES: functionTaking<bool>(true); functionTaking<bool>(""); - // 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<bool>(true); functionTaking<bool>("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<bool>(true); functionTaking<bool>(NULL); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> bool // CHECK-FIXES: functionTaking<bool>(false); } -void implicitCastToBoolFromUnaryMinusAndZeroLiterals() { +void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() { functionTaking<bool>(-0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit cast 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool // CHECK-FIXES: functionTaking<bool>((-0) != 0); functionTaking<bool>(-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<bool>((-0.0f) != 0.0f); functionTaking<bool>(-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<bool>((-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 @@ void implicitCastToBoolInWithOverloadedOperators() { UserStruct s; functionTaking<bool>(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<bool>(s(0) != 0); functionTaking<bool>(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<bool>((s + 2) != 0); } int functionReturningInt(); int* functionReturningPointer(); -void ignoreImplicitCastToBoolWhenDeclaringVariableInControlStatements() { +void ignoreImplicitConversionToBoolWhenDeclaringVariableInControlStatements() { if (int integer = functionReturningInt()) {} while (int* pointer = functionReturningPointer()) {} @@ -401,7 +401,7 @@ void ignoreExplicitCastsToBool() { bool booleanComingFromPointer = static_cast<bool>(pointer); } -void ignoreImplicitCastToBoolInMacroExpansions() { +void ignoreImplicitConversionToBoolInMacroExpansions() { int integer = 3; #define CAST_TO_BOOL_IN_MACRO_BODY integer && false @@ -411,7 +411,7 @@ void ignoreImplicitCastToBoolInMacroExpansions() { bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer); } -namespace ignoreImplicitCastToBoolInTemplateInstantiations { +namespace ignoreImplicitConversionToBoolInTemplateInstantiations { template<typename T> void templateFunction() { @@ -423,7 +423,7 @@ void useOfTemplateFunction() { templateFunction<int>(); } -} // namespace ignoreImplicitCastToBoolInTemplateInstantiations +} // namespace ignoreImplicitConversionToBoolInTemplateInstantiations namespace ignoreUserDefinedConversionOperator { |