diff options
-rw-r--r-- | clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp | 48 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp | 5 |
2 files changed, 28 insertions, 25 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp index 129123b3534..a7e4f0ccc54 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp @@ -40,24 +40,6 @@ AST_MATCHER(Stmt, isNULLMacroExpansion) { return isNULLMacroExpansion(&Node, Finder->getASTContext()); } -ast_matchers::internal::Matcher<Expr> createExceptionCasesMatcher() { - return expr(anyOf(hasParent(explicitCastExpr()), - allOf(isMacroExpansion(), unless(isNULLMacroExpansion())), - isInTemplateInstantiation(), - hasAncestor(functionTemplateDecl()))); -} - -StatementMatcher createImplicitCastFromBoolMatcher() { - return implicitCastExpr( - unless(createExceptionCasesMatcher()), - anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating), - // Prior to C++11 cast from bool literal to pointer was allowed. - allOf(anyOf(hasCastKind(CK_NullToPointer), - hasCastKind(CK_NullToMemberPointer)), - hasSourceExpression(cxxBoolLiteral()))), - hasSourceExpression(expr(hasType(qualType(booleanType()))))); -} - StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind, QualType Type, ASTContext &Context) { @@ -284,10 +266,15 @@ void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) { return; } + auto exceptionCases = expr( + anyOf(hasParent(explicitCastExpr()), + allOf(isMacroExpansion(), unless(isNULLMacroExpansion())), + isInTemplateInstantiation(), hasAncestor(functionTemplateDecl()))); + Finder->addMatcher( implicitCastExpr( // Exclude cases common to implicit cast to and from bool. - unless(createExceptionCasesMatcher()), + unless(exceptionCases), // Exclude case of using if or while statements with variable // declaration, e.g.: // if (int var = functionCall()) {} @@ -303,17 +290,30 @@ void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) { .bind("implicitCastToBool"), this); + auto implicitCastFromBool = implicitCastExpr( + unless(exceptionCases), + anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating), + // Prior to C++11 cast from bool literal to pointer was allowed. + allOf(anyOf(hasCastKind(CK_NullToPointer), + hasCastKind(CK_NullToMemberPointer)), + hasSourceExpression(cxxBoolLiteral()))), + hasSourceExpression(expr(hasType(booleanType())))); + + auto boolComparison = binaryOperator( + anyOf(hasOperatorName("=="), hasOperatorName("!=")), + hasLHS(implicitCastFromBool), hasRHS(implicitCastFromBool)); + auto boolOpAssignment = binaryOperator( + anyOf(hasOperatorName("|="), hasOperatorName("&=")), + hasLHS(expr(hasType(booleanType()))), hasRHS(implicitCastFromBool)); Finder->addMatcher( implicitCastExpr( - createImplicitCastFromBoolMatcher(), + implicitCastFromBool, // Exclude comparisons of bools, as they are always cast to integers // in such context: // bool_expr_a == bool_expr_b // bool_expr_a != bool_expr_b - unless(hasParent(binaryOperator( - anyOf(hasOperatorName("=="), hasOperatorName("!=")), - hasLHS(createImplicitCastFromBoolMatcher()), - hasRHS(createImplicitCastFromBoolMatcher())))), + unless(hasParent( + binaryOperator(anyOf(boolComparison, boolOpAssignment)))), // Check also for nested casts, for example: bool -> int -> float. anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")), anything())) diff --git a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp b/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp index 45bf64ccf99..16b95fcbe2c 100644 --- a/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp +++ b/clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast.cpp @@ -48,8 +48,11 @@ float implicitCastFromBoolInReturnValue() { // CHECK-FIXES: return static_cast<float>(boolean); } -void implicitCastFromBoolInSingleBoolExpressions() { +void implicitCastFromBoolInSingleBoolExpressions(bool b1, bool b2) { bool boolean = true; + boolean = b1 && b2; + boolean |= !b1 || !b2; + boolean &= b1; int integer = boolean - 3; // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int' |