1 //===--- ProBoundsPointerArithmeticCheck.cpp - clang-tidy------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ProBoundsPointerArithmeticCheck.h" 10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 13 using namespace clang::ast_matchers; 14 15 namespace clang { 16 namespace tidy { 17 namespace cppcoreguidelines { 18 19 void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) { 20 if (!getLangOpts().CPlusPlus) 21 return; 22 23 const auto AllPointerTypes = anyOf( 24 hasType(pointerType()), hasType(autoType(hasDeducedType(pointerType()))), 25 hasType(decltypeType(hasUnderlyingType(pointerType())))); 26 27 // Flag all operators +, -, +=, -=, ++, -- that result in a pointer 28 Finder->addMatcher( 29 binaryOperator( 30 hasAnyOperatorName("+", "-", "+=", "-="), AllPointerTypes, 31 unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit())))))) 32 .bind("expr"), 33 this); 34 35 Finder->addMatcher( 36 unaryOperator(hasAnyOperatorName("++", "--"), 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(AllPointerTypes, 45 hasType(decayedType(hasDecayedType(pointerType()))))))) 46 .bind("expr"), 47 this); 48 } 49 50 void ProBoundsPointerArithmeticCheck::check( 51 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