mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[analyzer] Replace adjacent assumeInBound calls to assumeInBoundDual
This is to minimize superfluous assume calls. Depends on D124758 Differential Revision: https://reviews.llvm.org/D124761
This commit is contained in:
parent
1c1c1e25f9
commit
34ac048aef
@ -225,6 +225,10 @@ public:
|
||||
LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
|
||||
assume(DefinedOrUnknownSVal cond) const;
|
||||
|
||||
LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
|
||||
assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
|
||||
QualType IndexType = QualType()) const;
|
||||
|
||||
LLVM_NODISCARD ProgramStateRef
|
||||
assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
|
||||
bool assumption, QualType IndexType = QualType()) const;
|
||||
|
@ -58,8 +58,8 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
|
||||
DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
|
||||
state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType());
|
||||
|
||||
ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
|
||||
ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
|
||||
ProgramStateRef StInBound, StOutBound;
|
||||
std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, ElementCount);
|
||||
if (StOutBound && !StInBound) {
|
||||
ExplodedNode *N = C.generateErrorNode(StOutBound);
|
||||
if (!N)
|
||||
|
@ -355,8 +355,8 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
|
||||
// Get the index of the accessed element.
|
||||
DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
|
||||
|
||||
ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
|
||||
ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
|
||||
ProgramStateRef StInBound, StOutBound;
|
||||
std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, Size);
|
||||
if (StOutBound && !StInBound) {
|
||||
// These checks are either enabled by the CString out-of-bounds checker
|
||||
// explicitly or implicitly by the Malloc checker.
|
||||
|
@ -137,8 +137,8 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE,
|
||||
|
||||
// Now, check if 'Idx in [0, Size-1]'.
|
||||
const QualType T = IdxExpr->getType();
|
||||
ProgramStateRef StInBound = State->assumeInBound(Idx, *Size, true, T);
|
||||
ProgramStateRef StOutBound = State->assumeInBound(Idx, *Size, false, T);
|
||||
ProgramStateRef StInBound, StOutBound;
|
||||
std::tie(StInBound, StOutBound) = State->assumeInBoundDual(Idx, *Size, T);
|
||||
if (StOutBound && !StInBound) {
|
||||
ExplodedNode *N = C.generateErrorNode(StOutBound);
|
||||
if (!N)
|
||||
|
@ -64,8 +64,8 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
||||
if (Idx == ElementCount)
|
||||
return;
|
||||
|
||||
ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
|
||||
ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
|
||||
ProgramStateRef StInBound, StOutBound;
|
||||
std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, ElementCount);
|
||||
if (StOutBound && !StInBound) {
|
||||
ExplodedNode *N = C.generateErrorNode(StOutBound);
|
||||
|
||||
|
@ -53,8 +53,8 @@ static bool isArrayIndexOutOfBounds(CheckerContext &C, const Expr *Ex) {
|
||||
DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
|
||||
DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
|
||||
state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType());
|
||||
ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
|
||||
ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
|
||||
ProgramStateRef StInBound, StOutBound;
|
||||
std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, ElementCount);
|
||||
return StOutBound && !StInBound;
|
||||
}
|
||||
|
||||
|
@ -314,12 +314,12 @@ ProgramStateRef ProgramState::BindExpr(const Stmt *S,
|
||||
return getStateManager().getPersistentState(NewSt);
|
||||
}
|
||||
|
||||
ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||
DefinedOrUnknownSVal UpperBound,
|
||||
bool Assumption,
|
||||
QualType indexTy) const {
|
||||
LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
|
||||
ProgramState::assumeInBoundDual(DefinedOrUnknownSVal Idx,
|
||||
DefinedOrUnknownSVal UpperBound,
|
||||
QualType indexTy) const {
|
||||
if (Idx.isUnknown() || UpperBound.isUnknown())
|
||||
return this;
|
||||
return {this, this};
|
||||
|
||||
// Build an expression for 0 <= Idx < UpperBound.
|
||||
// This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
|
||||
@ -338,7 +338,7 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||
SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
|
||||
Idx.castAs<NonLoc>(), Min, indexTy);
|
||||
if (newIdx.isUnknownOrUndef())
|
||||
return this;
|
||||
return {this, this};
|
||||
|
||||
// Adjust the upper bound.
|
||||
SVal newBound =
|
||||
@ -346,17 +346,26 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||
Min, indexTy);
|
||||
|
||||
if (newBound.isUnknownOrUndef())
|
||||
return this;
|
||||
return {this, this};
|
||||
|
||||
// Build the actual comparison.
|
||||
SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
|
||||
newBound.castAs<NonLoc>(), Ctx.IntTy);
|
||||
if (inBound.isUnknownOrUndef())
|
||||
return this;
|
||||
return {this, this};
|
||||
|
||||
// Finally, let the constraint manager take care of it.
|
||||
ConstraintManager &CM = SM.getConstraintManager();
|
||||
return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
|
||||
return CM.assumeDual(this, inBound.castAs<DefinedSVal>());
|
||||
}
|
||||
|
||||
ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
|
||||
DefinedOrUnknownSVal UpperBound,
|
||||
bool Assumption,
|
||||
QualType indexTy) const {
|
||||
std::pair<ProgramStateRef, ProgramStateRef> R =
|
||||
assumeInBoundDual(Idx, UpperBound, indexTy);
|
||||
return Assumption ? R.first : R.second;
|
||||
}
|
||||
|
||||
ConditionTruthVal ProgramState::isNonNull(SVal V) const {
|
||||
|
Loading…
Reference in New Issue
Block a user