65 lines · cpp
1//===--- UndefinedArraySubscriptChecker.h ----------------------*- C++ -*--===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// This defines UndefinedArraySubscriptChecker, a builtin check in ExprEngine10// that performs checks for undefined array subscripts.11//12//===----------------------------------------------------------------------===//13 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"20 21using namespace clang;22using namespace ento;23 24namespace {25class UndefinedArraySubscriptChecker26 : public Checker< check::PreStmt<ArraySubscriptExpr> > {27 const BugType BT{this, "Array subscript is undefined"};28 29public:30 void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;31};32} // end anonymous namespace33 34void35UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,36 CheckerContext &C) const {37 const Expr *Index = A->getIdx();38 if (!C.getSVal(Index).isUndef())39 return;40 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())46 return;47 48 ExplodedNode *N = C.generateErrorNode();49 if (!N)50 return;51 // Generate a report for this bug.52 auto R = std::make_unique<PathSensitiveBugReport>(BT, BT.getDescription(), N);53 R->addRange(A->getIdx()->getSourceRange());54 bugreporter::trackExpressionValue(N, A->getIdx(), *R);55 C.emitReport(std::move(R));56}57 58void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {59 mgr.registerChecker<UndefinedArraySubscriptChecker>();60}61 62bool ento::shouldRegisterUndefinedArraySubscriptChecker(const CheckerManager &mgr) {63 return true;64}65