UndefinedArraySubscriptChecker.cpp revision 221345
12116Sjkh//===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//
22116Sjkh//
32116Sjkh//                     The LLVM Compiler Infrastructure
42116Sjkh//
52116Sjkh// This file is distributed under the University of Illinois Open Source
62116Sjkh// License. See LICENSE.TXT for details.
72116Sjkh//
88870Srgrimes//===----------------------------------------------------------------------===//
92116Sjkh//
102116Sjkh// This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine
112116Sjkh// that performs checks for undefined array subscripts.
122116Sjkh//
13176451Sdas//===----------------------------------------------------------------------===//
14176451Sdas
152116Sjkh#include "ClangSACheckers.h"
162116Sjkh#include "clang/StaticAnalyzer/Core/Checker.h"
172116Sjkh#include "clang/StaticAnalyzer/Core/CheckerManager.h"
182116Sjkh#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
192116Sjkh#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
202116Sjkh
212116Sjkhusing namespace clang;
222116Sjkhusing namespace ento;
23143216Sdas
24143216Sdasnamespace {
252116Sjkhclass UndefinedArraySubscriptChecker
262116Sjkh  : public Checker< check::PreStmt<ArraySubscriptExpr> > {
272116Sjkh  mutable llvm::OwningPtr<BugType> BT;
2897413Salfred
2997413Salfredpublic:
302116Sjkh  void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
31143216Sdas};
322116Sjkh} // end anonymous namespace
332116Sjkh
342116Sjkhvoid
352116SjkhUndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
362116Sjkh                                             CheckerContext &C) const {
372116Sjkh  if (C.getState()->getSVal(A->getIdx()).isUndef()) {
382116Sjkh    if (ExplodedNode *N = C.generateSink()) {
392116Sjkh      if (!BT)
408870Srgrimes        BT.reset(new BuiltinBug("Array subscript is undefined"));
418870Srgrimes
428870Srgrimes      // Generate a report for this bug.
43140685Sdas      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
442116Sjkh      R->addRange(A->getIdx()->getSourceRange());
452116Sjkh      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
46143216Sdas                           A->getIdx());
47143216Sdas      C.EmitReport(R);
488870Srgrimes    }
492116Sjkh  }
502116Sjkh}
512116Sjkh
522116Sjkhvoid ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
532116Sjkh  mgr.registerChecker<UndefinedArraySubscriptChecker>();
542116Sjkh}
552116Sjkh