================ @@ -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 = ---------------- haoNoQ wrote:
The main problem with nesting is that `std::span` itself doesn't work properly with nesting. A `std::span<std::span<T>>` doesn't really represent a view into `std::array<std::array<T>>`. This is why `std::mdspan` is a thing, but it's an entire completely different thing. https://github.com/llvm/llvm-project/pull/112784 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits