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 UniqueptrDeleteReleaseCheck::registerMatchers(MatchFinder *Finder) { auto IsSusbstituted = qualType(anyOf( substTemplateTypeParmType(), hasDescendant(substTemplateTypeParmType()))); auto UniquePtrWithDefaultDelete = classTemplateSpecializationDecl( hasName("std::unique_ptr"), hasTemplateArgument(1, refersToType(qualType(hasDeclaration(cxxRecordDecl( hasName("std::default_delete"))))))); Finder->addMatcher( cxxDeleteExpr(has(ignoringParenImpCasts(cxxMemberCallExpr( on(expr(hasType(UniquePtrWithDefaultDelete), unless(hasType(IsSusbstituted))) .bind("uptr")), callee(cxxMethodDecl(hasName("release"))))))) .bind("delete"), this); }