From: Zhongxing Xu Date: Thu, 5 Feb 2009 06:57:29 +0000 (+0000) Subject: Make SymbolicRegion subclass TypedRegion, for symbols usually have types, so X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=026c66395b88a09437319139a43b090093f7e1dd;p=clang Make SymbolicRegion subclass TypedRegion, for symbols usually have types, so do the symblic regions associated with them and we need them to be typed. Current SymbolicRegion::getRValueType() method is very restricting. It may be modified when we are more clear about what could be the types of symblic regions. BasicConstraintManager::Assume() is changed due to that now SymblicRegion is a subclass of SubRegion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63844 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 8a62eff7a9..ba08e38387 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -38,10 +38,11 @@ class MemRegionManager; /// MemRegion - The root abstract class for all memory regions. class MemRegion : public llvm::FoldingSetNode { public: - enum Kind { MemSpaceRegionKind, SymbolicRegionKind, + enum Kind { MemSpaceRegionKind, AllocaRegionKind, // Typed regions. BEG_TYPED_REGIONS, + SymbolicRegionKind, CompoundLiteralRegionKind, StringRegionKind, ElementRegionKind, AnonTypedRegionKind, @@ -103,7 +104,7 @@ public: bool isSubRegionOf(const MemRegion* R) const; static bool classof(const MemRegion* R) { - return R->getKind() > SymbolicRegionKind; + return R->getKind() > MemSpaceRegionKind; } }; @@ -135,32 +136,6 @@ public: } }; -/// SymbolicRegion - A special, "non-concrete" region. Unlike other region -/// clases, SymbolicRegion represents a region that serves as an alias for -/// either a real region, a NULL pointer, etc. It essentially is used to -/// map the concept of symbolic values into the domain of regions. Symbolic -/// regions do not need to be typed. -class SymbolicRegion : public MemRegion { -protected: - const SymbolRef sym; - -public: - SymbolicRegion(const SymbolRef s) : MemRegion(SymbolicRegionKind), sym(s) {} - - SymbolRef getSymbol() const { - return sym; - } - - void Profile(llvm::FoldingSetNodeID& ID) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym); - - void print(llvm::raw_ostream& os) const; - - static bool classof(const MemRegion* R) { - return R->getKind() == SymbolicRegionKind; - } -}; - /// TypedRegion - An abstract class representing regions that are typed. class TypedRegion : public SubRegion { protected: @@ -188,6 +163,37 @@ public: } }; +/// SymbolicRegion - A special, "non-concrete" region. Unlike other region +/// clases, SymbolicRegion represents a region that serves as an alias for +/// either a real region, a NULL pointer, etc. It essentially is used to +/// map the concept of symbolic values into the domain of regions. Symbolic +/// regions do not need to be typed. +class SymbolicRegion : public TypedRegion { +protected: + const SymbolRef sym; + const SymbolManager& SymMgr; + +public: + SymbolicRegion(const SymbolRef s, const SymbolManager& mgr, MemRegion* sreg) + : TypedRegion(sreg, SymbolicRegionKind), sym(s), SymMgr(mgr) {} + + SymbolRef getSymbol() const { + return sym; + } + + QualType getRValueType(ASTContext& C) const; + + void Profile(llvm::FoldingSetNodeID& ID) const; + + static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym); + + void print(llvm::raw_ostream& os) const; + + static bool classof(const MemRegion* R) { + return R->getKind() == SymbolicRegionKind; + } +}; + /// StringRegion - Region associated with a StringLiteral. class StringRegion : public TypedRegion { friend class MemRegionManager; @@ -492,7 +498,7 @@ public: getCompoundLiteralRegion(const CompoundLiteralExpr* CL); /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. - SymbolicRegion* getSymbolicRegion(const SymbolRef sym); + SymbolicRegion* getSymbolicRegion(const SymbolRef sym, const SymbolManager&); StringRegion* getStringRegion(const StringLiteral* Str); diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp index 0c98bf6450..58c4727d51 100644 --- a/lib/Analysis/BasicConstraintManager.cpp +++ b/lib/Analysis/BasicConstraintManager.cpp @@ -165,17 +165,14 @@ const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond, // FIXME: Should this go into the storemanager? const MemRegion* R = cast(Cond).getRegion(); - - while (R) { - if (const SubRegion* SubR = dyn_cast(R)) { - R = SubR->getSuperRegion(); - continue; - } - else if (const SymbolicRegion* SymR = dyn_cast(R)) + const SubRegion* SubR = dyn_cast(R); + + while (SubR) { + // FIXME: now we only find the first symbolic region. + if (const SymbolicRegion* SymR = dyn_cast(SubR)) return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption, isFeasible); - - break; + SubR = dyn_cast(SubR->getSuperRegion()); } // FALL-THROUGH. diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 2feea594b8..ad542b884a 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -173,7 +173,8 @@ SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, switch(BaseL.getSubKind()) { case loc::SymbolValKind: - BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol()); + BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol(), + StateMgr.getSymbolManager()); break; case loc::GotoLabelKind: @@ -218,7 +219,8 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, // Create a region to represent this symbol. // FIXME: In the future we may just use symbolic regions instead of // SymbolVals to reason about symbolic memory chunks. - const MemRegion* SymR = MRMgr.getSymbolicRegion(Sym); + const MemRegion* SymR = MRMgr.getSymbolicRegion(Sym, + StateMgr.getSymbolManager()); // Layered a typed region on top of this. QualType T = StateMgr.getSymbolManager().getType(Sym); BaseR = MRMgr.getAnonTypedRegion(T, SymR); diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 82f4423541..e41c5f937b 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -107,6 +107,28 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { ElementRegion::ProfileRegion(ID, Index, superRegion); } +//===----------------------------------------------------------------------===// +// getLValueType() and getRValueType() +//===----------------------------------------------------------------------===// + +QualType SymbolicRegion::getRValueType(ASTContext& C) const { + const SymbolData& data = SymMgr.getSymbolData(sym); + + // FIXME: We could use the SymbolManager::getType() directly. But that + // would hide the assumptions we made here. What is the type of a symbolic + // region is unclear for other cases. + + // For now we assume the symbol is a typed region rvalue. + const TypedRegion* R + = cast(cast(data).getRegion()); + + // Assume the region rvalue has a pointer type, only then we could have a + // symbolic region associated with it. + PointerType* PTy = cast(R->getRValueType(C).getTypePtr()); + + return PTy->getPointeeType(); +} + QualType ElementRegion::getRValueType(ASTContext& C) const { // Strip off typedefs from the ArrayRegion's RvalueType. QualType T = getArrayRegion()->getRValueType(C)->getDesugaredType(); @@ -119,10 +141,6 @@ QualType ElementRegion::getRValueType(ASTContext& C) const { return T; } -//===----------------------------------------------------------------------===// -// getLValueType() and getRValueType() -//===----------------------------------------------------------------------===// - QualType StringRegion::getRValueType(ASTContext& C) const { return Str->getType(); } @@ -308,7 +326,8 @@ MemRegionManager::getElementRegion(SVal Idx, const TypedRegion* superRegion){ } /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. -SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym) { +SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym, + const SymbolManager& mgr) { llvm::FoldingSetNodeID ID; SymbolicRegion::ProfileRegion(ID, sym); @@ -319,7 +338,8 @@ SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym) { if (!R) { R = (SymbolicRegion*) A.Allocate(); - new (R) SymbolicRegion(sym); + // SymbolicRegion's storage class is usually unknown. + new (R) SymbolicRegion(sym, mgr, getUnknownRegion()); Regions.InsertNode(R, InsertPos); } diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 8d36d10a8a..e640087acb 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -312,7 +312,8 @@ SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base, break; case loc::SymbolValKind: - BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol()); + BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol(), + StateMgr.getSymbolManager()); break; case loc::GotoLabelKind: @@ -701,7 +702,8 @@ Store RegionStoreManager::Remove(Store store, Loc L) { if (isa(L)) R = cast(L).getRegion(); else if (isa(L)) - R = MRMgr.getSymbolicRegion(cast(L).getSymbol()); + R = MRMgr.getSymbolicRegion(cast(L).getSymbol(), + StateMgr.getSymbolManager()); if (R) { RegionBindingsTy B = GetRegionBindings(store);