summaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/AnalysisContext.cpp7
-rw-r--r--lib/Analysis/BasicStore.cpp47
-rw-r--r--lib/Analysis/CFRefCount.cpp20
-rw-r--r--lib/Analysis/MemRegion.cpp11
-rw-r--r--lib/Analysis/RegionStore.cpp39
5 files changed, 48 insertions, 76 deletions
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index 996d5c879a..324fdf2dce 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -37,6 +37,13 @@ Stmt *AnalysisContext::getBody() {
llvm::llvm_unreachable("unknown code decl");
}
+const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return MD->getSelfDecl();
+
+ return NULL;
+}
+
CFG *AnalysisContext::getCFG() {
if (!cfg)
cfg = CFG::buildCFG(getBody(), &D->getASTContext());
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 65efb66148..50b90f5813 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -36,11 +36,9 @@ public:
class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
BindingsTy::Factory VBFactory;
- const MemRegion* SelfRegion;
-
public:
BasicStoreManager(GRStateManager& mgr)
- : StoreManager(mgr), VBFactory(mgr.getAllocator()), SelfRegion(0) {}
+ : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
~BasicStoreManager() {}
@@ -58,7 +56,8 @@ public:
return state->makeWithStore(BindInternal(state->getStore(), L, V));
}
- Store scanForIvars(Stmt *B, const Decl* SelfDecl, Store St);
+ Store scanForIvars(Stmt *B, const Decl* SelfDecl,
+ const MemRegion *SelfRegion, Store St);
Store BindInternal(Store St, Loc loc, SVal V);
Store Remove(Store St, Loc loc);
@@ -88,11 +87,6 @@ public:
/// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
SVal ArrayToPointer(Loc Array) { return Array; }
-
- /// 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; }
/// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
/// It updatees the GRState object in place with the values removed.
@@ -148,7 +142,8 @@ SVal BasicStoreManager::getLValueCompoundLiteral(const GRState *state,
return ValMgr.makeLoc(MRMgr.getCompoundLiteralRegion(CL));
}
-SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl* D,
+SVal BasicStoreManager::getLValueIvar(const GRState *state,
+ const ObjCIvarDecl* D,
SVal Base) {
if (Base.isUnknownOrUndef())
@@ -158,9 +153,7 @@ SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl*
if (isa<loc::MemRegionVal>(BaseL)) {
const MemRegion *BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
-
- if (BaseR == SelfRegion)
- return ValMgr.makeLoc(MRMgr.getObjCIvarRegion(D, BaseR));
+ return ValMgr.makeLoc(MRMgr.getObjCIvarRegion(D, BaseR));
}
return UnknownVal();
@@ -343,12 +336,7 @@ Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
return store;
-
- // We only track bindings to self.ivar.
- if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
- if (IVR->getSuperRegion() != SelfRegion)
- return store;
-
+
if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
// Only convert 'V' to a location iff the underlying region type
// is a location as well.
@@ -468,7 +456,8 @@ BasicStoreManager::RemoveDeadBindings(GRState &state, Stmt* Loc,
state.setStore(store);
}
-Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, Store St) {
+Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl,
+ const MemRegion *SelfRegion, Store St) {
for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end();
CI != CE; ++CI) {
@@ -489,7 +478,7 @@ Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, Store St) {
}
}
else
- St = scanForIvars(*CI, SelfDecl, St);
+ St = scanForIvars(*CI, SelfDecl, SelfRegion, St);
}
return St;
@@ -511,17 +500,18 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
const Decl& CD = *InitLoc->getDecl();
if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
if (MD->getSelfDecl() == PD) {
- // Create a region for "self".
- assert (SelfRegion == 0);
- SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
- MRMgr.getHeapRegion());
+ // FIXME: Just use a symbolic region, and remove ObjCObjectRegion
+ // entirely.
+ const ObjCObjectRegion *SelfRegion =
+ MRMgr.getObjCObjectRegion(MD->getClassInterface(),
+ MRMgr.getHeapRegion());
St = BindInternal(St, ValMgr.makeLoc(MRMgr.getVarRegion(PD, InitLoc)),
ValMgr.makeLoc(SelfRegion));
// Scan the method for ivar references. While this requires an
// entire AST scan, the cost should not be high in practice.
- St = scanForIvars(MD->getBody(), PD, St);
+ St = scanForIvars(MD->getBody(), PD, SelfRegion, St);
}
}
}
@@ -641,11 +631,6 @@ const GRState *BasicStoreManager::InvalidateRegion(const GRState *state,
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
return state;
- // We only track bindings to self.ivar.
- if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
- if (IVR->getSuperRegion() != SelfRegion)
- return state;
-
QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
return Bind(state, loc::MemRegionVal(R), V);
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 1b7a746f26..d1f293e40c 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -3028,13 +3028,19 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
if (isa<ObjCMethodDecl>(&Eng.getGraph().getCodeDecl())) {
if (Expr* Receiver = ME->getReceiver()) {
SVal X = St->getSValAsScalarOrLoc(Receiver);
- if (loc::MemRegionVal* L = dyn_cast<loc::MemRegionVal>(&X))
- if (L->getBaseRegion() == St->getSelfRegion()) {
- // Update the summary to make the default argument effect
- // 'StopTracking'.
- Summ = Summaries.copySummary(Summ);
- Summ->setDefaultArgEffect(StopTracking);
- }
+ if (loc::MemRegionVal* L = dyn_cast<loc::MemRegionVal>(&X)) {
+ // Get the region associated with 'self'.
+ const LocationContext *LC = Pred->getLocationContext();
+ if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl()) {
+ SVal SelfVal = St->getSVal(St->getRegion(SelfDecl, LC));
+ if (L->getBaseRegion() == SelfVal.getAsRegion()) {
+ // Update the summary to make the default argument effect
+ // 'StopTracking'.
+ Summ = Summaries.copySummary(Summ);
+ Summ->setDefaultArgEffect(StopTracking);
+ }
+ }
+ }
}
}
}
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 2aacbf9065..ed53922655 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/raw_ostream.h"
#include "clang/Analysis/PathSensitive/MemRegion.h"
#include "clang/Analysis/PathSensitive/ValueManager.h"
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
using namespace clang;
@@ -38,7 +39,6 @@ bool SubRegion::isSubRegionOf(const MemRegion* R) const {
return false;
}
-
MemRegionManager* SubRegion::getMemRegionManager() const {
const SubRegion* r = this;
do {
@@ -253,8 +253,15 @@ StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
return getRegion<StringRegion>(Str);
}
-VarRegion* MemRegionManager::getVarRegion(const VarDecl* D,
+VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
const LocationContext *LC) {
+
+ // FIXME: Once we implement scope handling, we will need to properly lookup
+ // 'D' to the proper LocationContext. For now, just strip down to the
+ // StackFrame.
+ while (!isa<StackFrameContext>(LC))
+ LC = LC->getParent();
+
return getRegion<VarRegion>(D, LC);
}
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 13768eca8c..53ef054c53 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -168,15 +168,11 @@ public:
class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
const RegionStoreFeatures Features;
RegionBindings::Factory RBFactory;
-
- const MemRegion* SelfRegion;
-
public:
RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
: StoreManager(mgr),
Features(f),
- RBFactory(mgr.getAllocator()),
- SelfRegion(0) {}
+ RBFactory(mgr.getAllocator()) {}
virtual ~RegionStoreManager() {}
@@ -229,38 +225,9 @@ public:
NonLoc R, QualType resultTy);
Store getInitialStore(const LocationContext *InitLoc) {
- RegionBindings B = RBFactory.GetEmptyMap();
-
- // Eagerly bind 'self' to SelfRegion, because this is the only place we can
- // get the ObjCMethodDecl.
- typedef LiveVariables::AnalysisDataTy LVDataTy;
- LVDataTy &D = InitLoc->getLiveVariables()->getAnalysisData();
- for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I!=E; ++I){
- const NamedDecl *ND = I->first;
-
- if (const ImplicitParamDecl *PD = dyn_cast<ImplicitParamDecl>(ND)) {
- const Decl &CD = *InitLoc->getDecl();
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(&CD)) {
- if (MD->getSelfDecl() == PD) {
- SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
- MRMgr.getHeapRegion());
- B = RBFactory.Add(B, MRMgr.getVarRegion(PD, InitLoc),
- ValMgr.makeLoc(SelfRegion));
- }
- }
- }
- }
-
- return B.getRoot();
- }
-
- /// 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;
+ return RBFactory.GetEmptyMap().getRoot();
}
-
+
//===-------------------------------------------------------------------===//
// Binding values to regions.
//===-------------------------------------------------------------------===//