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