[analyzer] Pass CheckerManager to the registration functions.
[clang.git] / lib / StaticAnalyzer / Checkers / PointerArithChecker.cpp
blob741e48bfcbe02c8d33c7bc6b2712281e2b7fcf70
1 //=== PointerArithChecker.cpp - Pointer arithmetic checker -----*- C++ -*--===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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;
21 using namespace ento;
23 namespace {
24 class PointerArithChecker
25 : public CheckerVisitor<PointerArithChecker> {
26 BuiltinBug *BT;
27 public:
28 PointerArithChecker() : BT(0) {}
29 static void *getTag();
30 void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
34 void *PointerArithChecker::getTag() {
35 static int x;
36 return &x;
39 void PointerArithChecker::PreVisitBinaryOperator(CheckerContext &C,
40 const BinaryOperator *B) {
41 if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add)
42 return;
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())
51 return;
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()) {
59 if (!BT)
60 BT = new BuiltinBug("Dangerous pointer arithmetic",
61 "Pointer arithmetic done on non-array variables "
62 "means reliance on memory layout, which is "
63 "dangerous.");
64 RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
65 R->addRange(B->getSourceRange());
66 C.EmitReport(R);
71 static void RegisterPointerArithChecker(ExprEngine &Eng) {
72 Eng.registerCheck(new PointerArithChecker());
75 void ento::registerPointerArithChecker(CheckerManager &mgr) {
76 mgr.addCheckerRegisterFunction(RegisterPointerArithChecker);