diff options
author | Jordy Rose <jediknil@belkadan.com> | 2011-06-14 01:26:48 +0000 |
---|---|---|
committer | Jordy Rose <jediknil@belkadan.com> | 2011-06-14 01:26:48 +0000 |
commit | bd32beee8a0f22e1d5245112f5e34ad4669994ae (patch) | |
tree | c0911de7726ebcce0419f56952857e0bb79d0563 /lib/StaticAnalyzer/Checkers/CStringChecker.cpp | |
parent | 793bff3fb7ca2a31e81aa7f4f3f21f921459010b (diff) |
[analyzer] Change large if body to early return. No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132956 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CStringChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 155 |
1 files changed, 78 insertions, 77 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 1c9064e40d..fc9620f633 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -934,92 +934,93 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE, state = checkNonNull(C, state, Arg, ArgVal); - if (state) { - SVal strLength = getCStringLength(C, state, Arg, ArgVal); + if (!state) + return; - // If the argument isn't a valid C string, there's no valid state to - // transition to. - if (strLength.isUndef()) - return; + SVal strLength = getCStringLength(C, state, Arg, ArgVal); - DefinedOrUnknownSVal result = UnknownVal(); - - // If the check is for strnlen() then bind the return value to no more than - // the maxlen value. - if (IsStrnlen) { - QualType cmpTy = C.getSValBuilder().getContext().IntTy; - - // It's a little unfortunate to be getting this again, - // but it's not that expensive... - const Expr *maxlenExpr = CE->getArg(1); - SVal maxlenVal = state->getSVal(maxlenExpr); - - NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength); - NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal); - - if (strLengthNL && maxlenValNL) { - const GRState *stateStringTooLong, *stateStringNotTooLong; - - // Check if the strLength is greater than the maxlen. - llvm::tie(stateStringTooLong, stateStringNotTooLong) = - state->assume(cast<DefinedOrUnknownSVal> - (C.getSValBuilder().evalBinOpNN(state, BO_GT, - *strLengthNL, - *maxlenValNL, - cmpTy))); - - if (stateStringTooLong && !stateStringNotTooLong) { - // If the string is longer than maxlen, return maxlen. - result = *maxlenValNL; - } else if (stateStringNotTooLong && !stateStringTooLong) { - // If the string is shorter than maxlen, return its length. - result = *strLengthNL; - } - } + // If the argument isn't a valid C string, there's no valid state to + // transition to. + if (strLength.isUndef()) + return; - if (result.isUnknown()) { - // If we don't have enough information for a comparison, there's - // no guarantee the full string length will actually be returned. - // All we know is the return value is the min of the string length - // and the limit. This is better than nothing. - unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); - NonLoc *resultNL = cast<NonLoc>(&result); - - if (strLengthNL) { - state = state->assume(cast<DefinedOrUnknownSVal> - (C.getSValBuilder().evalBinOpNN(state, BO_LE, - *resultNL, - *strLengthNL, - cmpTy)), true); - } - - if (maxlenValNL) { - state = state->assume(cast<DefinedOrUnknownSVal> - (C.getSValBuilder().evalBinOpNN(state, BO_LE, - *resultNL, - *maxlenValNL, - cmpTy)), true); - } - } + DefinedOrUnknownSVal result = UnknownVal(); - } else { - // This is a plain strlen(), not strnlen(). - result = cast<DefinedOrUnknownSVal>(strLength); + // If the check is for strnlen() then bind the return value to no more than + // the maxlen value. + if (IsStrnlen) { + QualType cmpTy = C.getSValBuilder().getContext().IntTy; - // If we don't know the length of the string, conjure a return - // value, so it can be used in constraints, at least. - if (result.isUnknown()) { - unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); + // It's a little unfortunate to be getting this again, + // but it's not that expensive... + const Expr *maxlenExpr = CE->getArg(1); + SVal maxlenVal = state->getSVal(maxlenExpr); + + NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength); + NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal); + + if (strLengthNL && maxlenValNL) { + const GRState *stateStringTooLong, *stateStringNotTooLong; + + // Check if the strLength is greater than the maxlen. + llvm::tie(stateStringTooLong, stateStringNotTooLong) = + state->assume(cast<DefinedOrUnknownSVal> + (C.getSValBuilder().evalBinOpNN(state, BO_GT, + *strLengthNL, + *maxlenValNL, + cmpTy))); + + if (stateStringTooLong && !stateStringNotTooLong) { + // If the string is longer than maxlen, return maxlen. + result = *maxlenValNL; + } else if (stateStringNotTooLong && !stateStringTooLong) { + // If the string is shorter than maxlen, return its length. + result = *strLengthNL; } } - // Bind the return value. - assert(!result.isUnknown() && "Should have conjured a value by now"); - state = state->BindExpr(CE, result); - C.addTransition(state); + if (result.isUnknown()) { + // If we don't have enough information for a comparison, there's + // no guarantee the full string length will actually be returned. + // All we know is the return value is the min of the string length + // and the limit. This is better than nothing. + unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); + result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); + NonLoc *resultNL = cast<NonLoc>(&result); + + if (strLengthNL) { + state = state->assume(cast<DefinedOrUnknownSVal> + (C.getSValBuilder().evalBinOpNN(state, BO_LE, + *resultNL, + *strLengthNL, + cmpTy)), true); + } + + if (maxlenValNL) { + state = state->assume(cast<DefinedOrUnknownSVal> + (C.getSValBuilder().evalBinOpNN(state, BO_LE, + *resultNL, + *maxlenValNL, + cmpTy)), true); + } + } + + } else { + // This is a plain strlen(), not strnlen(). + result = cast<DefinedOrUnknownSVal>(strLength); + + // If we don't know the length of the string, conjure a return + // value, so it can be used in constraints, at least. + if (result.isUnknown()) { + unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); + result = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); + } } + + // Bind the return value. + assert(!result.isUnknown() && "Should have conjured a value by now"); + state = state->BindExpr(CE, result); + C.addTransition(state); } void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const { |