12 using namespace clang::ast_matchers;
18 return Node.getCastKind() == CK_PointerToBoolean;
20 AST_MATCHER(QualType, isBoolean) {
return Node->isBooleanType(); }
27 void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *
Finder) {
31 ifStmt(hasCondition(findAll(implicitCastExpr(
32 allOf(unless(hasParent(unaryOperator(hasOperatorName(
"!")))),
33 hasSourceExpression(expr(
34 hasType(pointerType(pointee(isBoolean()))),
35 ignoringParenImpCasts(declRefExpr().bind(
"expr")))),
36 isPointerToBoolean())))),
37 unless(isInTemplateInstantiation())).bind(
"if"),
41 void BoolPointerImplicitConversionCheck::check(
42 const MatchFinder::MatchResult &
Result) {
43 auto *If = Result.Nodes.getStmtAs<IfStmt>(
"if");
44 auto *Var = Result.Nodes.getStmtAs<DeclRefExpr>(
"expr");
47 if (Var->getLocStart().isMacroID())
55 const Decl *D = Var->getDecl();
56 auto DeclRef = ignoringParenImpCasts(declRefExpr(to(equalsNode(D))));
58 unaryOperator(hasOperatorName(
"*"), hasUnaryOperand(DeclRef))),
59 *If, *Result.Context).empty() ||
60 !match(findAll(arraySubscriptExpr(hasBase(DeclRef))), *If,
61 *Result.Context).empty() ||
64 !match(findAll(callExpr(hasAnyArgument(DeclRef))), *If, *Result.Context)
66 !match(findAll(cxxDeleteExpr(has(expr(DeclRef)))), *If, *Result.Context)
70 diag(Var->getLocStart(),
"dubious check of 'bool *' against 'nullptr', did "
71 "you mean to dereference it?")
72 << FixItHint::CreateInsertion(Var->getLocStart(),
"*");
std::unique_ptr< ast_matchers::MatchFinder > Finder
AST_MATCHER(Stmt, isInsideOfRangeBeginEndStmt)