aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-06-01 20:04:04 +0000
committerTed Kremenek <kremenek@apple.com>2012-06-01 20:04:04 +0000
commit7fa9b4f258636d89342eda28f21a986c8ac353b1 (patch)
treed7b3c4df21fc87a3f8eb202703db8f322d73aa5d /lib/StaticAnalyzer/Core/RegionStore.cpp
parent784ae8e5c6b557e2395991c6008293660f5afe66 (diff)
static analyzer: add inlining support for directly called blocks.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157833 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp60
1 files changed, 43 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index acc0ec4dcf..3a932bc7e2 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -394,6 +394,12 @@ public: // Part of public interface to class.
const LocationContext *callerCtx,
const StackFrameContext *calleeCtx);
+ StoreRef enterStackFrame(ProgramStateRef state,
+ const FunctionDecl *FD,
+ const LocationContext *callerCtx,
+ const StackFrameContext *calleeCtx);
+
+
//===------------------------------------------------------------------===//
// Region "extents".
//===------------------------------------------------------------------===//
@@ -1944,8 +1950,18 @@ void removeDeadBindingsWorker::VisitBinding(SVal V) {
}
// If V is a region, then add it to the worklist.
- if (const MemRegion *R = V.getAsRegion())
+ if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
+
+ // All regions captured by a block are also live.
+ if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
+ BlockDataRegion::referenced_vars_iterator I = BR->referenced_vars_begin(),
+ E = BR->referenced_vars_end();
+ for ( ; I != E; ++I)
+ AddToWorkList(I.getCapturedRegion());
+ }
+ }
+
// Update the set of live symbols.
for (SymExpr::symbol_iterator SI = V.symbol_begin(), SE = V.symbol_end();
@@ -1964,21 +1980,6 @@ void removeDeadBindingsWorker::VisitBindingKey(BindingKey K) {
// should continue to track that symbol.
if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
SymReaper.markLive(SymR->getSymbol());
-
- // For BlockDataRegions, enqueue the VarRegions for variables marked
- // with __block (passed-by-reference).
- // via BlockDeclRefExprs.
- if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
- for (BlockDataRegion::referenced_vars_iterator
- RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
- RI != RE; ++RI) {
- if ((*RI)->getDecl()->getAttr<BlocksAttr>())
- AddToWorkList(*RI);
- }
-
- // No possible data bindings on a BlockDataRegion.
- return;
- }
}
// Visit the data binding for K.
@@ -2045,12 +2046,37 @@ StoreRef RegionStoreManager::removeDeadBindings(Store store,
return StoreRef(B.getRootWithoutRetain(), *this);
}
+StoreRef RegionStoreManager::enterStackFrame(ProgramStateRef state,
+ const LocationContext *callerCtx,
+ const StackFrameContext *calleeCtx)
+{
+ const Decl *D = calleeCtx->getDecl();
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return enterStackFrame(state, FD, callerCtx, calleeCtx);
+
+ // FIXME: when we handle more cases, this will need to be expanded.
+
+ const BlockDecl *BD = cast<BlockDecl>(D);
+ BlockDecl::param_const_iterator PI = BD->param_begin(),
+ PE = BD->param_end();
+ StoreRef store = StoreRef(state->getStore(), *this);
+ const CallExpr *CE = cast<CallExpr>(calleeCtx->getCallSite());
+ CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
+ for (; AI != AE && PI != PE; ++AI, ++PI) {
+ SVal ArgVal = state->getSVal(*AI, callerCtx);
+ store = Bind(store.getStore(),
+ svalBuilder.makeLoc(MRMgr.getVarRegion(*PI, calleeCtx)),
+ ArgVal);
+ }
+
+ return store;
+}
StoreRef RegionStoreManager::enterStackFrame(ProgramStateRef state,
+ const FunctionDecl *FD,
const LocationContext *callerCtx,
const StackFrameContext *calleeCtx)
{
- FunctionDecl const *FD = cast<FunctionDecl>(calleeCtx->getDecl());
FunctionDecl::param_const_iterator PI = FD->param_begin(),
PE = FD->param_end();
StoreRef store = StoreRef(state->getStore(), *this);