From 814e6b915450456eb2a1ba15d82fc7f8ae3bc8a6 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Thu, 4 Feb 2010 04:56:43 +0000 Subject: [PATCH] Cast evaluation no longer touch GRState. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95290 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/Checker/PathSensitive/SValuator.h | 27 +----------- lib/Checker/AdjustedReturnValueChecker.cpp | 5 ++- lib/Checker/GRExprEngine.cpp | 17 ++++---- lib/Checker/OSAtomicChecker.cpp | 3 +- lib/Checker/RegionStore.cpp | 5 +-- lib/Checker/SValuator.cpp | 41 +++++++------------ 6 files changed, 28 insertions(+), 70 deletions(-) diff --git a/include/clang/Checker/PathSensitive/SValuator.h b/include/clang/Checker/PathSensitive/SValuator.h index 74abe67912..9beb8cb086 100644 --- a/include/clang/Checker/PathSensitive/SValuator.h +++ b/include/clang/Checker/PathSensitive/SValuator.h @@ -38,33 +38,8 @@ public: SValuator(ValueManager &valMgr) : ValMgr(valMgr) {} virtual ~SValuator() {} - template - class GenericCastResult : public std::pair { - public: - const GRState *getState() const { return this->first; } - T getSVal() const { return this->second; } - GenericCastResult(const GRState *s, T v) - : std::pair(s, v) {} - }; + SVal EvalCast(SVal V, QualType castTy, QualType originalType); - class CastResult : public GenericCastResult { - public: - CastResult(const GRState *s, SVal v) : GenericCastResult(s, v) {} - }; - - class DefinedOrUnknownCastResult : - public GenericCastResult { - public: - DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v) - : GenericCastResult(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; diff --git a/lib/Checker/AdjustedReturnValueChecker.cpp b/lib/Checker/AdjustedReturnValueChecker.cpp index 483b41b6bd..e95a86b838 100644 --- a/lib/Checker/AdjustedReturnValueChecker.cpp +++ b/lib/Checker/AdjustedReturnValueChecker.cpp @@ -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)); } } diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 1e16bde5f1..978be8dc64 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -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), diff --git a/lib/Checker/OSAtomicChecker.cpp b/lib/Checker/OSAtomicChecker.cpp index f84388a755..7f4aeca331 100644 --- a/lib/Checker/OSAtomicChecker.cpp +++ b/lib/Checker/OSAtomicChecker.cpp @@ -153,8 +153,7 @@ bool OSAtomicChecker::EvalOSAtomicCompareAndSwap(CheckerContext &C, // Handle implicit value casts. if (const TypedRegion *R = dyn_cast_or_null(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(theValueExpr), N, diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index c350894036..25e8059d26 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -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. diff --git a/lib/Checker/SValuator.cpp b/lib/Checker/SValuator.cpp index fd2bbd06fb..542fc1b107 100644 --- a/lib/Checker/SValuator.cpp +++ b/lib/Checker/SValuator.cpp @@ -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(val), castTy)); + return EvalCastNL(cast(val), castTy); // Check for casts from pointers to integers. if (castTy->isIntegerType() && Loc::IsLocType(originalTy)) - return CastResult(state, EvalCastL(cast(val), castTy)); + return EvalCastL(cast(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(originalTy)->getElementType(); // QualType pointerTy = C.getPointerType(elemTy); - return CastResult(state, EvalCastL(cast(val), castTy)); + return EvalCastL(cast(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(val) ? EvalCastL(cast(val), castTy) - : EvalCastNL(cast(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(X.getSVal())); + return isa(val) ? EvalCastL(cast(val), castTy) + : EvalCastNL(cast(val), castTy); }