1 //===--- ProBoundsPointerArithmeticCheck.cpp - clang-tidy------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "ProBoundsPointerArithmeticCheck.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 14 using namespace clang::ast_matchers; 15 16 namespace clang { 17 namespace tidy { 18 namespace cppcoreguidelines { 19 20 void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) { 21 if (!getLangOpts().CPlusPlus) 22 return; 23 24 // Flag all operators +, -, +=, -=, ++, -- that result in a pointer 25 Finder->addMatcher( 26 binaryOperator( 27 anyOf(hasOperatorName("+"), hasOperatorName("-"), 28 hasOperatorName("+="), hasOperatorName("-=")), 29 hasType(pointerType()), 30 unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit())))))) 31 .bind("expr"), 32 this); 33 34 Finder->addMatcher( 35 unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")), 36 hasType(pointerType())) 37 .bind("expr"), 38 this); 39 40 // Array subscript on a pointer (not an array) is also pointer arithmetic 41 Finder->addMatcher( 42 arraySubscriptExpr( 43 hasBase(ignoringImpCasts( 44 anyOf(hasType(pointerType()), 45 hasType(decayedType(hasDecayedType(pointerType()))))))) 46 .bind("expr"), 47 this); 48 } 49 50 void 51 ProBoundsPointerArithmeticCheck::check(const MatchFinder::MatchResult &Result) { 52 const auto *MatchedExpr = Result.Nodes.getNodeAs<Expr>("expr"); 53 54 diag(MatchedExpr->getExprLoc(), "do not use pointer arithmetic"); 55 } 56 57 } // namespace cppcoreguidelines 58 } // namespace tidy 59 } // namespace clang 60