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