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