From 7e53bd6fb01b062ece426252fb94c76bcce58941 Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Fri, 20 Apr 2012 21:59:08 +0000 Subject: [analyzer] Run remove dead bindings right before leaving a function. This is needed to ensure that we always report issues in the correct function. For example, leaks are identified when we call remove dead bindings. In order to make sure we report a callee's leak in the callee, we have to run the operation in the callee's context. This change required quite a bit of infrastructure work since: - We used to only run remove dead bindings before a given statement; here we need to run it after the last statement in the function. For this, we added additional Program Point and special mode in the SymbolReaper to remove all symbols in context lower than the current one. - The call exit operation turned into a sequence of nodes, which are now guarded by CallExitBegin and CallExitEnd nodes for clarity and convenience. (Sorry for the long diff.) llvm-svn: 155244 --- clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Core/CoreEngine.cpp') diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index ca662c79921..c9de20e500e 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -248,7 +248,7 @@ void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, break; } - case ProgramPoint::CallExitKind: + case ProgramPoint::CallExitBeginKind: SubEng.processCallExit(Pred); break; @@ -531,14 +531,14 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, WList->enqueue(Succ, Block, Idx+1); } -ExplodedNode *CoreEngine::generateCallExitNode(ExplodedNode *N) { - // Create a CallExit node and enqueue it. +ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N) { + // Create a CallExitBegin node and enqueue it. const StackFrameContext *LocCtx = cast(N->getLocationContext()); const Stmt *CE = LocCtx->getCallSite(); // Use the the callee location context. - CallExit Loc(CE, LocCtx); + CallExitBegin Loc(CE, LocCtx); bool isNew; ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew); @@ -565,12 +565,13 @@ void CoreEngine::enqueue(ExplodedNodeSet &Set, void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set) { for (ExplodedNodeSet::iterator I = Set.begin(), E = Set.end(); I != E; ++I) { ExplodedNode *N = *I; - // If we are in an inlined call, generate CallExit node. + // If we are in an inlined call, generate CallExitBegin node. if (N->getLocationContext()->getParent()) { - N = generateCallExitNode(N); + N = generateCallExitBeginNode(N); if (N) WList->enqueue(N); } else { + // TODO: We should run remove dead bindings here. G->addEndOfPath(N); NumPathsExplored++; } -- cgit v1.2.3