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 anyOf(hasOperatorName("+"), hasOperatorName("-"), 31 hasOperatorName("+="), hasOperatorName("-=")), 32 AllPointerTypes, 33 unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit())))))) 34 .bind("expr"), 35 this); 36 37 Finder->addMatcher( 38 unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")), 39 hasType(pointerType())) 40 .bind("expr"), 41 this); 42 43 // Array subscript on a pointer (not an array) is also pointer arithmetic 44 Finder->addMatcher( 45 arraySubscriptExpr( 46 hasBase(ignoringImpCasts( 47 anyOf(AllPointerTypes, 48 hasType(decayedType(hasDecayedType(pointerType()))))))) 49 .bind("expr"), 50 this); 51 } 52 53 void ProBoundsPointerArithmeticCheck::check( 54 const MatchFinder::MatchResult &Result) { 55 const auto *MatchedExpr = Result.Nodes.getNodeAs<Expr>("expr"); 56 57 diag(MatchedExpr->getExprLoc(), "do not use pointer arithmetic"); 58 } 59 60 } // namespace cppcoreguidelines 61 } // namespace tidy 62 } // namespace clang 63