void DeleteNullPointerCheck::registerMatchers(MatchFinder *Finder) { const auto DeleteExpr = cxxDeleteExpr(has(castExpr(has(declRefExpr( to(decl(equalsBoundNode("deletedPointer")))))))) .bind("deleteExpr"); const auto DeleteMemberExpr = cxxDeleteExpr(has(castExpr(has(memberExpr(hasDeclaration( fieldDecl(equalsBoundNode("deletedMemberPointer")))))))) .bind("deleteMemberExpr"); const auto PointerExpr = ignoringImpCasts(anyOf( declRefExpr(to(decl().bind("deletedPointer"))), memberExpr(hasDeclaration(fieldDecl().bind("deletedMemberPointer"))))); const auto PointerCondition = castExpr(hasCastKind(CK_PointerToBoolean), hasSourceExpression(PointerExpr)); const auto BinaryPointerCheckCondition = binaryOperator(hasEitherOperand(castExpr(hasCastKind(CK_NullToPointer))), hasEitherOperand(PointerExpr)); Finder->addMatcher( ifStmt(hasCondition(anyOf(PointerCondition, BinaryPointerCheckCondition)), hasThen(anyOf( DeleteExpr, DeleteMemberExpr, compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)), statementCountIs(1)) .bind("compound")))) .bind("ifWithDelete"), this); }
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { // FIXME: Support continue, break and throw. Finder->addMatcher( ifStmt( hasThen(stmt(anyOf(returnStmt(), compoundStmt(has(returnStmt()))))), hasElse(stmt().bind("else"))).bind("if"), this); }
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { const auto ControlFlowInterruptorMatcher = stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"), breakStmt().bind("break"), cxxThrowExpr().bind("throw"))); Finder->addMatcher( stmt(forEach( ifStmt(hasThen(stmt( anyOf(ControlFlowInterruptorMatcher, compoundStmt(has(ControlFlowInterruptorMatcher))))), hasElse(stmt().bind("else"))) .bind("if"))), this); }