[clang] [analyzer] Add alpha.cplusplus.BoundsInformation checker (PR #112784)
Gábor Horváth via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 21 03:43:57 PDT 2024
================
@@ -0,0 +1,199 @@
+//== BoundsInformationChecker.cpp - bounds information checker --*- C++ -*--==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines BoundsInformationChecker, a path-sensitive checker that
+// checks that the buffer and count arguments are within the bounds of
+// the source buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class BoundsInformationChecker : public Checker<check::PreCall> {
+ const BugType BT_DifferentMemRegion{
+ this, "std::span constructor arguments from different sources",
+ categories::SecurityError};
+ const BugType BT_NonConstantSizeArg{
+ this,
+ "std::span constructor for std::array has non-constant size argument",
+ categories::SecurityError};
+ const BugType BT_OutOfBounds{
+ this,
+ "std::span constructor for std::array uses out-of-bounds size argument",
+ categories::SecurityError};
+ void reportBug(ExplodedNode *N, const Expr *E, CheckerContext &C,
+ const BugType &BT, StringRef Msg) const;
+
+public:
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+void BoundsInformationChecker::reportBug(ExplodedNode *N, const Expr *E,
+ CheckerContext &C, const BugType &BT,
+ StringRef Msg) const {
+ // Generate a report for this bug.
+ auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
+ if (auto *CE = dyn_cast<CXXConstructExpr>(E)) {
+ bugreporter::trackExpressionValue(N, CE->getArg(0), *R);
+ bugreporter::trackExpressionValue(N, CE->getArg(1), *R);
+ }
+ C.emitReport(std::move(R));
+}
+
+static const MemRegion *GetRegionOrigin(SVal SV) {
+ const SymExpr *Sym = SV.getAsSymbol(/*IncludeBaseRegions =*/true);
+ return Sym ? Sym->getOriginRegion() : nullptr;
+}
+
+static const ValueDecl *GetExpressionOrigin(const Stmt *STMT) {
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(STMT)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ return VD;
+ } else if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(STMT)) {
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
+ MCE->getImplicitObjectArgument()->IgnoreParenCasts())) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ return VD;
+ } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(
+ MCE->getImplicitObjectArgument()->IgnoreParenCasts())) {
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+ return FD;
+ }
+ } else if (const CXXOperatorCallExpr *OCE =
+ dyn_cast<CXXOperatorCallExpr>(STMT)) {
+ if (OCE->getNumArgs() >= 1) {
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(OCE->getArg(0))) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ return VD;
+ }
+ }
+ } else if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(STMT)) {
+ if (const ArraySubscriptExpr *ASExpr =
----------------
Xazax-hun wrote:
Will this work properly for nesting? E.g., `foo[i][j]`. I wonder if this needs to be recursive. Or is this a scenario that we explicitly don't want to support yet?
https://github.com/llvm/llvm-project/pull/112784
More information about the cfe-commits
mailing list