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> > {
27e2778999SDylan Noblesmith   mutable 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 {
37632e3b7eSTed Kremenek   if (C.getState()->getSVal(A->getIdx(), C.getLocationContext()).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.
433a6bdf8fSAnna Zaks       BugReport *R = new BugReport(*BT, BT->getName(), N);
44d99bd55aSTed Kremenek       R->addRange(A->getIdx()->getSourceRange());
45a0f7d35aSJordan Rose       bugreporter::trackNullOrUndefValue(N, A->getIdx(), *R);
46*e10d5a76SJordan Rose       C.emitReport(R);
47d99bd55aSTed Kremenek     }
48d99bd55aSTed Kremenek   }
49d99bd55aSTed Kremenek }
50da6c7568SArgyrios Kyrtzidis 
51da6c7568SArgyrios Kyrtzidis void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
52da6c7568SArgyrios Kyrtzidis   mgr.registerChecker<UndefinedArraySubscriptChecker>();
53da6c7568SArgyrios Kyrtzidis }
54