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

source code of clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp