https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/74891
>From 8c3b797f1f34d18c1e9211898f7d1a5697251317 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Fri, 8 Dec 2023 22:01:23 +0000 Subject: [PATCH] [clang-tidy] Fix missing parentheses in readability-implicit-bool-conversion fixes Check now more properly add missing parentheses to code like this: 'bool bar = true ? 1 : 0 != 0;'. --- .../ImplicitBoolConversionCheck.cpp | 35 +--- .../clang-tidy/utils/FixItHintUtils.cpp | 34 ++++ .../clang-tidy/utils/FixItHintUtils.h | 4 + clang-tools-extra/docs/ReleaseNotes.rst | 2 +- ...it-bool-conversion-allow-in-conditions.cpp | 6 +- .../implicit-bool-conversion-cxx98.cpp | 12 +- .../readability/implicit-bool-conversion.cpp | 154 ++++++++++-------- 7 files changed, 139 insertions(+), 108 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index f0fca30de3b3c4..e011598cc7c9f9 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ImplicitBoolConversionCheck.h" +#include "../utils/FixItHintUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" @@ -61,31 +62,6 @@ bool isUnaryLogicalNotOperator(const Stmt *Statement) { return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot; } -bool areParensNeededForOverloadedOperator(OverloadedOperatorKind OperatorKind) { - switch (OperatorKind) { - case OO_New: - case OO_Delete: // Fall-through on purpose. - case OO_Array_New: - case OO_Array_Delete: - case OO_ArrowStar: - case OO_Arrow: - case OO_Call: - case OO_Subscript: - return false; - - default: - return true; - } -} - -bool areParensNeededForStatement(const Stmt *Statement) { - if (const auto *OperatorCall = dyn_cast<CXXOperatorCallExpr>(Statement)) { - return areParensNeededForOverloadedOperator(OperatorCall->getOperator()); - } - - return isa<BinaryOperator>(Statement) || isa<UnaryOperator>(Statement); -} - void fixGenericExprCastToBool(DiagnosticBuilder &Diag, const ImplicitCastExpr *Cast, const Stmt *Parent, ASTContext &Context) { @@ -105,9 +81,10 @@ void fixGenericExprCastToBool(DiagnosticBuilder &Diag, const Expr *SubExpr = Cast->getSubExpr(); - bool NeedInnerParens = areParensNeededForStatement(SubExpr); + bool NeedInnerParens = + SubExpr != nullptr && utils::fixit::areParensNeededForStatement(*SubExpr); bool NeedOuterParens = - Parent != nullptr && areParensNeededForStatement(Parent); + Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent); std::string StartLocInsertion; @@ -365,7 +342,7 @@ void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast, return; } - auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> bool") + auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> 'bool'") << Cast->getSubExpr()->getType(); StringRef EquivalentLiteral = @@ -382,7 +359,7 @@ void ImplicitBoolConversionCheck::handleCastFromBool( ASTContext &Context) { QualType DestType = NextImplicitCast ? NextImplicitCast->getType() : Cast->getType(); - auto Diag = diag(Cast->getBeginLoc(), "implicit conversion bool -> %0") + auto Diag = diag(Cast->getBeginLoc(), "implicit conversion 'bool' -> %0") << DestType; if (const auto *BoolLiteral = diff --git a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp index 226dd60b5bf5f5..bbdd4326b0bac2 100644 --- a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp @@ -224,6 +224,40 @@ std::optional<FixItHint> addQualifierToVarDecl(const VarDecl &Var, return std::nullopt; } +bool areParensNeededForStatement(const Stmt &Node) { + if (isa<ParenExpr>(&Node)) + return false; + + if (isa<clang::BinaryOperator>(&Node) || isa<UnaryOperator>(&Node)) + return true; + + if (isa<clang::ConditionalOperator>(&Node) || + isa<BinaryConditionalOperator>(&Node)) + return true; + + if (const auto *Op = dyn_cast<CXXOperatorCallExpr>(&Node)) { + switch (Op->getOperator()) { + case OO_PlusPlus: + [[fallthrough]]; + case OO_MinusMinus: + return Op->getNumArgs() != 2; + case OO_Call: + [[fallthrough]]; + case OO_Subscript: + [[fallthrough]]; + case OO_Arrow: + return false; + default: + return true; + }; + } + + if (isa<CStyleCastExpr>(&Node)) + return true; + + return false; +} + // Return true if expr needs to be put in parens when it is an argument of a // prefix unary operator, e.g. when it is a binary or ternary operator // syntactically. diff --git a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h index 15894c4bf5cf8f..d25bea2c6d2973 100644 --- a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h +++ b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.h @@ -47,6 +47,10 @@ addQualifierToVarDecl(const VarDecl &Var, const ASTContext &Context, // \brief Format a pointer to an expression std::string formatDereference(const Expr &ExprNode, const ASTContext &Context); + +// \brief Checks whatever a expression require extra () to be always used in +// safe way in any other expression. +bool areParensNeededForStatement(const Stmt &Node); } // namespace clang::tidy::utils::fixit #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FIXITHINTUTILS_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6d5f49dc062545..15516fffdeebff 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -423,7 +423,7 @@ Changes in existing checks <clang-tidy/checks/readability/implicit-bool-conversion>` check to take do-while loops into account for the `AllowIntegerConditions` and `AllowPointerConditions` options. It also now provides more consistent - suggestions when parentheses are added to the return value. + suggestions when parentheses are added to the return value or expressions. - Improved :doc:`readability-non-const-parameter <clang-tidy/checks/readability/non-const-parameter>` check to ignore diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp index e393e297140cbd..64dd3c1e051c52 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp @@ -18,7 +18,7 @@ struct Struct { void regularImplicitConversionIntegerToBoolIsNotIgnored() { int integer = 0; functionTaking<bool>(integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool [readability-implicit-bool-conversion] + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion] // CHECK-FIXES: functionTaking<bool>(integer != 0); } @@ -51,12 +51,12 @@ void implicitConversionIntegerToBoolInConditionalsIsAllowed() { void regularImplicitConversionPointerToBoolIsNotIgnored() { int* pointer = nullptr; functionTaking<bool>(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion '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 conversion 'int Struct::*' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool' // CHECK-FIXES: functionTaking<bool>(memberPointer != nullptr); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx98.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx98.cpp index 861677ac6c3037..e4c47b06d8f841 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx98.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx98.cpp @@ -15,31 +15,31 @@ struct Struct { void useOldNullMacroInReplacements() { int* pointer = NULL; functionTaking<bool>(pointer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int *' -> bool [readability-implicit-bool-conversion] + // 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 conversion '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 conversion 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 conversion 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 conversion 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 conversion 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/checkers/readability/implicit-bool-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp index f7f5d506a9ce0e..6f1f2972971887 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp @@ -21,30 +21,30 @@ void implicitConversionFromBoolSimpleCases() { functionTaking<bool>(boolean); functionTaking<int>(boolean); - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion bool -> 'int' [readability-implicit-bool-conversion] + // 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 conversion 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 conversion 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 conversion 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 conversion bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double' // CHECK-FIXES: functionTaking<double>(static_cast<double>(boolean)); } float implicitConversionFromBoolInReturnValue() { bool boolean = false; return boolean; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion bool -> 'float' + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'bool' -> 'float' // CHECK-FIXES: return static_cast<float>(boolean); } @@ -58,15 +58,15 @@ void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) { boolean = b2 != false; int integer = boolean - 3; - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 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 conversion 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 conversion bool -> 'char' + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'char' // CHECK-FIXES: char character = static_cast<char>(boolean); } @@ -75,41 +75,41 @@ void implicitConversionFromBoollInComplexBoolExpressions() { bool anotherBoolean = false; int integer = boolean && anotherBoolean; - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 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 conversion 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 conversion 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 conversion 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 implicitConversionFromBoolLiterals() { functionTaking<int>(true); - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 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 conversion 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 conversion 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 conversion 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 conversion bool -> 'double' + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double' // CHECK-FIXES: functionTaking<double>(1.0); } @@ -118,11 +118,11 @@ void implicitConversionFromBoolInComparisons() { int integer = 0; functionTaking<bool>(boolean == integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 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 conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: functionTaking<bool>(integer != static_cast<int>(boolean)); } @@ -171,59 +171,59 @@ void useOfTemplateFunction() { void implicitConversionToBoolSimpleCases() { int integer = 10; functionTaking<bool>(integer); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion 'int Struct::*' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int Struct::*' -> 'bool' // CHECK-FIXES: functionTaking<bool>(pointerToMember != nullptr); } void implicitConversionToBoolInSingleExpressions() { int integer = 10; bool boolComingFromInt = integer; - // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion '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 conversion '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 conversion '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 conversion 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion 'int *' -> 'bool' // CHECK-FIXES: bool boolComingFromPointer = pointer != nullptr; } @@ -233,131 +233,131 @@ void implicitConversionToBoolInComplexExpressions() { int integer = 10; int anotherInteger = 20; bool boolComingFromInteger = integer + anotherInteger; - // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: implicit conversion '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 conversion '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 conversion 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'double' -> 'bool' // CHECK-FIXES: bool boolComingFromDoubleFloating = ((doubleFloating - 0.4) != 0.0) && boolean; } void implicitConversionInNegationExpressions() { int integer = 10; bool boolComingFromNegatedInt = !integer; - // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: implicit conversion '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 conversion '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 conversion '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 conversion 'int *' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: implicit conversion 'int *' -> 'bool' // CHECK-FIXES: bool boolComingFromNegatedPointer = pointer == nullptr; } void implicitConversionToBoolInControlStatements() { int integer = 10; if (integer) {} - // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: implicit conversion '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 conversion '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 conversion '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 conversion 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: implicit conversion 'double' -> 'bool' // CHECK-FIXES: do {} while (doubleFloating != 0.0); } bool implicitConversionToBoolInReturnValue() { float floating = 1.0f; return floating; - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool' // CHECK-FIXES: return floating != 0.0f; } void implicitConversionToBoolFromLiterals() { functionTaking<bool>(0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion '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 conversion 'long' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'long' -> 'bool' // CHECK-FIXES: functionTaking<bool>(false); } void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() { functionTaking<bool>(-0); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion '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 conversion '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 conversion 'double' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool' // CHECK-FIXES: functionTaking<bool>((-0.0) != 0.0); } @@ -370,11 +370,11 @@ void implicitConversionToBoolInWithOverloadedOperators() { UserStruct s; functionTaking<bool>(s(0)); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion '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 conversion 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' // CHECK-FIXES: functionTaking<bool>((s + 2) != 0); } @@ -446,27 +446,27 @@ struct S { int c : 2; S(bool a, bool b, bool c) : a(a), b(b), c(c) {} - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion bool -> 'int' - // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int' + // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: S(bool a, bool b, bool c) : a(static_cast<int>(a)), b(b), c(static_cast<int>(c)) {} }; bool f(S& s) { functionTaking<bool>(s.a); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' // CHECK-FIXES: functionTaking<bool>(s.a != 0); functionTaking<bool>(s.b); // CHECK-FIXES: functionTaking<bool>(s.b); s.a = true; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: s.a = 1; s.b = true; // CHECK-FIXES: s.b = true; s.c = true; - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: s.c = 1; functionTaking<bool>(s.c); - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'int' -> 'bool' // CHECK-FIXES: functionTaking<bool>(s.c != 0); } @@ -475,14 +475,14 @@ bool f(S& s) { int implicitConversionReturnInt() { return true; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: return 1 } int implicitConversionReturnIntWithParens() { return (true); - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion bool -> 'int' + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' // CHECK-FIXES: return 1 } @@ -490,14 +490,14 @@ int implicitConversionReturnIntWithParens() bool implicitConversionReturnBool() { return 1; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' // CHECK-FIXES: return true } bool implicitConversionReturnBoolWithParens() { return (1); - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> bool + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' // CHECK-FIXES: return true } @@ -508,3 +508,19 @@ namespace PR47000 { using IntType = int; int to_int2(bool x) { return IntType{x}; } } + +namespace PR71867 { + bool foo(bool x) { + return x ? 1 : false; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' + // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: return (x ? 1 : 0) != 0; + } + + bool boo(bool x) { + return x ? true : 0; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' + // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: return (x ? 1 : 0) != 0; + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits