UndefinedArraySubscriptChecker.cpp revision 04291a7c76e16a2dc5433c80c3d13c826bf372dc
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 "InternalChecks.h"
16#include "clang/StaticAnalyzer/BugReporter/BugType.h"
17#include "clang/StaticAnalyzer/PathSensitive/CheckerVisitor.h"
18
19using namespace clang;
20using namespace ento;
21
22namespace {
23class UndefinedArraySubscriptChecker
24  : public CheckerVisitor<UndefinedArraySubscriptChecker> {
25  BugType *BT;
26public:
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
37void ento::RegisterUndefinedArraySubscriptChecker(ExprEngine &Eng) {
38  Eng.registerCheck(new UndefinedArraySubscriptChecker());
39}
40
41void
42UndefinedArraySubscriptChecker::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