aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Cameron <ascottcameron@gmail.com>2020-08-05 07:14:28 -0400
committerAaron Ballman <aaron@aaronballman.com>2020-08-05 07:14:28 -0400
commita44161692ae879068d4086a7e568a348800ba01d (patch)
tree682a7ae0b17c0fff33b614dc5ee2e80738461a6a /clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
parentGISelWorkList.h - remove unnecessary includes. NFCI. (diff)
downloadllvm-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/BoolPointerImplicitConversionCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp67
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