PointerArithChecker.cpp revision 695fb502825a53ccd178ec1c85c77929d88acb71
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" 16#include "clang/StaticAnalyzer/Core/CheckerManager.h" 17#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 18#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h" 19 20using namespace clang; 21using namespace ento; 22 23namespace { 24class PointerArithChecker 25 : public CheckerVisitor<PointerArithChecker> { 26 BuiltinBug *BT; 27public: 28 PointerArithChecker() : BT(0) {} 29 static void *getTag(); 30 void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B); 31}; 32} 33 34void *PointerArithChecker::getTag() { 35 static int x; 36 return &x; 37} 38 39void PointerArithChecker::PreVisitBinaryOperator(CheckerContext &C, 40 const BinaryOperator *B) { 41 if (B->getOpcode() != BO_Sub && B->getOpcode() != BO_Add) 42 return; 43 44 const GRState *state = C.getState(); 45 SVal LV = state->getSVal(B->getLHS()); 46 SVal RV = state->getSVal(B->getRHS()); 47 48 const MemRegion *LR = LV.getAsRegion(); 49 50 if (!LR || !RV.isConstant()) 51 return; 52 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)) { 57 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); 67 } 68 } 69} 70 71static void RegisterPointerArithChecker(ExprEngine &Eng) { 72 Eng.registerCheck(new PointerArithChecker()); 73} 74 75void ento::registerPointerArithChecker(CheckerManager &mgr) { 76 mgr.addCheckerRegisterFunction(RegisterPointerArithChecker); 77} 78