summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-08-19 16:27:34 +0000
committerJordan Rose <jordan_rose@apple.com>2013-08-19 16:27:34 +0000
commit60619a639b727af3e2a82801ad0626c6bfc75cbb (patch)
tree7d463a4634cf4dc97d7d34fc20deb03212fa9da5 /clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
parent5374c07ab92e2c78ccf43186383fc5e33835ebb8 (diff)
downloadbcm5719-llvm-60619a639b727af3e2a82801ad0626c6bfc75cbb.tar.gz
bcm5719-llvm-60619a639b727af3e2a82801ad0626c6bfc75cbb.zip
[analyzer] Assume that strings are no longer than SIZE_MAX/4.
This keeps the analyzer from making silly assumptions, like thinking strlen(foo)+1 could wrap around to 0. This fixes PR16558. Patch by Karthik Bhat! llvm-svn: 188680
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 932f6316b55..ba1d9b9ff6b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -661,7 +661,7 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
if (Recorded)
return *Recorded;
}
-
+
// Otherwise, get a new symbol and update the state.
SValBuilder &svalBuilder = C.getSValBuilder();
QualType sizeTy = svalBuilder.getContext().getSizeType();
@@ -669,8 +669,21 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
MR, Ex, sizeTy,
C.blockCount());
- if (!hypothetical)
+ if (!hypothetical) {
+ if (Optional<NonLoc> strLn = strLength.getAs<NonLoc>()) {
+ // In case of unbounded calls strlen etc bound the range to SIZE_MAX/4
+ BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
+ const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
+ llvm::APSInt fourInt = APSIntType(maxValInt).getValue(4);
+ const llvm::APSInt *maxLengthInt = BVF.evalAPSInt(BO_Div, maxValInt,
+ fourInt);
+ NonLoc maxLength = svalBuilder.makeIntVal(*maxLengthInt);
+ SVal evalLength = svalBuilder.evalBinOpNN(state, BO_LE, *strLn,
+ maxLength, sizeTy);
+ state = state->assume(evalLength.castAs<DefinedOrUnknownSVal>(), true);
+ }
state = state->set<CStringLength>(MR, strLength);
+ }
return strLength;
}
OpenPOWER on IntegriCloud