clang  3.7.0
UndefinedArraySubscriptChecker.cpp
Go to the documentation of this file.
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 "ClangSACheckers.h"
16 #include "clang/AST/DeclCXX.h"
21 
22 using namespace clang;
23 using namespace ento;
24 
25 namespace {
26 class UndefinedArraySubscriptChecker
27  : public Checker< check::PreStmt<ArraySubscriptExpr> > {
28  mutable std::unique_ptr<BugType> BT;
29 
30 public:
31  void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
32 };
33 } // end anonymous namespace
34 
35 void
36 UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
37  CheckerContext &C) const {
38  const Expr *Index = A->getIdx();
39  if (!C.getSVal(Index).isUndef())
40  return;
41 
42  // Sema generates anonymous array variables for copying array struct fields.
43  // Don't warn if we're in an implicitly-generated constructor.
44  const Decl *D = C.getLocationContext()->getDecl();
45  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D))
46  if (Ctor->isDefaulted())
47  return;
48 
49  ExplodedNode *N = C.generateSink();
50  if (!N)
51  return;
52  if (!BT)
53  BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
54 
55  // Generate a report for this bug.
56  auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
57  R->addRange(A->getIdx()->getSourceRange());
59  C.emitReport(std::move(R));
60 }
61 
62 void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
63  mgr.registerChecker<UndefinedArraySubscriptChecker>();
64 }
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2147
ExplodedNode * generateSink(ProgramStateRef State=nullptr, ExplodedNode *Pred=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a sink node. Generating a sink stops exploration of the given path.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
const Decl * getDecl() const
bool isUndef() const
Definition: SVals.h:121
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2066
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
const LocationContext * getLocationContext() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.