clang  3.7.0
PointerArithChecker.cpp
Go to the documentation of this file.
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.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ClangSACheckers.h"
20 
21 using namespace clang;
22 using namespace ento;
23 
24 namespace {
25 class PointerArithChecker
26  : public Checker< check::PreStmt<BinaryOperator> > {
27  mutable std::unique_ptr<BuiltinBug> BT;
28 
29 public:
30  void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
31 };
32 }
33 
34 void PointerArithChecker::checkPreStmt(const BinaryOperator *B,
35  CheckerContext &C) const {
36  if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add)
37  return;
38 
39  ProgramStateRef state = C.getState();
40  const LocationContext *LCtx = C.getLocationContext();
41  SVal LV = state->getSVal(B->getLHS(), LCtx);
42  SVal RV = state->getSVal(B->getRHS(), LCtx);
43 
44  const MemRegion *LR = LV.getAsRegion();
45 
46  if (!LR || !RV.isConstant())
47  return;
48 
49  // If pointer arithmetic is done on variables of non-array type, this often
50  // means behavior rely on memory organization, which is dangerous.
51  if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) ||
52  isa<CompoundLiteralRegion>(LR)) {
53 
54  if (ExplodedNode *N = C.addTransition()) {
55  if (!BT)
56  BT.reset(
57  new BuiltinBug(this, "Dangerous pointer arithmetic",
58  "Pointer arithmetic done on non-array variables "
59  "means reliance on memory layout, which is "
60  "dangerous."));
61  auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N);
62  R->addRange(B->getSourceRange());
63  C.emitReport(std::move(R));
64  }
65  }
66 }
67 
68 void ento::registerPointerArithChecker(CheckerManager &mgr) {
69  mgr.registerChecker<PointerArithChecker>();
70 }
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:77
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph). Uses the default CheckerContex...
Expr * getLHS() const
Definition: Expr.h:2964
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2918
bool isConstant() const
Definition: SVals.cpp:174
const ProgramStateRef & getState() const
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
const MemRegion * getAsRegion() const
Definition: SVals.cpp:135
Opcode getOpcode() const
Definition: Expr.h:2961
Expr * getRHS() const
Definition: Expr.h:2966
const LocationContext * getLocationContext() const