20 const auto DeleteExpr =
22 has(declRefExpr(to(decl(equalsBoundNode(
"deletedPointer"))))))
25 const auto DeleteMemberExpr =
26 cxxDeleteExpr(has(memberExpr(hasDeclaration(
27 fieldDecl(equalsBoundNode(
"deletedMemberPointer"))))))
28 .bind(
"deleteMemberExpr");
30 const auto PointerExpr = anyOf(
31 declRefExpr(to(decl().bind(
"deletedPointer"))),
32 memberExpr(hasDeclaration(fieldDecl().bind(
"deletedMemberPointer"))));
34 const auto BinaryPointerCheckCondition = binaryOperator(hasOperands(
35 anyOf(cxxNullPtrLiteralExpr(), integerLiteral(equals(0))), PointerExpr));
38 ifStmt(hasCondition(anyOf(PointerExpr, BinaryPointerCheckCondition)),
40 DeleteExpr, DeleteMemberExpr,
41 compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)),
44 .bind(
"ifWithDelete"),
49 const auto *IfWithDelete = Result.Nodes.getNodeAs<IfStmt>(
"ifWithDelete");
50 const auto *Compound = Result.Nodes.getNodeAs<CompoundStmt>(
"compound");
53 IfWithDelete->getBeginLoc(),
54 "'if' statement is unnecessary; deleting null pointer has no effect");
55 if (IfWithDelete->hasElseStorage())
60 IfWithDelete->getThen()->getBeginLoc(), *Result.SourceManager,
61 Result.Context->getLangOpts());
65 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
66 IfWithDelete->getBeginLoc(), PrevTok->getLocation()));
69 Diag << FixItHint::CreateRemoval(
70 CharSourceRange::getTokenRange(Compound->getLBracLoc()));
71 Diag << FixItHint::CreateRemoval(
72 CharSourceRange::getTokenRange(Compound->getRBracLoc()));
std::optional< Token > getPreviousToken(SourceLocation Location, const SourceManager &SM, const LangOptions &LangOpts, bool SkipComments)
Returns previous token or std::nullopt if not found.