1d99bd55aSTed Kremenek //===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//
2d99bd55aSTed Kremenek //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d99bd55aSTed Kremenek //
7d99bd55aSTed Kremenek //===----------------------------------------------------------------------===//
8d99bd55aSTed Kremenek //
9d99bd55aSTed Kremenek // This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine
10d99bd55aSTed Kremenek // that performs checks for undefined array subscripts.
11d99bd55aSTed Kremenek //
12d99bd55aSTed Kremenek //===----------------------------------------------------------------------===//
13d99bd55aSTed Kremenek
1476a21502SKristof Umann #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
152ab0ac53SReid Kleckner #include "clang/AST/DeclCXX.h"
163a02247dSChandler Carruth #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
176a5674ffSArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/Checker.h"
18da6c7568SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19da6c7568SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20d99bd55aSTed Kremenek
21d99bd55aSTed Kremenek using namespace clang;
22d99bd55aSTed Kremenek using namespace ento;
23d99bd55aSTed Kremenek
24d99bd55aSTed Kremenek namespace {
25d99bd55aSTed Kremenek class UndefinedArraySubscriptChecker
266a5674ffSArgyrios Kyrtzidis : public Checker< check::PreStmt<ArraySubscriptExpr> > {
27b8984329SAhmed Charles mutable std::unique_ptr<BugType> BT;
28da6c7568SArgyrios Kyrtzidis
29d99bd55aSTed Kremenek public:
30da6c7568SArgyrios Kyrtzidis void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
31d99bd55aSTed Kremenek };
32d99bd55aSTed Kremenek } // end anonymous namespace
33d99bd55aSTed Kremenek
34d99bd55aSTed Kremenek void
checkPreStmt(const ArraySubscriptExpr * A,CheckerContext & C) const35da6c7568SArgyrios Kyrtzidis UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
36da6c7568SArgyrios Kyrtzidis CheckerContext &C) const {
37bc74eb1cSJordan Rose const Expr *Index = A->getIdx();
38bc74eb1cSJordan Rose if (!C.getSVal(Index).isUndef())
39bc74eb1cSJordan Rose return;
40bc74eb1cSJordan Rose
41bc74eb1cSJordan Rose // Sema generates anonymous array variables for copying array struct fields.
42bc74eb1cSJordan Rose // Don't warn if we're in an implicitly-generated constructor.
43bc74eb1cSJordan Rose const Decl *D = C.getLocationContext()->getDecl();
44bc74eb1cSJordan Rose if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D))
4554533f73SJordan Rose if (Ctor->isDefaulted())
46bc74eb1cSJordan Rose return;
47bc74eb1cSJordan Rose
48e39bd407SDevin Coughlin ExplodedNode *N = C.generateErrorNode();
49bc74eb1cSJordan Rose if (!N)
50bc74eb1cSJordan Rose return;
51d99bd55aSTed Kremenek if (!BT)
524aca9b1cSAlexander Kornienko BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
53d99bd55aSTed Kremenek
54d99bd55aSTed Kremenek // Generate a report for this bug.
5572649423SKristof Umann auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
56d99bd55aSTed Kremenek R->addRange(A->getIdx()->getSourceRange());
57b2cf0063SGeorge Karpenkov bugreporter::trackExpressionValue(N, A->getIdx(), *R);
588d3a7a56SAaron Ballman C.emitReport(std::move(R));
59d99bd55aSTed Kremenek }
60da6c7568SArgyrios Kyrtzidis
registerUndefinedArraySubscriptChecker(CheckerManager & mgr)61da6c7568SArgyrios Kyrtzidis void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
62da6c7568SArgyrios Kyrtzidis mgr.registerChecker<UndefinedArraySubscriptChecker>();
63da6c7568SArgyrios Kyrtzidis }
64058a7a45SKristof Umann
shouldRegisterUndefinedArraySubscriptChecker(const CheckerManager & mgr)65*bda3dd0dSKirstóf Umann bool ento::shouldRegisterUndefinedArraySubscriptChecker(const CheckerManager &mgr) {
66058a7a45SKristof Umann return true;
67058a7a45SKristof Umann }
68