From: Ted Kremenek Date: Fri, 24 Oct 2008 20:32:16 +0000 (+0000) Subject: Added method "getSelfRegion" to Store. This method returns the region associated... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9deb0e35dea0f82691fadb60b61f45887ba67aba;p=clang Added method "getSelfRegion" to Store. This method returns the region associated with the "this" or "self" object (C++ and Objective-C respectively). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58107 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 95a439e636..b599301c17 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -266,6 +266,9 @@ private: /// cfg - The CFG for the analyzed function/method. CFG& cfg; + + /// codedecl - The Decl representing the function/method being analyzed. + const Decl& codedecl; /// TF - Object that represents a bundle of transfer functions /// for manipulating and creating SVals. @@ -294,7 +297,8 @@ public: GRStateManager(ASTContext& Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, - llvm::BumpPtrAllocator& alloc, CFG& c, LiveVariables& L) + llvm::BumpPtrAllocator& alloc, CFG& c, + const Decl& cd, LiveVariables& L) : EnvMgr(alloc), ISetFactory(alloc), GDMFactory(alloc), @@ -302,6 +306,7 @@ public: SymMgr(alloc), Alloc(alloc), cfg(c), + codedecl(cd), Liveness(L) { StoreMgr.reset((*CreateStoreManager)(*this)); ConstraintMgr.reset((*CreateConstraintManager)(*this)); @@ -312,6 +317,7 @@ public: const GRState* getInitialState(); ASTContext& getContext() { return BasicVals.getContext(); } + const Decl& getCodeDecl() { return codedecl; } BasicValueFactory& getBasicVals() { return BasicVals; } const BasicValueFactory& getBasicVals() const { return BasicVals; } SymbolManager& getSymbolManager() { return SymMgr; } @@ -341,6 +347,10 @@ public: return getRegionManager().getVarRegion(D); } + const MemRegion* getSelfRegion(const GRState* state) { + return StoreMgr->getSelfRegion(state->getStore()); + } + // Get the lvalue for a variable reference. SVal GetLValue(const GRState* St, const VarDecl* D) { return StoreMgr->getLValueVar(St, D); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 5e3fa8df69..aa3b5e791b 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -61,7 +61,15 @@ public: virtual SVal getLValueElement(const GRState* St, SVal Base, SVal Offset) = 0; + + /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit + /// conversions between arrays and pointers. virtual SVal ArrayToPointer(SVal Array) = 0; + + /// getSelfRegion - Returns the region for the 'self' (Objective-C) or + /// 'this' object (C++). When used when analyzing a normal function this + /// method returns NULL. + virtual const MemRegion* getSelfRegion(Store store) = 0; virtual Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index 96a7ea1c16..033dc02cd7 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -508,7 +508,7 @@ bool AuditCFNumberCreate::Audit(ExplodedNode* N,GRStateManager&){ return false; - QualType T = Ctx.getCanonicalType(R->getType()); + QualType T = Ctx.getCanonicalType(R->getType(Ctx)); // FIXME: If the pointee isn't an integer type, should we flag a warning? // People can do weird stuff with pointers. diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 70631ac5bf..e12b9ea0a1 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -27,20 +27,19 @@ class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { VarBindingsTy::Factory VBFactory; GRStateManager& StateMgr; MemRegionManager MRMgr; + const MemRegion* SelfRegion; public: BasicStoreManager(GRStateManager& mgr) - : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {} + : StateMgr(mgr), MRMgr(StateMgr.getAllocator()), SelfRegion(0) {} - virtual ~BasicStoreManager() {} + ~BasicStoreManager() {} - virtual SVal Retrieve(Store St, Loc LV, QualType T); - virtual Store Bind(Store St, Loc LV, SVal V); - virtual Store Remove(Store St, Loc LV); - - virtual Store getInitialStore(); - - virtual MemRegionManager& getRegionManager() { return MRMgr; } + SVal Retrieve(Store St, Loc LV, QualType T); + Store Bind(Store St, Loc LV, SVal V); + Store Remove(Store St, Loc LV); + Store getInitialStore(); + MemRegionManager& getRegionManager() { return MRMgr; } // FIXME: Investigate what is using this. This method should be removed. virtual Loc getLoc(const VarDecl* VD) { @@ -52,26 +51,31 @@ public: SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D); SVal getLValueElement(const GRState* St, SVal Base, SVal Offset); + /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit + /// conversions between arrays and pointers. SVal ArrayToPointer(SVal Array) { return Array; } - virtual Store - RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, - llvm::SmallVectorImpl& RegionRoots, - LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols); + /// getSelfRegion - Returns the region for the 'self' (Objective-C) or + /// 'this' object (C++). When used when analyzing a normal function this + /// method returns NULL. + const MemRegion* getSelfRegion(Store) { + return SelfRegion; + } + + Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, + llvm::SmallVectorImpl& RegionRoots, + LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols); - virtual void iterBindings(Store store, BindingsHandler& f); + void iterBindings(Store store, BindingsHandler& f); - virtual Store AddDecl(Store store, - const VarDecl* VD, Expr* Ex, - SVal InitVal = UndefinedVal(), unsigned Count = 0); + Store AddDecl(Store store, const VarDecl* VD, Expr* Ex, + SVal InitVal = UndefinedVal(), unsigned Count = 0); static inline VarBindingsTy GetVarBindings(Store store) { return VarBindingsTy(static_cast(store)); } - virtual void print(Store store, std::ostream& Out, - const char* nl, const char *sep); - + void print(Store store, std::ostream& Out, const char* nl, const char *sep); }; } // end anonymous namespace @@ -291,6 +295,7 @@ BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc, } Store BasicStoreManager::getInitialStore() { + // The LiveVariables information already has a compilation of all VarDecls // used in the function. Iterate through this set, and "symbolicate" // any VarDecl whose value originally comes from outside the function. @@ -303,7 +308,22 @@ Store BasicStoreManager::getInitialStore() { for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) { NamedDecl* ND = const_cast(I->first); - if (VarDecl* VD = dyn_cast(ND)) { + // Handle implicit parameters. + if (ImplicitParamDecl* PD = dyn_cast(ND)) { + const Decl& CD = StateMgr.getCodeDecl(); + if (const ObjCMethodDecl* MD = dyn_cast(&CD)) { + if (MD->getSelfDecl() == PD) { + // Create a region for "self". + assert (SelfRegion == 0); + SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(), + MRMgr.getHeapRegion()); + + St = Bind(St, loc::MemRegionVal(MRMgr.getVarRegion(PD)), + loc::MemRegionVal(SelfRegion)); + } + } + } + else if (VarDecl* VD = dyn_cast(ND)) { // Punt on static variables for now. if (VD->getStorageClass() == VarDecl::Static) continue; diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 996fea9f63..acfd7a1993 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -122,7 +122,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, Liveness(L), Builder(NULL), StateMgr(G.getContext(), SMC, - CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L), + CreateBasicConstraintManager, G.getAllocator(), cfg, CD, L), SymMgr(StateMgr.getSymbolManager()), CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 5c75ab369e..e2b6b13e64 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -66,6 +66,14 @@ public: } Store getInitialStore(); + + /// getSelfRegion - Returns the region for the 'self' (Objective-C) or + /// 'this' object (C++). When used when analyzing a normal function this + /// method returns NULL. + const MemRegion* getSelfRegion(Store) { + assert (false && "Not implemented."); + return 0; + } Store RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live, llvm::SmallVectorImpl& RegionRoots,