Refine MemRegions for blocks. Add a new region called
'BlockDataRegion' to distinguish between the code associated with a
block (which is represented by 'BlockTextRegion') and an instance of a
block, which includes both code and data. 'BlockDataRegion' has an
associated LocationContext, which can be used to eventually model the
lifetime of a block object once LocationContexts can represent scopes
(and iterations around a loop, etc.).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89900 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 10d0776..06aa6bd 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -3002,7 +3002,7 @@
// FIXME: Better support for blocks. For now we stop tracking anything
// that is passed to blocks.
// FIXME: Need to handle variables that are "captured" by the block.
- if (dyn_cast_or_null<BlockTextRegion>(L.getAsRegion())) {
+ if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
Summ = Summaries.getPersistentStopSummary();
}
else {
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index cb3f68b..12e9ba8 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1107,7 +1107,9 @@
ExplodedNodeSet Tmp;
CanQualType T = getContext().getCanonicalType(BE->getType());
- SVal V = ValMgr.getBlockPointer(BE->getBlockDecl(), T);
+ SVal V = ValMgr.getBlockPointer(BE->getBlockDecl(), T,
+ Pred->getLocationContext());
+
MakeNode(Tmp, BE, Pred, GetState(Pred)->BindExpr(BE, V),
ProgramPoint::PostLValueKind);
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 8b4c7a6..430ec23 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -148,6 +148,19 @@
BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
}
+void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+ const BlockTextRegion *BC,
+ const LocationContext *LC,
+ const MemRegion *) {
+ ID.AddInteger(MemRegion::BlockDataRegionKind);
+ ID.AddPointer(BC);
+ ID.AddPointer(LC);
+}
+
+void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+ BlockDataRegion::ProfileRegion(ID, BC, LC, NULL);
+}
+
//===----------------------------------------------------------------------===//
// Region pretty-printing.
//===----------------------------------------------------------------------===//
@@ -176,9 +189,14 @@
}
void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
- os << "block{" << (void*) this << '}';
+ os << "block_code{" << (void*) this << '}';
}
+void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
+ os << "block_data{" << BC << '}';
+}
+
+
void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
// FIXME: More elaborate pretty-printing.
os << "{ " << (void*) CL << " }";
@@ -274,6 +292,18 @@
return getRegion<VarRegion>(D, LC);
}
+BlockDataRegion *MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
+ 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 getSubRegion<BlockDataRegion>(BC, LC, getStackRegion());
+}
+
CompoundLiteralRegion*
MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
return getRegion<CompoundLiteralRegion>(CL);
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 16a4690..deb6c07 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -714,6 +714,7 @@
case MemRegion::FunctionTextRegionKind:
case MemRegion::BlockTextRegionKind:
+ case MemRegion::BlockDataRegionKind:
// Technically this can happen if people do funny things with casts.
return UnknownVal();
@@ -860,6 +861,7 @@
case MemRegion::FunctionTextRegionKind:
case MemRegion::BlockTextRegionKind:
+ case MemRegion::BlockDataRegionKind:
// Technically this can happen if people do funny things with casts.
return UnknownVal();
diff --git a/lib/Analysis/ValueManager.cpp b/lib/Analysis/ValueManager.cpp
index 37df443..22a8211 100644
--- a/lib/Analysis/ValueManager.cpp
+++ b/lib/Analysis/ValueManager.cpp
@@ -142,9 +142,11 @@
return loc::MemRegionVal(R);
}
-DefinedSVal ValueManager::getBlockPointer(const BlockDecl *BD,
- CanQualType locTy) {
- CodeTextRegion *R = MemMgr.getBlockTextRegion(BD, locTy);
- return loc::MemRegionVal(R);
+DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D,
+ CanQualType locTy,
+ const LocationContext *LC) {
+ BlockTextRegion *BC = MemMgr.getBlockTextRegion(D, locTy);
+ BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
+ return loc::MemRegionVal(BD);
}