123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- //===--- MisplacedPointerArithmeticInAllocCheck.cpp - clang-tidy-----------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "MisplacedPointerArithmeticInAllocCheck.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/ASTMatchers/ASTMatchFinder.h"
- #include "clang/Lex/Lexer.h"
- using namespace clang::ast_matchers;
- namespace clang::tidy::bugprone {
- void MisplacedPointerArithmeticInAllocCheck::registerMatchers(
- MatchFinder *Finder) {
- const auto AllocFunc =
- functionDecl(hasAnyName("::malloc", "std::malloc", "::alloca", "::calloc",
- "std::calloc", "::realloc", "std::realloc"));
- const auto AllocFuncPtr =
- varDecl(hasType(isConstQualified()),
- hasInitializer(ignoringParenImpCasts(
- declRefExpr(hasDeclaration(AllocFunc)))));
- const auto AdditiveOperator = binaryOperator(hasAnyOperatorName("+", "-"));
- const auto IntExpr = expr(hasType(isInteger()));
- const auto AllocCall = callExpr(callee(decl(anyOf(AllocFunc, AllocFuncPtr))));
- Finder->addMatcher(
- binaryOperator(
- AdditiveOperator,
- hasLHS(anyOf(AllocCall, castExpr(hasSourceExpression(AllocCall)))),
- hasRHS(IntExpr))
- .bind("PtrArith"),
- this);
- const auto New = cxxNewExpr(unless(isArray()));
- Finder->addMatcher(binaryOperator(AdditiveOperator,
- hasLHS(anyOf(New, castExpr(New))),
- hasRHS(IntExpr))
- .bind("PtrArith"),
- this);
- const auto ArrayNew = cxxNewExpr(isArray());
- Finder->addMatcher(binaryOperator(AdditiveOperator,
- hasLHS(anyOf(ArrayNew, castExpr(ArrayNew))),
- hasRHS(IntExpr))
- .bind("PtrArith"),
- this);
- }
- void MisplacedPointerArithmeticInAllocCheck::check(
- const MatchFinder::MatchResult &Result) {
- const auto *PtrArith = Result.Nodes.getNodeAs<BinaryOperator>("PtrArith");
- const Expr *AllocExpr = PtrArith->getLHS()->IgnoreParenCasts();
- std::string CallName;
- if (const auto *Call = dyn_cast<CallExpr>(AllocExpr)) {
- const NamedDecl *Func = Call->getDirectCallee();
- if (!Func) {
- Func = cast<NamedDecl>(Call->getCalleeDecl());
- }
- CallName = Func->getName().str();
- } else {
- const auto *New = cast<CXXNewExpr>(AllocExpr);
- if (New->isArray()) {
- CallName = "operator new[]";
- } else {
- const auto *CtrE = New->getConstructExpr();
- if (!CtrE || !CtrE->getArg(CtrE->getNumArgs() - 1)
- ->getType()
- ->isIntegralOrEnumerationType())
- return;
- CallName = "operator new";
- }
- }
- const SourceRange OldRParen = SourceRange(PtrArith->getLHS()->getEndLoc());
- const StringRef RParen =
- Lexer::getSourceText(CharSourceRange::getTokenRange(OldRParen),
- *Result.SourceManager, getLangOpts());
- const SourceLocation NewRParen = Lexer::getLocForEndOfToken(
- PtrArith->getEndLoc(), 0, *Result.SourceManager, getLangOpts());
- diag(PtrArith->getBeginLoc(),
- "arithmetic operation is applied to the result of %0() instead of its "
- "size-like argument")
- << CallName << FixItHint::CreateRemoval(OldRParen)
- << FixItHint::CreateInsertion(NewRParen, RParen);
- }
- } // namespace clang::tidy::bugprone
|