brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · e96bfe7 Raw
75 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DeleteNullPointerCheck.h"10#include "../utils/LexerUtils.h"11#include "clang/AST/ASTContext.h"12#include "clang/ASTMatchers/ASTMatchFinder.h"13#include "clang/Lex/Lexer.h"14 15using namespace clang::ast_matchers;16 17namespace clang::tidy::readability {18 19void DeleteNullPointerCheck::registerMatchers(MatchFinder *Finder) {20  const auto DeleteExpr =21      cxxDeleteExpr(22          has(declRefExpr(to(decl(equalsBoundNode("deletedPointer"))))))23          .bind("deleteExpr");24 25  const auto DeleteMemberExpr =26      cxxDeleteExpr(has(memberExpr(hasDeclaration(27                        fieldDecl(equalsBoundNode("deletedMemberPointer"))))))28          .bind("deleteMemberExpr");29 30  const auto PointerExpr = anyOf(31      declRefExpr(to(decl().bind("deletedPointer"))),32      memberExpr(hasDeclaration(fieldDecl().bind("deletedMemberPointer"))));33 34  const auto BinaryPointerCheckCondition = binaryOperator(hasOperands(35      anyOf(cxxNullPtrLiteralExpr(), integerLiteral(equals(0))), PointerExpr));36 37  Finder->addMatcher(38      ifStmt(hasCondition(anyOf(PointerExpr, BinaryPointerCheckCondition)),39             hasThen(anyOf(40                 DeleteExpr, DeleteMemberExpr,41                 compoundStmt(anyOf(has(DeleteExpr), has(DeleteMemberExpr)),42                              statementCountIs(1))43                     .bind("compound"))))44          .bind("ifWithDelete"),45      this);46}47 48void DeleteNullPointerCheck::check(const MatchFinder::MatchResult &Result) {49  const auto *IfWithDelete = Result.Nodes.getNodeAs<IfStmt>("ifWithDelete");50  const auto *Compound = Result.Nodes.getNodeAs<CompoundStmt>("compound");51 52  auto Diag = diag(53      IfWithDelete->getBeginLoc(),54      "'if' statement is unnecessary; deleting null pointer has no effect");55  if (IfWithDelete->getElse())56    return;57  // FIXME: generate fixit for this case.58 59  Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(60      IfWithDelete->getBeginLoc(),61      utils::lexer::getPreviousToken(IfWithDelete->getThen()->getBeginLoc(),62                                     *Result.SourceManager,63                                     Result.Context->getLangOpts())64          .getLocation()));65 66  if (Compound) {67    Diag << FixItHint::CreateRemoval(68        CharSourceRange::getTokenRange(Compound->getLBracLoc()));69    Diag << FixItHint::CreateRemoval(70        CharSourceRange::getTokenRange(Compound->getRBracLoc()));71  }72}73 74} // namespace clang::tidy::readability75