73 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 "ProBoundsPointerArithmeticCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::cppcoreguidelines {16 17ProBoundsPointerArithmeticCheck::ProBoundsPointerArithmeticCheck(18 StringRef Name, ClangTidyContext *Context)19 : ClangTidyCheck(Name, Context),20 AllowIncrementDecrementOperators(21 Options.get("AllowIncrementDecrementOperators", false)) {}22 23void ProBoundsPointerArithmeticCheck::storeOptions(24 ClangTidyOptions::OptionMap &Opts) {25 Options.store(Opts, "AllowIncrementDecrementOperators",26 AllowIncrementDecrementOperators);27}28 29void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {30 const auto AllPointerTypes =31 anyOf(hasType(hasUnqualifiedDesugaredType(pointerType())),32 hasType(autoType(33 hasDeducedType(hasUnqualifiedDesugaredType(pointerType())))),34 hasType(decltypeType(hasUnderlyingType(pointerType()))));35 36 // Flag all operators +, -, +=, -= that result in a pointer37 Finder->addMatcher(38 binaryOperator(39 hasAnyOperatorName("+", "-", "+=", "-="), AllPointerTypes,40 unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))))))41 .bind("expr"),42 this);43 44 // Flag all operators ++, -- that result in a pointer45 if (!AllowIncrementDecrementOperators)46 Finder->addMatcher(47 unaryOperator(hasAnyOperatorName("++", "--"),48 hasType(hasUnqualifiedDesugaredType(pointerType())),49 unless(hasUnaryOperand(50 ignoringImpCasts(declRefExpr(to(isImplicit()))))))51 .bind("expr"),52 this);53 54 // Array subscript on a pointer (not an array) is also pointer arithmetic55 Finder->addMatcher(56 arraySubscriptExpr(57 hasBase(ignoringImpCasts(58 anyOf(AllPointerTypes,59 hasType(decayedType(hasDecayedType(pointerType())))))),60 hasIndex(hasType(isInteger())))61 .bind("expr"),62 this);63}64 65void ProBoundsPointerArithmeticCheck::check(66 const MatchFinder::MatchResult &Result) {67 const auto *MatchedExpr = Result.Nodes.getNodeAs<Expr>("expr");68 69 diag(MatchedExpr->getExprLoc(), "do not use pointer arithmetic");70}71 72} // namespace clang::tidy::cppcoreguidelines73