aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp72
1 files changed, 56 insertions, 16 deletions
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp
index 6a86536492cd..6cf06413b537 100644
--- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp
+++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp
@@ -30,7 +30,9 @@ DefinedOrUnknownSVal getDynamicExtent(ProgramStateRef State,
MR = MR->StripCasts();
if (const DefinedOrUnknownSVal *Size = State->get<DynamicExtentMap>(MR))
- return *Size;
+ if (auto SSize =
+ SVB.convertToArrayIndex(*Size).getAs<DefinedOrUnknownSVal>())
+ return *SSize;
return MR->getMemRegionManager().getStaticSize(MR, SVB);
}
@@ -40,6 +42,32 @@ DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB) {
SVB.getArrayIndexType());
}
+static DefinedOrUnknownSVal getConstantArrayElementCount(SValBuilder &SVB,
+ const MemRegion *MR) {
+ MR = MR->StripCasts();
+
+ const auto *TVR = MR->getAs<TypedValueRegion>();
+ if (!TVR)
+ return UnknownVal();
+
+ if (const ConstantArrayType *CAT =
+ SVB.getContext().getAsConstantArrayType(TVR->getValueType()))
+ return SVB.makeIntVal(CAT->getSize(), /* isUnsigned = */ false);
+
+ return UnknownVal();
+}
+
+static DefinedOrUnknownSVal
+getDynamicElementCount(ProgramStateRef State, SVal Size,
+ DefinedOrUnknownSVal ElementSize) {
+ SValBuilder &SVB = State->getStateManager().getSValBuilder();
+
+ auto ElementCount =
+ SVB.evalBinOp(State, BO_Div, Size, ElementSize, SVB.getArrayIndexType())
+ .getAs<DefinedOrUnknownSVal>();
+ return ElementCount.value_or(UnknownVal());
+}
+
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
const MemRegion *MR,
SValBuilder &SVB,
@@ -47,17 +75,16 @@ DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
assert(MR != nullptr && "Not-null region expected");
MR = MR->StripCasts();
- DefinedOrUnknownSVal Size = getDynamicExtent(State, MR, SVB);
- SVal ElementSize = getElementExtent(ElementTy, SVB);
+ DefinedOrUnknownSVal ElementSize = getElementExtent(ElementTy, SVB);
+ if (ElementSize.isZeroConstant())
+ return getConstantArrayElementCount(SVB, MR);
- SVal ElementCount =
- SVB.evalBinOp(State, BO_Div, Size, ElementSize, SVB.getArrayIndexType());
-
- return ElementCount.castAs<DefinedOrUnknownSVal>();
+ return getDynamicElementCount(State, getDynamicExtent(State, MR, SVB),
+ ElementSize);
}
SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV) {
- SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder();
+ SValBuilder &SVB = State->getStateManager().getSValBuilder();
const MemRegion *MRegion = BufV.getAsRegion();
if (!MRegion)
return UnknownVal();
@@ -68,15 +95,28 @@ SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV) {
if (!BaseRegion)
return UnknownVal();
- NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex(
- Offset.getOffset() /
- MRegion->getMemRegionManager().getContext().getCharWidth());
- DefinedOrUnknownSVal ExtentInBytes =
- getDynamicExtent(State, BaseRegion, SvalBuilder);
+ NonLoc OffsetInChars =
+ SVB.makeArrayIndex(Offset.getOffset() / SVB.getContext().getCharWidth());
+ DefinedOrUnknownSVal ExtentInBytes = getDynamicExtent(State, BaseRegion, SVB);
+
+ return SVB.evalBinOp(State, BinaryOperator::Opcode::BO_Sub, ExtentInBytes,
+ OffsetInChars, SVB.getArrayIndexType());
+}
+
+DefinedOrUnknownSVal getDynamicElementCountWithOffset(ProgramStateRef State,
+ SVal BufV,
+ QualType ElementTy) {
+ const MemRegion *MR = BufV.getAsRegion();
+ if (!MR)
+ return UnknownVal();
+
+ SValBuilder &SVB = State->getStateManager().getSValBuilder();
+ DefinedOrUnknownSVal ElementSize = getElementExtent(ElementTy, SVB);
+ if (ElementSize.isZeroConstant())
+ return getConstantArrayElementCount(SVB, MR);
- return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub,
- ExtentInBytes, OffsetInBytes,
- SvalBuilder.getArrayIndexType());
+ return getDynamicElementCount(State, getDynamicExtentWithOffset(State, BufV),
+ ElementSize);
}
ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR,