[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) {
----------------
Xazax-hun wrote:

I am wondering if there is a way to get around pattern matching. Is it possible, that the same information could be derived from the memory regions? 

https://github.com/llvm/llvm-project/pull/112784


More information about the cfe-commits mailing list