1 //=== PointerArithChecker.cpp - Pointer arithmetic checker -----*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This files defines PointerArithChecker, a builtin checker that checks for
11 // pointer arithmetic on locations other than array elements.
13 //===----------------------------------------------------------------------===//
15 #include "ClangSACheckers.h"
16 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
17 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
20 using namespace clang
;
24 class PointerArithChecker
25 : public CheckerVisitor
<PointerArithChecker
> {
28 PointerArithChecker() : BT(0) {}
29 static void *getTag();
30 void PreVisitBinaryOperator(CheckerContext
&C
, const BinaryOperator
*B
);
34 void *PointerArithChecker::getTag() {
39 void PointerArithChecker::PreVisitBinaryOperator(CheckerContext
&C
,
40 const BinaryOperator
*B
) {
41 if (B
->getOpcode() != BO_Sub
&& B
->getOpcode() != BO_Add
)
44 const GRState
*state
= C
.getState();
45 SVal LV
= state
->getSVal(B
->getLHS());
46 SVal RV
= state
->getSVal(B
->getRHS());
48 const MemRegion
*LR
= LV
.getAsRegion();
50 if (!LR
|| !RV
.isConstant())
53 // If pointer arithmetic is done on variables of non-array type, this often
54 // means behavior rely on memory organization, which is dangerous.
55 if (isa
<VarRegion
>(LR
) || isa
<CodeTextRegion
>(LR
) ||
56 isa
<CompoundLiteralRegion
>(LR
)) {
58 if (ExplodedNode
*N
= C
.generateNode()) {
60 BT
= new BuiltinBug("Dangerous pointer arithmetic",
61 "Pointer arithmetic done on non-array variables "
62 "means reliance on memory layout, which is "
64 RangedBugReport
*R
= new RangedBugReport(*BT
, BT
->getDescription(), N
);
65 R
->addRange(B
->getSourceRange());
71 static void RegisterPointerArithChecker(ExprEngine
&Eng
) {
72 Eng
.registerCheck(new PointerArithChecker());
75 void ento::registerPointerArithChecker(CheckerManager
&mgr
) {
76 mgr
.addCheckerRegisterFunction(RegisterPointerArithChecker
);