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 15da6c7568SArgyrios Kyrtzidis #include "ClangSACheckers.h" 166a5674ffSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/Checker.h" 17da6c7568SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/CheckerManager.h" 18da6c7568SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 19f8cbac4bSTed Kremenek #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20d99bd55aSTed Kremenek 21d99bd55aSTed Kremenek using namespace clang; 22d99bd55aSTed Kremenek using namespace ento; 23d99bd55aSTed Kremenek 24d99bd55aSTed Kremenek namespace { 25d99bd55aSTed Kremenek class UndefinedArraySubscriptChecker 266a5674ffSArgyrios Kyrtzidis : public Checker< check::PreStmt<ArraySubscriptExpr> > { 27da6c7568SArgyrios Kyrtzidis mutable llvm::OwningPtr<BugType> BT; 28da6c7568SArgyrios Kyrtzidis 29d99bd55aSTed Kremenek public: 30da6c7568SArgyrios Kyrtzidis void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const; 31d99bd55aSTed Kremenek }; 32d99bd55aSTed Kremenek } // end anonymous namespace 33d99bd55aSTed Kremenek 34d99bd55aSTed Kremenek void 35da6c7568SArgyrios Kyrtzidis UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A, 36da6c7568SArgyrios Kyrtzidis CheckerContext &C) const { 37d99bd55aSTed Kremenek if (C.getState()->getSVal(A->getIdx()).isUndef()) { 38d99bd55aSTed Kremenek if (ExplodedNode *N = C.generateSink()) { 39d99bd55aSTed Kremenek if (!BT) 40da6c7568SArgyrios Kyrtzidis BT.reset(new BuiltinBug("Array subscript is undefined")); 41d99bd55aSTed Kremenek 42d99bd55aSTed Kremenek // Generate a report for this bug. 43*3a6bdf8fSAnna Zaks BugReport *R = new BugReport(*BT, BT->getName(), N); 44d99bd55aSTed Kremenek R->addRange(A->getIdx()->getSourceRange()); 45d99bd55aSTed Kremenek R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, 46d99bd55aSTed Kremenek A->getIdx()); 47d99bd55aSTed Kremenek C.EmitReport(R); 48d99bd55aSTed Kremenek } 49d99bd55aSTed Kremenek } 50d99bd55aSTed Kremenek } 51da6c7568SArgyrios Kyrtzidis 52da6c7568SArgyrios Kyrtzidis void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) { 53da6c7568SArgyrios Kyrtzidis mgr.registerChecker<UndefinedArraySubscriptChecker>(); 54da6c7568SArgyrios Kyrtzidis } 55