1*d99bd55aSTed Kremenek //===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===// 2*d99bd55aSTed Kremenek // 3*d99bd55aSTed Kremenek // The LLVM Compiler Infrastructure 4*d99bd55aSTed Kremenek // 5*d99bd55aSTed Kremenek // This file is distributed under the University of Illinois Open Source 6*d99bd55aSTed Kremenek // License. See LICENSE.TXT for details. 7*d99bd55aSTed Kremenek // 8*d99bd55aSTed Kremenek //===----------------------------------------------------------------------===// 9*d99bd55aSTed Kremenek // 10*d99bd55aSTed Kremenek // This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine 11*d99bd55aSTed Kremenek // that performs checks for undefined array subscripts. 12*d99bd55aSTed Kremenek // 13*d99bd55aSTed Kremenek //===----------------------------------------------------------------------===// 14*d99bd55aSTed Kremenek 15*d99bd55aSTed Kremenek #include "ExprEngineInternalChecks.h" 16*d99bd55aSTed Kremenek #include "clang/StaticAnalyzer/BugReporter/BugType.h" 17*d99bd55aSTed Kremenek #include "clang/StaticAnalyzer/PathSensitive/CheckerVisitor.h" 18*d99bd55aSTed Kremenek 19*d99bd55aSTed Kremenek using namespace clang; 20*d99bd55aSTed Kremenek using namespace ento; 21*d99bd55aSTed Kremenek 22*d99bd55aSTed Kremenek namespace { 23*d99bd55aSTed Kremenek class UndefinedArraySubscriptChecker 24*d99bd55aSTed Kremenek : public CheckerVisitor<UndefinedArraySubscriptChecker> { 25*d99bd55aSTed Kremenek BugType *BT; 26*d99bd55aSTed Kremenek public: 27*d99bd55aSTed Kremenek UndefinedArraySubscriptChecker() : BT(0) {} 28*d99bd55aSTed Kremenek static void *getTag() { 29*d99bd55aSTed Kremenek static int x = 0; 30*d99bd55aSTed Kremenek return &x; 31*d99bd55aSTed Kremenek } 32*d99bd55aSTed Kremenek void PreVisitArraySubscriptExpr(CheckerContext &C, 33*d99bd55aSTed Kremenek const ArraySubscriptExpr *A); 34*d99bd55aSTed Kremenek }; 35*d99bd55aSTed Kremenek } // end anonymous namespace 36*d99bd55aSTed Kremenek 37*d99bd55aSTed Kremenek void ento::RegisterUndefinedArraySubscriptChecker(ExprEngine &Eng) { 38*d99bd55aSTed Kremenek Eng.registerCheck(new UndefinedArraySubscriptChecker()); 39*d99bd55aSTed Kremenek } 40*d99bd55aSTed Kremenek 41*d99bd55aSTed Kremenek void 42*d99bd55aSTed Kremenek UndefinedArraySubscriptChecker::PreVisitArraySubscriptExpr(CheckerContext &C, 43*d99bd55aSTed Kremenek const ArraySubscriptExpr *A) { 44*d99bd55aSTed Kremenek if (C.getState()->getSVal(A->getIdx()).isUndef()) { 45*d99bd55aSTed Kremenek if (ExplodedNode *N = C.generateSink()) { 46*d99bd55aSTed Kremenek if (!BT) 47*d99bd55aSTed Kremenek BT = new BuiltinBug("Array subscript is undefined"); 48*d99bd55aSTed Kremenek 49*d99bd55aSTed Kremenek // Generate a report for this bug. 50*d99bd55aSTed Kremenek EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N); 51*d99bd55aSTed Kremenek R->addRange(A->getIdx()->getSourceRange()); 52*d99bd55aSTed Kremenek R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 53*d99bd55aSTed Kremenek A->getIdx()); 54*d99bd55aSTed Kremenek C.EmitReport(R); 55*d99bd55aSTed Kremenek } 56*d99bd55aSTed Kremenek } 57*d99bd55aSTed Kremenek } 58