From: Ted Kremenek Date: Thu, 22 Jan 2009 23:43:57 +0000 (+0000) Subject: Add RegionStore support for the implicit object region that 'self' references. This... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6fd8f914d399035e1417d9e548d3a8d598195370;p=clang Add RegionStore support for the implicit object region that 'self' references. This causes tests 'ObjCProperties.m' and 'refcnt_naming.m' to now pass with RegionStore. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 6f0ec1d0b7..ec801d47f2 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -110,13 +110,19 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager { RegionViews::Factory RVFactory; GRStateManager& StateMgr; + const MemRegion* SelfRegion; + const ImplicitParamDecl *SelfDecl; public: RegionStoreManager(GRStateManager& mgr) : StoreManager(mgr.getAllocator()), RBFactory(mgr.getAllocator()), RVFactory(mgr.getAllocator()), - StateMgr(mgr) {} + StateMgr(mgr), SelfRegion(0), SelfDecl(0) { + if (const ObjCMethodDecl* MD = + dyn_cast(&StateMgr.getCodeDecl())) + SelfDecl = MD->getSelfDecl(); + } virtual ~RegionStoreManager() {} @@ -187,8 +193,16 @@ public: /// 'this' object (C++). When used when analyzing a normal function this /// method returns NULL. const MemRegion* getSelfRegion(Store) { - assert (false && "Not implemented."); - return 0; + if (!SelfDecl) + return 0; + + if (!SelfRegion) { + const ObjCMethodDecl *MD = cast(&StateMgr.getCodeDecl()); + SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(), + MRMgr.getHeapRegion()); + } + + return SelfRegion; } /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values. @@ -563,9 +577,14 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { // function/method. These are either symbolic values or 'undefined'. // We treat function parameters as symbolic values. - if (const VarRegion* VR = dyn_cast(R)) - if (isa(VR->getDecl())) + if (const VarRegion* VR = dyn_cast(R)) { + const VarDecl *VD = VR->getDecl(); + + if (isa(VD)) return SVal::GetRValueSymbolVal(getSymbolManager(), VR); + else if (VD == SelfDecl) + return loc::MemRegionVal(getSelfRegion(0)); + } if (MRMgr.onStack(R) || MRMgr.onHeap(R)) { // All stack variables are considered to have undefined values diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m index f2f18b5771..7ce434fbfa 100644 --- a/test/Analysis/ObjCProperties.m +++ b/test/Analysis/ObjCProperties.m @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple %s -verify +// RUN: clang -analyze -checker-simple %s -verify && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic %s -verify && +// RUN: clang -analyze -checker-cfref -analyzer-store-region %s -verify // The point of this test cases is to exercise properties in the static // analyzer diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m index 3c86853b47..44ccf27a56 100644 --- a/test/Analysis/refcnt_naming.m +++ b/test/Analysis/refcnt_naming.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s typedef const struct __CFString * CFStringRef; typedef const struct __CFAllocator * CFAllocatorRef;