diff options
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CStringChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 77c24629d71e..28ad7e9e5071 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -289,8 +289,8 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C, if (!ER) return state; - assert(ER->getValueType() == C.getASTContext().CharTy && - "CheckLocation should only be called with char* ElementRegions"); + if (ER->getValueType() != C.getASTContext().CharTy) + return state; // Get the size of the array. const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion()); @@ -874,6 +874,8 @@ bool CStringChecker::IsFirstBufInBound(CheckerContext &C, if (!ER) return true; // cf top comment. + // FIXME: Does this crash when a non-standard definition + // of a library function is encountered? assert(ER->getValueType() == C.getASTContext().CharTy && "IsFirstBufInBound should only be called with char* ElementRegions"); @@ -1050,31 +1052,22 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, // If this is mempcpy, get the byte after the last byte copied and // bind the expr. if (IsMempcpy) { - loc::MemRegionVal destRegVal = destVal.castAs<loc::MemRegionVal>(); - - // Get the length to copy. - if (Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) { - // Get the byte after the last byte copied. - SValBuilder &SvalBuilder = C.getSValBuilder(); - ASTContext &Ctx = SvalBuilder.getContext(); - QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); - loc::MemRegionVal DestRegCharVal = SvalBuilder.evalCast(destRegVal, - CharPtrTy, Dest->getType()).castAs<loc::MemRegionVal>(); - SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, - DestRegCharVal, - *lenValNonLoc, - Dest->getType()); - - // The byte after the last byte copied is the return value. - state = state->BindExpr(CE, LCtx, lastElement); - } else { - // If we don't know how much we copied, we can at least - // conjure a return value for later. - SVal result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, + // Get the byte after the last byte copied. + SValBuilder &SvalBuilder = C.getSValBuilder(); + ASTContext &Ctx = SvalBuilder.getContext(); + QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); + SVal DestRegCharVal = + SvalBuilder.evalCast(destVal, CharPtrTy, Dest->getType()); + SVal lastElement = C.getSValBuilder().evalBinOp( + state, BO_Add, DestRegCharVal, sizeVal, Dest->getType()); + // If we don't know how much we copied, we can at least + // conjure a return value for later. + if (lastElement.isUnknown()) + lastElement = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); - state = state->BindExpr(CE, LCtx, result); - } + // The byte after the last byte copied is the return value. + state = state->BindExpr(CE, LCtx, lastElement); } else { // All other copies return the destination buffer. // (Well, bcopy() has a void return type, but this won't hurt.) |