diff options
-rw-r--r-- | clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp | 34 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/readability-implicit-bool-cast-allow-conditional-casts.cpp | 5 |
2 files changed, 26 insertions, 13 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp index 3322cbf1fa2..7f0770f6e69 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolCastCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" +#include <queue> using namespace clang::ast_matchers; @@ -281,20 +282,29 @@ void addFixItHintsForLiteralCastFromBool(DiagnosticBuilder &Diagnostic, Context))); } -StatementMatcher createConditionalExpressionMatcher() { - return stmt(anyOf(ifStmt(), conditionalOperator(), - parenExpr(hasParent(conditionalOperator())))); -} - bool isAllowedConditionalCast(const ImplicitCastExpr *CastExpression, ASTContext &Context) { - auto AllowedConditionalMatcher = stmt(hasParent(stmt( - anyOf(createConditionalExpressionMatcher(), - unaryOperator(hasOperatorName("!"), - hasParent(createConditionalExpressionMatcher())))))); - - auto MatchResult = match(AllowedConditionalMatcher, *CastExpression, Context); - return !MatchResult.empty(); + std::queue<const Stmt *> Q; + Q.push(CastExpression); + while (!Q.empty()) { + for (const auto &N : Context.getParents(*Q.front())) { + const Stmt *S = N.get<Stmt>(); + if (!S) + return false; + if (isa<IfStmt>(S) || isa<ConditionalOperator>(S)) + return true; + if (isa<ParenExpr>(S) || isa<ImplicitCastExpr>(S) || + (isa<UnaryOperator>(S) && + cast<UnaryOperator>(S)->getOpcode() == UO_LNot) || + (isa<BinaryOperator>(S) && cast<BinaryOperator>(S)->isLogicalOp())) { + Q.push(S); + } else { + return false; + } + } + Q.pop(); + } + return false; } } // anonymous namespace 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-cast-allow-conditional-casts.cpp index 6ce59311a5e..3f7b1136336 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-cast-allow-conditional-casts.cpp @@ -25,8 +25,11 @@ void regularImplicitCastIntegerToBoolIsNotIgnored() { void implicitCastIntegerToBoolInConditionalsIsAllowed() { if (functionReturningInt()) {} if (!functionReturningInt()) {} + if (functionReturningInt() && functionReturningPointer()) {} + if (!functionReturningInt() && !functionReturningPointer()) {} int value1 = functionReturningInt() ? 1 : 2; - int value2 = ! functionReturningInt() ? 1 : 2; + int value2 = !functionReturningInt() ? 1 : 2; + int value3 = (functionReturningInt() && functionReturningPointer() || !functionReturningInt()) ? 1 : 2; } void regularImplicitCastPointerToBoolIsNotIgnored() { |