brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · f5acafb Raw
101 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 "MisplacedPointerArithmeticInAllocCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/Lex/Lexer.h"13 14using namespace clang::ast_matchers;15 16namespace clang::tidy::bugprone {17 18void MisplacedPointerArithmeticInAllocCheck::registerMatchers(19    MatchFinder *Finder) {20  const auto AllocFunc =21      functionDecl(hasAnyName("::malloc", "std::malloc", "::alloca", "::calloc",22                              "std::calloc", "::realloc", "std::realloc"));23 24  const auto AllocFuncPtr =25      varDecl(hasType(isConstQualified()),26              hasInitializer(ignoringParenImpCasts(27                  declRefExpr(hasDeclaration(AllocFunc)))));28 29  const auto AdditiveOperator = binaryOperator(hasAnyOperatorName("+", "-"));30 31  const auto IntExpr = expr(hasType(isInteger()));32 33  const auto AllocCall = callExpr(callee(decl(anyOf(AllocFunc, AllocFuncPtr))));34 35  Finder->addMatcher(36      binaryOperator(37          AdditiveOperator,38          hasLHS(anyOf(AllocCall, castExpr(hasSourceExpression(AllocCall)))),39          hasRHS(IntExpr))40          .bind("PtrArith"),41      this);42 43  const auto New = cxxNewExpr(unless(isArray()));44 45  Finder->addMatcher(binaryOperator(AdditiveOperator,46                                    hasLHS(anyOf(New, castExpr(New))),47                                    hasRHS(IntExpr))48                         .bind("PtrArith"),49                     this);50 51  const auto ArrayNew = cxxNewExpr(isArray());52 53  Finder->addMatcher(binaryOperator(AdditiveOperator,54                                    hasLHS(anyOf(ArrayNew, castExpr(ArrayNew))),55                                    hasRHS(IntExpr))56                         .bind("PtrArith"),57                     this);58}59 60void MisplacedPointerArithmeticInAllocCheck::check(61    const MatchFinder::MatchResult &Result) {62  const auto *PtrArith = Result.Nodes.getNodeAs<BinaryOperator>("PtrArith");63  const Expr *AllocExpr = PtrArith->getLHS()->IgnoreParenCasts();64  std::string CallName;65 66  if (const auto *Call = dyn_cast<CallExpr>(AllocExpr)) {67    const NamedDecl *Func = Call->getDirectCallee();68    if (!Func) {69      Func = cast<NamedDecl>(Call->getCalleeDecl());70    }71    CallName = Func->getName().str();72  } else {73    const auto *New = cast<CXXNewExpr>(AllocExpr);74    if (New->isArray()) {75      CallName = "operator new[]";76    } else {77      const auto *CtrE = New->getConstructExpr();78      if (!CtrE || !CtrE->getArg(CtrE->getNumArgs() - 1)79                        ->getType()80                        ->isIntegralOrEnumerationType())81        return;82      CallName = "operator new";83    }84  }85 86  const SourceRange OldRParen = SourceRange(PtrArith->getLHS()->getEndLoc());87  const StringRef RParen =88      Lexer::getSourceText(CharSourceRange::getTokenRange(OldRParen),89                           *Result.SourceManager, getLangOpts());90  const SourceLocation NewRParen = Lexer::getLocForEndOfToken(91      PtrArith->getEndLoc(), 0, *Result.SourceManager, getLangOpts());92 93  diag(PtrArith->getBeginLoc(),94       "arithmetic operation is applied to the result of %0() instead of its "95       "size-like argument")96      << CallName << FixItHint::CreateRemoval(OldRParen)97      << FixItHint::CreateInsertion(NewRParen, RParen);98}99 100} // namespace clang::tidy::bugprone101