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