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