aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-05-04 21:48:42 +0000
committerTed Kremenek <kremenek@apple.com>2012-05-04 21:48:42 +0000
commit85d87df66a50a15a1957f7213802000b451a8ec9 (patch)
tree24a4c26b96e7d536b8f72a538e9916ea7a330659 /lib/StaticAnalyzer/Core/RegionStore.cpp
parent396663b22cd72e2a0164a6655d92d3a69d28b579 (diff)
Explicitly model capturing variables for blocks in the static analyzer. Fixes <rdar://problem/11125868>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156211 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index d5db03d7ce..26a7e4b24f 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -681,8 +681,22 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
BI != BE; ++BI) {
const VarRegion *VR = *BI;
const VarDecl *VD = VR->getDecl();
- if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
+ if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage()) {
AddToWorkList(VR);
+ }
+ else if (Loc::isLocType(VR->getValueType())) {
+ // Map the current bindings to a Store to retrieve the value
+ // of the binding. If that binding itself is a region, we should
+ // invalidate that region. This is because a block may capture
+ // a pointer value, but the thing pointed by that pointer may
+ // get invalidated.
+ Store store = B.getRootWithoutRetain();
+ SVal V = RM.getBinding(store, loc::MemRegionVal(VR));
+ if (const Loc *L = dyn_cast<Loc>(&V)) {
+ if (const MemRegion *LR = L->getAsRegion())
+ AddToWorkList(LR);
+ }
+ }
}
return;
}