diff options
author | Alex Cameron <ascottcameron@gmail.com> | 2020-08-05 07:14:28 -0400 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2020-08-05 07:14:28 -0400 |
commit | a44161692ae879068d4086a7e568a348800ba01d (patch) | |
tree | 682a7ae0b17c0fff33b614dc5ee2e80738461a6a /clang-tools-extra/clang-tidy/bugprone | |
parent | GISelWorkList.h - remove unnecessary includes. NFCI. (diff) | |
download | llvm-project-a44161692ae879068d4086a7e568a348800ba01d.tar.gz llvm-project-a44161692ae879068d4086a7e568a348800ba01d.tar.bz2 llvm-project-a44161692ae879068d4086a7e568a348800ba01d.zip |
Support member expressions in bugprone-bool-pointer-implicit-conversion.
This addresses PR45189.
Diffstat (limited to 'clang-tools-extra/clang-tidy/bugprone')
-rw-r--r-- | clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp index b764bdbf7c4c..17dab1b0f73e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp @@ -20,53 +20,68 @@ void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( traverse( ast_type_traits::TK_AsIs, - ifStmt(hasCondition(findAll(implicitCastExpr( - unless(hasParent(unaryOperator(hasOperatorName("!")))), - hasSourceExpression(expr( - hasType(pointerType(pointee(booleanType()))), - ignoringParenImpCasts(declRefExpr().bind("expr")))), - hasCastKind(CK_PointerToBoolean)))), - unless(isInTemplateInstantiation())) + ifStmt( + hasCondition(findAll(implicitCastExpr( + unless(hasParent(unaryOperator(hasOperatorName("!")))), + hasSourceExpression(expr( + hasType(pointerType(pointee(booleanType()))), + ignoringParenImpCasts(anyOf(declRefExpr().bind("expr"), + memberExpr().bind("expr"))))), + hasCastKind(CK_PointerToBoolean)))), + unless(isInTemplateInstantiation())) .bind("if")), this); } -void BoolPointerImplicitConversionCheck::check( - const MatchFinder::MatchResult &Result) { - auto *If = Result.Nodes.getNodeAs<IfStmt>("if"); - auto *Var = Result.Nodes.getNodeAs<DeclRefExpr>("expr"); - +static void checkImpl(const MatchFinder::MatchResult &Result, const Expr *Ref, + const IfStmt *If, + const ast_matchers::internal::Matcher<Expr> &RefMatcher, + ClangTidyCheck &Check) { // Ignore macros. - if (Var->getBeginLoc().isMacroID()) + if (Ref->getBeginLoc().isMacroID()) return; - // Only allow variable accesses for now, no function calls or member exprs. + // Only allow variable accesses and member exprs for now, no function calls. // Check that we don't dereference the variable anywhere within the if. This // avoids false positives for checks of the pointer for nullptr before it is // dereferenced. If there is a dereferencing operator on this variable don't // emit a diagnostic. Also ignore array subscripts. - const Decl *D = Var->getDecl(); - auto DeclRef = ignoringParenImpCasts(declRefExpr(to(equalsNode(D)))); - if (!match(findAll( - unaryOperator(hasOperatorName("*"), hasUnaryOperand(DeclRef))), + if (!match(findAll(unaryOperator(hasOperatorName("*"), + hasUnaryOperand(RefMatcher))), *If, *Result.Context) .empty() || - !match(findAll(arraySubscriptExpr(hasBase(DeclRef))), *If, + !match(findAll(arraySubscriptExpr(hasBase(RefMatcher))), *If, *Result.Context) .empty() || // FIXME: We should still warn if the paremater is implicitly converted to // bool. - !match(findAll(callExpr(hasAnyArgument(ignoringParenImpCasts(DeclRef)))), - *If, *Result.Context) + !match( + findAll(callExpr(hasAnyArgument(ignoringParenImpCasts(RefMatcher)))), + *If, *Result.Context) .empty() || - !match(findAll(cxxDeleteExpr(has(ignoringParenImpCasts(expr(DeclRef))))), - *If, *Result.Context) + !match( + findAll(cxxDeleteExpr(has(ignoringParenImpCasts(expr(RefMatcher))))), + *If, *Result.Context) .empty()) return; - diag(Var->getBeginLoc(), "dubious check of 'bool *' against 'nullptr', did " - "you mean to dereference it?") - << FixItHint::CreateInsertion(Var->getBeginLoc(), "*"); + Check.diag(Ref->getBeginLoc(), + "dubious check of 'bool *' against 'nullptr', did " + "you mean to dereference it?") + << FixItHint::CreateInsertion(Ref->getBeginLoc(), "*"); +} + +void BoolPointerImplicitConversionCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *If = Result.Nodes.getNodeAs<IfStmt>("if"); + if (const auto *E = Result.Nodes.getNodeAs<Expr>("expr")) { + const Decl *D = isa<DeclRefExpr>(E) ? cast<DeclRefExpr>(E)->getDecl() + : cast<MemberExpr>(E)->getMemberDecl(); + const auto M = + ignoringParenImpCasts(anyOf(declRefExpr(to(equalsNode(D))), + memberExpr(hasDeclaration(equalsNode(D))))); + checkImpl(Result, E, If, M, *this); + } } } // namespace bugprone |