1 //===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine
10 // that performs checks for undefined array subscripts.
12 //===----------------------------------------------------------------------===//
14 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
17 #include "clang/StaticAnalyzer/Core/Checker.h"
18 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
21 using namespace clang
;
25 class UndefinedArraySubscriptChecker
26 : public Checker
< check::PreStmt
<ArraySubscriptExpr
> > {
27 mutable std::unique_ptr
<BugType
> BT
;
30 void checkPreStmt(const ArraySubscriptExpr
*A
, CheckerContext
&C
) const;
32 } // end anonymous namespace
35 UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr
*A
,
36 CheckerContext
&C
) const {
37 const Expr
*Index
= A
->getIdx();
38 if (!C
.getSVal(Index
).isUndef())
41 // Sema generates anonymous array variables for copying array struct fields.
42 // Don't warn if we're in an implicitly-generated constructor.
43 const Decl
*D
= C
.getLocationContext()->getDecl();
44 if (const CXXConstructorDecl
*Ctor
= dyn_cast
<CXXConstructorDecl
>(D
))
45 if (Ctor
->isDefaulted())
48 ExplodedNode
*N
= C
.generateErrorNode();
52 BT
.reset(new BugType(this, "Array subscript is undefined"));
54 // Generate a report for this bug.
55 auto R
= std::make_unique
<PathSensitiveBugReport
>(*BT
, BT
->getDescription(), N
);
56 R
->addRange(A
->getIdx()->getSourceRange());
57 bugreporter::trackExpressionValue(N
, A
->getIdx(), *R
);
58 C
.emitReport(std::move(R
));
61 void ento::registerUndefinedArraySubscriptChecker(CheckerManager
&mgr
) {
62 mgr
.registerChecker
<UndefinedArraySubscriptChecker
>();
65 bool ento::shouldRegisterUndefinedArraySubscriptChecker(const CheckerManager
&mgr
) {