From 313b6dab9efcce465b68da0fed7bf422b6e5c375 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Mon, 6 Jul 2009 06:01:24 +0000 Subject: [PATCH] Further cleanup of region invalidation code. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74816 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathSensitive/Store.h | 2 +- lib/Analysis/CFRefCount.cpp | 86 +++++++++----------- lib/Analysis/Store.cpp | 25 ++++-- 3 files changed, 58 insertions(+), 55 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 1070e11a9b..40c01b46e8 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -157,7 +157,7 @@ public: virtual const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl *vd) = 0; - const GRState *InvalidateRegion(const GRState *state, const TypedRegion *R, + const GRState *InvalidateRegion(const GRState *state, const MemRegion *R, const Expr *E, unsigned Count); // FIXME: Make out-of-line. virtual const GRState *setExtent(const GRState *state, diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index a96281a5e9..c8919c38cb 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -2757,10 +2757,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, ExplodedNode* Pred) { // Get the state. - GRStateManager& StateMgr = Eng.getStateManager(); const GRState *state = Builder.GetState(Pred); - ASTContext& Ctx = StateMgr.getContext(); - ValueManager &ValMgr = Eng.getValueManager(); // Evaluate the effect of the arguments. RefVal::Kind hasErr = (RefVal::Kind) 0; @@ -2796,59 +2793,54 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, // expression (the context) and the expression itself. This should // disambiguate conjured symbols. unsigned Count = Builder.getCurrentBlockCount(); - const TypedRegion* R = dyn_cast(MR->getRegion()); - StoreManager& StoreMgr = - Eng.getStateManager().getStoreManager(); - if (R) { - // Are we dealing with an ElementRegion? If the element type is - // a basic integer type (e.g., char, int) and the underying region - // is a variable region then strip off the ElementRegion. - // FIXME: We really need to think about this for the general case - // as sometimes we are reasoning about arrays and other times - // about (char*), etc., is just a form of passing raw bytes. - // e.g., void *p = alloca(); foo((char*)p); - if (const ElementRegion *ER = dyn_cast(R)) { - // Checking for 'integral type' is probably too promiscuous, but - // we'll leave it in for now until we have a systematic way of - // handling all of these cases. Eventually we need to come up - // with an interface to StoreManager so that this logic can be - // approriately delegated to the respective StoreManagers while - // still allowing us to do checker-specific logic (e.g., - // invalidating reference counts), probably via callbacks. - if (ER->getElementType()->isIntegralType()) { - const MemRegion *superReg = ER->getSuperRegion(); - if (isa(superReg) || isa(superReg) || - isa(superReg)) - R = cast(superReg); - } - - // FIXME: What about layers of ElementRegions? + StoreManager& StoreMgr = Eng.getStateManager().getStoreManager(); + + const MemRegion *R = MR->getRegion(); + // Are we dealing with an ElementRegion? If the element type is + // a basic integer type (e.g., char, int) and the underying region + // is a variable region then strip off the ElementRegion. + // FIXME: We really need to think about this for the general case + // as sometimes we are reasoning about arrays and other times + // about (char*), etc., is just a form of passing raw bytes. + // e.g., void *p = alloca(); foo((char*)p); + if (const ElementRegion *ER = dyn_cast(R)) { + // Checking for 'integral type' is probably too promiscuous, but + // we'll leave it in for now until we have a systematic way of + // handling all of these cases. Eventually we need to come up + // with an interface to StoreManager so that this logic can be + // approriately delegated to the respective StoreManagers while + // still allowing us to do checker-specific logic (e.g., + // invalidating reference counts), probably via callbacks. + if (ER->getElementType()->isIntegralType()) { + const MemRegion *superReg = ER->getSuperRegion(); + if (isa(superReg) || isa(superReg) || + isa(superReg)) + R = cast(superReg); } - - // Is the invalidated variable something that we were tracking? - SymbolRef Sym = state->getSValAsScalarOrLoc(R).getAsLocSymbol(); - - // Remove any existing reference-count binding. - if (Sym) state = state->remove(Sym); - - state = StoreMgr.InvalidateRegion(state, R, *I, Count); - } - else if (isa(MR->getRegion())) { - // Invalidate the alloca region by setting its default value to - // conjured symbol. The type of the symbol is irrelavant. - SVal V = ValMgr.getConjuredSymbolVal(*I, Eng.getContext().IntTy, - Count); - state = StoreMgr.setDefaultValue(state, MR->getRegion(), V); + // FIXME: What about layers of ElementRegions? } - else - state = state->bindLoc(*MR, UnknownVal()); + + // Is the invalidated variable something that we were tracking? + SymbolRef Sym = state->getSValAsScalarOrLoc(R).getAsLocSymbol(); + + // Remove any existing reference-count binding. + if (Sym) + state = state->remove(Sym); + + state = StoreMgr.InvalidateRegion(state, R, *I, Count); } else { // Nuke all other arguments passed by reference. + // FIXME: is this necessary or correct? unbind only removes the binding. + // We should bind it to UnknownVal explicitly. Otherwise default value + // may be loaded. state = state->unbindLoc(cast(V)); } } else if (isa(V)) + // FIXME: is this necessary or correct? unbind only removes the binding. + // We should bind it to UnknownVal explicitly. Otherwise default value + // may be loaded. state = state->unbindLoc(cast(V).getLoc()); } diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index c836de9940..deb546ae6a 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -111,17 +111,28 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R, } const GRState *StoreManager::InvalidateRegion(const GRState *state, - const TypedRegion *R, + const MemRegion *R, const Expr *E, unsigned Count) { + ASTContext& Ctx = StateMgr.getContext(); + if (!R->isBoundable()) return state; - ASTContext& Ctx = StateMgr.getContext(); - QualType T = R->getValueType(Ctx); + if (isa(R) || isa(R)) { + // Invalidate the alloca region by setting its default value to + // conjured symbol. The type of the symbol is irrelavant. + SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count); + state = setDefaultValue(state, R, V); + return state; + } + + const TypedRegion *TR = cast(R); + + QualType T = TR->getValueType(Ctx); if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { SVal V = ValMgr.getConjuredSymbolVal(E, T, Count); - return Bind(state, ValMgr.makeLoc(R), V); + return Bind(state, ValMgr.makeLoc(TR), V); } else if (const RecordType *RT = T->getAsStructureType()) { // FIXME: handle structs with default region value. @@ -138,7 +149,7 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state, // For now just handle scalar fields. FieldDecl *FD = *FI; QualType FT = FD->getType(); - const FieldRegion* FR = MRMgr.getFieldRegion(FD, R); + const FieldRegion* FR = MRMgr.getFieldRegion(FD, TR); if (Loc::IsLocType(FT) || (FT->isIntegerType() && FT->isScalarType())) { @@ -158,10 +169,10 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state, // Set the default value of the array to conjured symbol. SVal V = ValMgr.getConjuredSymbolVal(E, AT->getElementType(), Count); - state = setDefaultValue(state, R, V); + state = setDefaultValue(state, TR, V); } else { // Just blast away other values. - state = Bind(state, ValMgr.makeLoc(R), UnknownVal()); + state = Bind(state, ValMgr.makeLoc(TR), UnknownVal()); } return state; -- 2.40.0