UndefinedArraySubscriptChecker.cpp revision eb290caacc49587e4d3c992ba742d1916cab5350
1d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//
2d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//
3d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//                     The LLVM Compiler Infrastructure
4d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//
5d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// This file is distributed under the University of Illinois Open Source
6d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// License. See LICENSE.TXT for details.
7d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//
8d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===----------------------------------------------------------------------===//
9d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//
10d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis// This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine
11d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu// that performs checks for undefined array subscripts.
12d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//
13d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu//===----------------------------------------------------------------------===//
14d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu
15eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "ClangSACheckers.h"
16eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerV2.h"
17eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
18eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
20d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu
21d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xuusing namespace clang;
229ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
23d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu
24d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xunamespace {
25ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass UndefinedArraySubscriptChecker
26eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis  : public CheckerV2< check::PreStmt<ArraySubscriptExpr> > {
27eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis  mutable llvm::OwningPtr<BugType> BT;
28eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis
29d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xupublic:
30eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis  void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
31d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu};
32d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu} // end anonymous namespace
33d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu
34d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xuvoid
35eb290caacc49587e4d3c992ba742d1916cab5350Argyrios KyrtzidisUndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
36eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis                                             CheckerContext &C) const {
371397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek  if (C.getState()->getSVal(A->getIdx()).isUndef()) {
38d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek    if (ExplodedNode *N = C.generateSink()) {
39d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu      if (!BT)
40eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis        BT.reset(new BuiltinBug("Array subscript is undefined"));
41d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu
42d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu      // Generate a report for this bug.
43d02e232c43b979758810794de24d3f5cde40fe93Benjamin Kramer      EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
44d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu      R->addRange(A->getIdx()->getSourceRange());
45d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
46d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu                           A->getIdx());
47d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu      C.EmitReport(R);
48d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu    }
49d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu  }
50d694485f9d6e3ea7b458df8241dfffd38f62aca8Zhongxing Xu}
51eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis
52eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidisvoid ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
53eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis  mgr.registerChecker<UndefinedArraySubscriptChecker>();
54eb290caacc49587e4d3c992ba742d1916cab5350Argyrios Kyrtzidis}
55