From: Zhongxing Xu Date: Fri, 3 Apr 2009 07:33:13 +0000 (+0000) Subject: This is the first step to gradually remove the use of loc::SymbolVal. Now X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1718c78770db93d1b762620f07728a56786f2ae;p=clang This is the first step to gradually remove the use of loc::SymbolVal. Now when creating symbolic values, we distinguish between location and non-location values. For location values, we create a symbolic region instead of a loc::SymbolVal. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68373 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index 264d8898e2..a3187ea819 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -28,6 +28,7 @@ namespace clang { class CompoundValData; class BasicValueFactory; class MemRegion; +class MemRegionManager; class GRStateManager; class SVal { @@ -72,7 +73,8 @@ public: } /// GetRValueSymbolVal - make a unique symbol for value of R. - static SVal GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R); + static SVal GetRValueSymbolVal(SymbolManager& SymMgr, MemRegionManager& MRMgr, + const MemRegion* R); static SVal GetConjuredSymbolVal(SymbolManager& SymMgr, const Expr *E, unsigned Count); diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 28a5b98fc4..c1efb983c0 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -125,6 +125,9 @@ public: } void print(Store store, std::ostream& Out, const char* nl, const char *sep); + +private: + ASTContext& getContext() { return StateMgr.getContext(); } }; } // end anonymous namespace @@ -273,9 +276,10 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, break; } - // FIXME: Handle SymbolRegions? Shouldn't be possible in - // BasicStoreManager. - assert(!isa(R)); + if (const SymbolicRegion* SR = dyn_cast(R)) { + SymbolRef Sym = SR->getSymbol(); + BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); + } break; } @@ -477,7 +481,7 @@ Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, Store St) { SelfRegion); SVal X = SVal::GetRValueSymbolVal(StateMgr.getSymbolManager(), - IVR); + MRMgr, IVR); St = BindInternal(St, Loc::MakeVal(IVR), X); } @@ -534,7 +538,7 @@ Store BasicStoreManager::getInitialStore() { const MemRegion *R = StateMgr.getRegion(VD); SVal X = (VD->hasGlobalStorage() || isa(VD) || isa(VD)) - ? SVal::GetRValueSymbolVal(StateMgr.getSymbolManager(), R) + ? SVal::GetRValueSymbolVal(StateMgr.getSymbolManager(), MRMgr,R) : UndefinedVal(); St = BindInternal(St, Loc::MakeVal(R), X); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 0e3d3ad2d4..487aac06c5 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1138,7 +1138,7 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred, bool isFeasibleNull = false; GRStateRef StNull = GRStateRef(Assume(state, LV, false, isFeasibleNull), getStateManager()); - + if (isFeasibleNull) { // Use the Generic Data Map to mark in the state what lval was null. @@ -1920,7 +1920,22 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ // to a desugared type. assert(Loc::IsLocType(T)); - assert(Loc::IsLocType(ExTy)); + // We get a symbolic function pointer for a dereference of a function + // pointer, but it is of function type. Example: + + // struct FPRec { + // void (*my_func)(int * x); + // }; + // + // int bar(int x); + // + // int f1_a(struct FPRec* foo) { + // int x; + // (*foo->my_func)(&x); + // return bar(x)+1; // no-warning + // } + + assert(Loc::IsLocType(ExTy) || ExTy->isFunctionType()); const MemRegion* R = RV->getRegion(); StoreManager& StoreMgr = getStoreManager(); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 0b2d99b29b..a126792806 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -360,6 +360,10 @@ SVal RegionStoreManager::getLValueFieldOrIvar(const GRState* St, SVal Base, switch (BaseL.getSubKind()) { case loc::MemRegionKind: BaseR = cast(BaseL).getRegion(); + if (const SymbolicRegion* SR = dyn_cast(BaseR)) { + SymbolRef Sym = SR->getSymbol(); + BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); + } break; case loc::SymbolValKind: { @@ -412,13 +416,20 @@ SVal RegionStoreManager::getLValueElement(const GRState* St, const TypedRegion* BaseRegion = 0; if (isa(Base)) { + // FIXME: This case will be removed. SymbolRef Sym = cast(Base).getSymbol(); SymbolicRegion* SR = MRMgr.getSymbolicRegion(Sym); // Layer the type information. BaseRegion = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); - } - else - BaseRegion = cast(cast(Base).getRegion()); + } else { + const MemRegion* R = cast(Base).getRegion(); + if (const SymbolicRegion* SR = dyn_cast(R)) { + SymbolRef Sym = SR->getSymbol(); + BaseRegion = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); + } + else + BaseRegion = cast(R); + } // Pointer of any type can be cast and used as array base. const ElementRegion *ElemR = dyn_cast(BaseRegion); @@ -617,8 +628,11 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) { if (!isa(L)) return UnknownVal(); - const TypedRegion* TR - = cast(cast(L).getRegion()); + const MemRegion* MR = cast(L).getRegion(); + if (isa(MR)) + return UnknownVal(); + + const TypedRegion* TR = cast(MR); const ElementRegion* ER = dyn_cast(TR); @@ -683,10 +697,17 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { if (isa(L)) return L; + const MemRegion* MR = cast(L).getRegion(); + + // We return unknown for symbolic region for now. This might be improved. + // Example: + // void f(int* p) { int x = *p; } + if (isa(MR)) + return UnknownVal(); + // FIXME: Perhaps this method should just take a 'const MemRegion*' argument // instead of 'Loc', and have the other Loc cases handled at a higher level. - const TypedRegion* R - = cast(cast(L).getRegion()); + const TypedRegion* R = cast(MR); assert(R && "bad region"); // FIXME: We should eventually handle funny addressing. e.g.: @@ -735,7 +756,7 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { if (SR == SelfRegion) { // FIXME: Do we need to handle the case where the super region // has a view? We want to canonicalize the bindings. - return SVal::GetRValueSymbolVal(getSymbolManager(), R); + return SVal::GetRValueSymbolVal(getSymbolManager(), MRMgr, R); } // Otherwise, we need a new symbol. For now return Unknown. @@ -757,7 +778,7 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { VD->hasGlobalStorage()) { QualType VTy = VD->getType(); if (Loc::IsLocType(VTy) || VTy->isIntegerType()) - return SVal::GetRValueSymbolVal(getSymbolManager(), VR); + return SVal::GetRValueSymbolVal(getSymbolManager(), MRMgr, VR); else return UnknownVal(); } @@ -773,7 +794,7 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { // All other integer values are symbolic. if (Loc::IsLocType(RTy) || RTy->isIntegerType()) - return SVal::GetRValueSymbolVal(getSymbolManager(), R); + return SVal::GetRValueSymbolVal(getSymbolManager(), MRMgr, R); else return UnknownVal(); } @@ -811,7 +832,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){ if (MRMgr.onStack(FR) || MRMgr.onHeap(FR)) FieldValue = UndefinedVal(); else - FieldValue = SVal::GetRValueSymbolVal(getSymbolManager(), FR); + FieldValue = SVal::GetRValueSymbolVal(getSymbolManager(), MRMgr, FR); } StructVal = getBasicVals().consVals(FieldValue, StructVal); diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index 850e65e3b6..b642857c50 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -264,14 +264,15 @@ NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList Vals, return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); } -SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R) { +SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, MemRegionManager& MRMgr, + const MemRegion* R) { SymbolRef sym = SymMgr.getRegionRValueSymbol(R); if (const TypedRegion* TR = dyn_cast(R)) { QualType T = TR->getRValueType(SymMgr.getContext()); if (Loc::IsLocType(T)) - return Loc::MakeVal(sym); + return Loc::MakeVal(MRMgr.getSymbolicRegion(sym)); // Only handle integers for now. if (T->isIntegerType())