зеркало из https://github.com/microsoft/clang.git
Cast evaluation no longer touch GRState.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95290 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
95a011204f
Коммит
814e6b9154
|
@ -38,33 +38,8 @@ public:
|
|||
SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
|
||||
virtual ~SValuator() {}
|
||||
|
||||
template <typename T>
|
||||
class GenericCastResult : public std::pair<const GRState *, T> {
|
||||
public:
|
||||
const GRState *getState() const { return this->first; }
|
||||
T getSVal() const { return this->second; }
|
||||
GenericCastResult(const GRState *s, T v)
|
||||
: std::pair<const GRState*,T>(s, v) {}
|
||||
};
|
||||
SVal EvalCast(SVal V, QualType castTy, QualType originalType);
|
||||
|
||||
class CastResult : public GenericCastResult<SVal> {
|
||||
public:
|
||||
CastResult(const GRState *s, SVal v) : GenericCastResult<SVal>(s, v) {}
|
||||
};
|
||||
|
||||
class DefinedOrUnknownCastResult :
|
||||
public GenericCastResult<DefinedOrUnknownSVal> {
|
||||
public:
|
||||
DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v)
|
||||
: GenericCastResult<DefinedOrUnknownSVal>(s, v) {}
|
||||
};
|
||||
|
||||
CastResult EvalCast(SVal V, const GRState *ST,
|
||||
QualType castTy, QualType originalType);
|
||||
|
||||
DefinedOrUnknownCastResult EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
|
||||
QualType castTy, QualType originalType);
|
||||
|
||||
virtual SVal EvalMinus(NonLoc val) = 0;
|
||||
|
||||
virtual SVal EvalComplement(NonLoc val) = 0;
|
||||
|
|
|
@ -50,6 +50,7 @@ void AdjustedReturnValueChecker::PostVisitCallExpr(CheckerContext &C,
|
|||
const GRState *state = C.getState();
|
||||
|
||||
SVal V = state->getSVal(CE);
|
||||
|
||||
if (V.isUnknown())
|
||||
return;
|
||||
|
||||
|
@ -91,7 +92,7 @@ void AdjustedReturnValueChecker::PostVisitCallExpr(CheckerContext &C,
|
|||
// FIXME: Do more checking and actual emit an error. At least performing
|
||||
// the cast avoids some assertion failures elsewhere.
|
||||
SValuator &SVator = C.getSValuator();
|
||||
const SValuator::CastResult &R = SVator.EvalCast(V, state, expectedResultTy, actualResultTy);
|
||||
C.GenerateNode(R.getState()->BindExpr(CE, R.getSVal()));
|
||||
V = SVator.EvalCast(V, expectedResultTy, actualResultTy);
|
||||
C.GenerateNode(state->BindExpr(CE, V));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
// functions and build the ExplodedGraph at the expression level.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "GRExprEngineInternalChecks.h"
|
||||
#include "clang/Checker/PathSensitive/GRExprEngine.h"
|
||||
#include "clang/Checker/PathSensitive/GRExprEngineBuilders.h"
|
||||
|
@ -2236,8 +2235,8 @@ void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
|
|||
ExplodedNode* N = *I;
|
||||
const GRState* state = GetState(N);
|
||||
SVal V = state->getSVal(Ex);
|
||||
const SValuator::CastResult &Res = SVator.EvalCast(V, state, T, ExTy);
|
||||
state = Res.getState()->BindExpr(CastE, Res.getSVal());
|
||||
V = SVator.EvalCast(V, T, ExTy);
|
||||
state = state->BindExpr(CastE, V);
|
||||
MakeNode(Dst, CastE, N, state);
|
||||
}
|
||||
return;
|
||||
|
@ -3007,13 +3006,11 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
|||
QualType RTy = getContext().getCanonicalType(RHS->getType());
|
||||
|
||||
// Promote LHS.
|
||||
llvm::tie(state, V) = SVator.EvalCast(V, state, CLHSTy, LTy);
|
||||
V = SVator.EvalCast(V, CLHSTy, LTy);
|
||||
|
||||
// Compute the result of the operation.
|
||||
SVal Result;
|
||||
llvm::tie(state, Result) = SVator.EvalCast(EvalBinOp(state, Op, V,
|
||||
RightV, CTy),
|
||||
state, B->getType(), CTy);
|
||||
SVal Result = SVator.EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
|
||||
B->getType(), CTy);
|
||||
|
||||
// EXPERIMENTAL: "Conjured" symbols.
|
||||
// FIXME: Handle structs.
|
||||
|
@ -3033,12 +3030,12 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
|
|||
LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count);
|
||||
|
||||
// However, we need to convert the symbol to the computation type.
|
||||
llvm::tie(state, Result) = SVator.EvalCast(LHSVal, state, CTy, LTy);
|
||||
Result = SVator.EvalCast(LHSVal, CTy, LTy);
|
||||
}
|
||||
else {
|
||||
// The left-hand side may bind to a different value then the
|
||||
// computation type.
|
||||
llvm::tie(state, LHSVal) = SVator.EvalCast(Result, state, LTy, CTy);
|
||||
LHSVal = SVator.EvalCast(Result, LTy, CTy);
|
||||
}
|
||||
|
||||
EvalStore(Tmp3, B, LHS, *I4, state->BindExpr(B, Result),
|
||||
|
|
|
@ -153,8 +153,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C,
|
|||
// Handle implicit value casts.
|
||||
if (const TypedRegion *R =
|
||||
dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
|
||||
llvm::tie(state, val) = SVator.EvalCast(val, state,R->getValueType(Ctx),
|
||||
newValueExpr->getType());
|
||||
val = SVator.EvalCast(val,R->getValueType(Ctx),newValueExpr->getType());
|
||||
}
|
||||
|
||||
Engine.EvalStore(TmpStore, NULL, const_cast<Expr *>(theValueExpr), N,
|
||||
|
|
|
@ -1523,9 +1523,8 @@ const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
|
|||
|
||||
if (IsAnyPointerOrIntptr(superTy, Ctx) &&
|
||||
IsAnyPointerOrIntptr(erTy, Ctx)) {
|
||||
SValuator::CastResult cr =
|
||||
ValMgr.getSValuator().EvalCast(V, state, superTy, erTy);
|
||||
return Bind(cr.getState(), loc::MemRegionVal(superR), cr.getSVal());
|
||||
V = ValMgr.getSValuator().EvalCast(V, superTy, erTy);
|
||||
return Bind(state, loc::MemRegionVal(superR), V);
|
||||
}
|
||||
// For now, just invalidate the fields of the struct/union/class.
|
||||
// FIXME: Precisely handle the fields of the record.
|
||||
|
|
|
@ -53,31 +53,29 @@ DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
|
|||
ValMgr.getContext().IntTy));
|
||||
}
|
||||
|
||||
SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
||||
QualType castTy, QualType originalTy){
|
||||
|
||||
SVal SValuator::EvalCast(SVal val, QualType castTy, QualType originalTy) {
|
||||
if (val.isUnknownOrUndef() || castTy == originalTy)
|
||||
return CastResult(state, val);
|
||||
return val;
|
||||
|
||||
ASTContext &C = ValMgr.getContext();
|
||||
|
||||
// For const casts, just propagate the value.
|
||||
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
|
||||
if (C.hasSameUnqualifiedType(castTy, originalTy))
|
||||
return CastResult(state, val);
|
||||
return val;
|
||||
|
||||
// Check for casts to real or complex numbers. We don't handle these at all
|
||||
// right now.
|
||||
if (castTy->isFloatingType() || castTy->isAnyComplexType())
|
||||
return CastResult(state, UnknownVal());
|
||||
return UnknownVal();
|
||||
|
||||
// Check for casts from integers to integers.
|
||||
if (castTy->isIntegerType() && originalTy->isIntegerType())
|
||||
return CastResult(state, EvalCastNL(cast<NonLoc>(val), castTy));
|
||||
return EvalCastNL(cast<NonLoc>(val), castTy);
|
||||
|
||||
// Check for casts from pointers to integers.
|
||||
if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
|
||||
return CastResult(state, EvalCastL(cast<Loc>(val), castTy));
|
||||
return EvalCastL(cast<Loc>(val), castTy);
|
||||
|
||||
// Check for casts from integers to pointers.
|
||||
if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
|
||||
|
@ -85,10 +83,9 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
|||
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
|
||||
StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
|
||||
R = storeMgr.CastRegion(R, castTy);
|
||||
return R ? CastResult(state, loc::MemRegionVal(R))
|
||||
: CastResult(state, UnknownVal());
|
||||
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
|
||||
}
|
||||
return CastResult(state, LV->getLoc());
|
||||
return LV->getLoc();
|
||||
}
|
||||
goto DispatchCast;
|
||||
}
|
||||
|
@ -96,7 +93,7 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
|||
// Just pass through function and block pointers.
|
||||
if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
|
||||
assert(Loc::IsLocType(castTy));
|
||||
return CastResult(state, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Check for casts from array type to another type.
|
||||
|
@ -107,7 +104,7 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
|||
// Are we casting from an array to a pointer? If so just pass on
|
||||
// the decayed value.
|
||||
if (castTy->isPointerType())
|
||||
return CastResult(state, val);
|
||||
return val;
|
||||
|
||||
// Are we casting from an array to an integer? If so, cast the decayed
|
||||
// pointer value to an integer.
|
||||
|
@ -117,7 +114,7 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
|||
// need the original decayed type.
|
||||
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
|
||||
// QualType pointerTy = C.getPointerType(elemTy);
|
||||
return CastResult(state, EvalCastL(cast<Loc>(val), castTy));
|
||||
return EvalCastL(cast<Loc>(val), castTy);
|
||||
}
|
||||
|
||||
// Check for casts from a region to a specific type.
|
||||
|
@ -150,21 +147,11 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
|
|||
// different type. If the MemRegion* returned is NULL, this expression
|
||||
// evaluates to UnknownVal.
|
||||
R = storeMgr.CastRegion(R, castTy);
|
||||
return R ? CastResult(state, loc::MemRegionVal(R))
|
||||
: CastResult(state, UnknownVal());
|
||||
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
|
||||
}
|
||||
|
||||
DispatchCast:
|
||||
// All other cases.
|
||||
return CastResult(state,
|
||||
isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
|
||||
: EvalCastNL(cast<NonLoc>(val), castTy));
|
||||
}
|
||||
|
||||
SValuator::DefinedOrUnknownCastResult
|
||||
SValuator::EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
|
||||
QualType castTy, QualType originalType) {
|
||||
SValuator::CastResult X = EvalCast((SVal) V, ST, castTy, originalType);
|
||||
return DefinedOrUnknownCastResult(X.getState(),
|
||||
cast<DefinedOrUnknownSVal>(X.getSVal()));
|
||||
return isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
|
||||
: EvalCastNL(cast<NonLoc>(val), castTy);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче