diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index d5555daecd..cf94ac3060 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -182,14 +182,35 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { CanQualType T = getContext().getCanonicalType(BE->getType()); + + // Get the value of the block itself. SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T, Pred->getLocationContext()); + ProgramStateRef State = Pred->getState(); + + // If we created a new MemRegion for the block, we should explicitly bind + // the captured variables. + if (const BlockDataRegion *BDR = + dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) { + + BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(), + E = BDR->referenced_vars_end(); + + for (; I != E; ++I) { + const MemRegion *capturedR = I.getCapturedRegion(); + const MemRegion *originalR = I.getOriginalRegion(); + if (capturedR != originalR) { + SVal originalV = State->getSVal(loc::MemRegionVal(originalR)); + State = State->bindLoc(loc::MemRegionVal(capturedR), originalV); + } + } + } + ExplodedNodeSet Tmp; StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext); Bldr.generateNode(BE, Pred, - Pred->getState()->BindExpr(BE, Pred->getLocationContext(), - V), + State->BindExpr(BE, Pred->getLocationContext(), V), false, 0, ProgramPoint::PostLValueKind); |