Author: Gabor Marton Date: 2022-05-10T10:16:55+02:00 New Revision: 34ac048aef298270d82e5430727ffd00f15c63d5
URL: https://github.com/llvm/llvm-project/commit/34ac048aef298270d82e5430727ffd00f15c63d5 DIFF: https://github.com/llvm/llvm-project/commit/34ac048aef298270d82e5430727ffd00f15c63d5.diff LOG: [analyzer] Replace adjacent assumeInBound calls to assumeInBoundDual This is to minimize superfluous assume calls. Depends on D124758 Differential Revision: https://reviews.llvm.org/D124761 Added: Modified: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp clang/lib/StaticAnalyzer/Core/ProgramState.cpp Removed: ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 0e283103f5c2e..cb6540ff7e7c4 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -225,6 +225,10 @@ class ProgramState : public llvm::FoldingSetNode { 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; diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index 605b11874ef5e..03e85b9c43739 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -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) diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index b001288a3d6ba..57357dadd7562 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -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. diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index 13985af76b00c..c15b5f4ee609a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -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) diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp index c4dc06d4a0777..b35ab1fe23ce3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp @@ -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); diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index 6d49af843b972..2658b473a4775 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -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; } diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 9d84b816c122f..8465cc70fbbd9 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits