aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
new file mode 100644
index 000000000000..8b2172db445c
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
@@ -0,0 +1,71 @@
+//===- DynamicSize.cpp - Dynamic size related APIs --------------*- 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 file defines APIs that track and query dynamic size information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+
+namespace clang {
+namespace ento {
+
+DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
+ SValBuilder &SVB) {
+ return MR->getMemRegionManager().getStaticSize(MR, SVB);
+}
+
+DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
+ const MemRegion *MR,
+ SValBuilder &SVB,
+ QualType ElementTy) {
+ MemRegionManager &MemMgr = MR->getMemRegionManager();
+ ASTContext &Ctx = MemMgr.getContext();
+
+ DefinedOrUnknownSVal Size = getDynamicSize(State, MR, SVB);
+ SVal ElementSizeV = SVB.makeIntVal(
+ Ctx.getTypeSizeInChars(ElementTy).getQuantity(), SVB.getArrayIndexType());
+
+ SVal DivisionV =
+ SVB.evalBinOp(State, BO_Div, Size, ElementSizeV, SVB.getArrayIndexType());
+
+ return DivisionV.castAs<DefinedOrUnknownSVal>();
+}
+
+SVal getDynamicSizeWithOffset(ProgramStateRef State, const SVal &BufV) {
+ SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder();
+ const MemRegion *MRegion = BufV.getAsRegion();
+ if (!MRegion)
+ return UnknownVal();
+ RegionOffset Offset = MRegion->getAsOffset();
+ if (Offset.hasSymbolicOffset())
+ return UnknownVal();
+ const MemRegion *BaseRegion = MRegion->getBaseRegion();
+ if (!BaseRegion)
+ return UnknownVal();
+
+ NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex(
+ Offset.getOffset() /
+ MRegion->getMemRegionManager().getContext().getCharWidth());
+ DefinedOrUnknownSVal ExtentInBytes =
+ getDynamicSize(State, BaseRegion, SvalBuilder);
+
+ return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub,
+ ExtentInBytes, OffsetInBytes,
+ SvalBuilder.getArrayIndexType());
+}
+
+} // namespace ento
+} // namespace clang