diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-06-01 20:04:04 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-06-01 20:04:04 +0000 |
commit | 7fa9b4f258636d89342eda28f21a986c8ac353b1 (patch) | |
tree | d7b3c4df21fc87a3f8eb202703db8f322d73aa5d /lib/StaticAnalyzer/Core/RegionStore.cpp | |
parent | 784ae8e5c6b557e2395991c6008293660f5afe66 (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.cpp | 60 |
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); |