diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:00:46 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:00:46 +0000 |
| commit | 0414e226b73ef7952be3ef346c1c802e7f036f54 (patch) | |
| tree | ff0114c0524108a01707e4101f3224db0d7fd01f /lib/StaticAnalyzer/Core/SValBuilder.cpp | |
| parent | 97b17066aaac3f1590a809d79abe98fde03821ec (diff) | |
Notes
Diffstat (limited to 'lib/StaticAnalyzer/Core/SValBuilder.cpp')
| -rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index cdae04068e1d1..18315225a99d5 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -214,15 +214,15 @@ SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, } DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) { - return loc::MemRegionVal(MemMgr.getFunctionTextRegion(func)); + return loc::MemRegionVal(MemMgr.getFunctionCodeRegion(func)); } DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount) { - const BlockTextRegion *BC = - MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext()); + const BlockCodeRegion *BC = + MemMgr.getBlockCodeRegion(block, locTy, locContext->getAnalysisDeclContext()); const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext, blockCount); return loc::MemRegionVal(BD); @@ -423,6 +423,45 @@ static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy, return true; } +// Handles casts of type CK_IntegralCast. +// At the moment, this function will redirect to evalCast, except when the range +// of the original value is known to be greater than the max of the target type. +SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val, + QualType castTy, QualType originalTy) { + + // No truncations if target type is big enough. + if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy)) + return evalCast(val, castTy, originalTy); + + const SymExpr *se = val.getAsSymbolicExpression(); + if (!se) // Let evalCast handle non symbolic expressions. + return evalCast(val, castTy, originalTy); + + // Find the maximum value of the target type. + APSIntType ToType(getContext().getTypeSize(castTy), + castTy->isUnsignedIntegerType()); + llvm::APSInt ToTypeMax = ToType.getMaxValue(); + NonLoc ToTypeMaxVal = + makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue() + : ToTypeMax.getSExtValue(), + castTy) + .castAs<NonLoc>(); + // Check the range of the symbol being casted against the maximum value of the + // target type. + NonLoc FromVal = val.castAs<NonLoc>(); + QualType CmpTy = getConditionType(); + NonLoc CompVal = + evalBinOpNN(state, BO_LT, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>(); + ProgramStateRef IsNotTruncated, IsTruncated; + std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal); + if (!IsNotTruncated && IsTruncated) { + // Symbol is truncated so we evaluate it as a cast. + NonLoc CastVal = makeNonLoc(se, originalTy, castTy); + return CastVal; + } + return evalCast(val, castTy, originalTy); +} + // FIXME: should rewrite according to the cast kind. SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { castTy = Context.getCanonicalType(castTy); |
