[analyzer] lib/StaticAnalyzer/Checkers/ExprEngineExperimentalChecks.cpp -> lib/Static...
[clang.git] / lib / StaticAnalyzer / CoreEngine.cpp
blob13cca35aacfa5b4fce3843d23646d777c9eaa4f3
1 //==- CoreEngine.cpp - Path-Sensitive Dataflow Engine ------------*- C++ -*-//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a generic engine for intraprocedural, path-sensitive,
11 // dataflow analysis via graph reachability engine.
13 //===----------------------------------------------------------------------===//
15 #include "clang/StaticAnalyzer/PathSensitive/AnalysisManager.h"
16 #include "clang/StaticAnalyzer/PathSensitive/CoreEngine.h"
17 #include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h"
18 #include "clang/Index/TranslationUnit.h"
19 #include "clang/AST/Expr.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include <vector>
23 #include <queue>
25 using llvm::cast;
26 using llvm::isa;
27 using namespace clang;
28 using namespace ento;
30 // This should be removed in the future.
31 namespace clang {
32 namespace ento {
33 TransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
34 const LangOptions& lopts);
38 //===----------------------------------------------------------------------===//
39 // Worklist classes for exploration of reachable states.
40 //===----------------------------------------------------------------------===//
42 WorkList::Visitor::~Visitor() {}
44 namespace {
45 class DFS : public WorkList {
46 llvm::SmallVector<WorkListUnit,20> Stack;
47 public:
48 virtual bool hasWork() const {
49 return !Stack.empty();
52 virtual void enqueue(const WorkListUnit& U) {
53 Stack.push_back(U);
56 virtual WorkListUnit dequeue() {
57 assert (!Stack.empty());
58 const WorkListUnit& U = Stack.back();
59 Stack.pop_back(); // This technically "invalidates" U, but we are fine.
60 return U;
63 virtual bool visitItemsInWorkList(Visitor &V) {
64 for (llvm::SmallVectorImpl<WorkListUnit>::iterator
65 I = Stack.begin(), E = Stack.end(); I != E; ++I) {
66 if (V.visit(*I))
67 return true;
69 return false;
73 class BFS : public WorkList {
74 std::deque<WorkListUnit> Queue;
75 public:
76 virtual bool hasWork() const {
77 return !Queue.empty();
80 virtual void enqueue(const WorkListUnit& U) {
81 Queue.push_front(U);
84 virtual WorkListUnit dequeue() {
85 WorkListUnit U = Queue.front();
86 Queue.pop_front();
87 return U;
90 virtual bool visitItemsInWorkList(Visitor &V) {
91 for (std::deque<WorkListUnit>::iterator
92 I = Queue.begin(), E = Queue.end(); I != E; ++I) {
93 if (V.visit(*I))
94 return true;
96 return false;
100 } // end anonymous namespace
102 // Place the dstor for WorkList here because it contains virtual member
103 // functions, and we the code for the dstor generated in one compilation unit.
104 WorkList::~WorkList() {}
106 WorkList *WorkList::makeDFS() { return new DFS(); }
107 WorkList *WorkList::makeBFS() { return new BFS(); }
109 namespace {
110 class BFSBlockDFSContents : public WorkList {
111 std::deque<WorkListUnit> Queue;
112 llvm::SmallVector<WorkListUnit,20> Stack;
113 public:
114 virtual bool hasWork() const {
115 return !Queue.empty() || !Stack.empty();
118 virtual void enqueue(const WorkListUnit& U) {
119 if (isa<BlockEntrance>(U.getNode()->getLocation()))
120 Queue.push_front(U);
121 else
122 Stack.push_back(U);
125 virtual WorkListUnit dequeue() {
126 // Process all basic blocks to completion.
127 if (!Stack.empty()) {
128 const WorkListUnit& U = Stack.back();
129 Stack.pop_back(); // This technically "invalidates" U, but we are fine.
130 return U;
133 assert(!Queue.empty());
134 // Don't use const reference. The subsequent pop_back() might make it
135 // unsafe.
136 WorkListUnit U = Queue.front();
137 Queue.pop_front();
138 return U;
140 virtual bool visitItemsInWorkList(Visitor &V) {
141 for (llvm::SmallVectorImpl<WorkListUnit>::iterator
142 I = Stack.begin(), E = Stack.end(); I != E; ++I) {
143 if (V.visit(*I))
144 return true;
146 for (std::deque<WorkListUnit>::iterator
147 I = Queue.begin(), E = Queue.end(); I != E; ++I) {
148 if (V.visit(*I))
149 return true;
151 return false;
155 } // end anonymous namespace
157 WorkList* WorkList::makeBFSBlockDFSContents() {
158 return new BFSBlockDFSContents();
161 //===----------------------------------------------------------------------===//
162 // Core analysis engine.
163 //===----------------------------------------------------------------------===//
165 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
166 bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
167 const GRState *InitState) {
169 if (G->num_roots() == 0) { // Initialize the analysis by constructing
170 // the root if none exists.
172 const CFGBlock* Entry = &(L->getCFG()->getEntry());
174 assert (Entry->empty() &&
175 "Entry block must be empty.");
177 assert (Entry->succ_size() == 1 &&
178 "Entry block must have 1 successor.");
180 // Get the solitary successor.
181 const CFGBlock* Succ = *(Entry->succ_begin());
183 // Construct an edge representing the
184 // starting location in the function.
185 BlockEdge StartLoc(Entry, Succ, L);
187 // Set the current block counter to being empty.
188 WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
190 if (!InitState)
191 // Generate the root.
192 generateNode(StartLoc, SubEng.getInitialState(L), 0);
193 else
194 generateNode(StartLoc, InitState, 0);
197 // Check if we have a steps limit
198 bool UnlimitedSteps = Steps == 0;
200 while (WList->hasWork()) {
201 if (!UnlimitedSteps) {
202 if (Steps == 0)
203 break;
204 --Steps;
207 const WorkListUnit& WU = WList->dequeue();
209 // Set the current block counter.
210 WList->setBlockCounter(WU.getBlockCounter());
212 // Retrieve the node.
213 ExplodedNode* Node = WU.getNode();
215 // Dispatch on the location type.
216 switch (Node->getLocation().getKind()) {
217 case ProgramPoint::BlockEdgeKind:
218 HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
219 break;
221 case ProgramPoint::BlockEntranceKind:
222 HandleBlockEntrance(cast<BlockEntrance>(Node->getLocation()), Node);
223 break;
225 case ProgramPoint::BlockExitKind:
226 assert (false && "BlockExit location never occur in forward analysis.");
227 break;
229 case ProgramPoint::CallEnterKind:
230 HandleCallEnter(cast<CallEnter>(Node->getLocation()), WU.getBlock(),
231 WU.getIndex(), Node);
232 break;
234 case ProgramPoint::CallExitKind:
235 HandleCallExit(cast<CallExit>(Node->getLocation()), Node);
236 break;
238 default:
239 assert(isa<PostStmt>(Node->getLocation()) ||
240 isa<PostInitializer>(Node->getLocation()));
241 HandlePostStmt(WU.getBlock(), WU.getIndex(), Node);
242 break;
246 SubEng.processEndWorklist(hasWorkRemaining());
247 return WList->hasWork();
250 void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
251 unsigned Steps,
252 const GRState *InitState,
253 ExplodedNodeSet &Dst) {
254 ExecuteWorkList(L, Steps, InitState);
255 for (llvm::SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(),
256 E = G->EndNodes.end(); I != E; ++I) {
257 Dst.Add(*I);
261 void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
262 unsigned Index, ExplodedNode *Pred) {
263 CallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(),
264 L.getCalleeContext(), Block, Index);
265 SubEng.processCallEnter(Builder);
268 void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
269 CallExitNodeBuilder Builder(*this, Pred);
270 SubEng.processCallExit(Builder);
273 void CoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
275 const CFGBlock* Blk = L.getDst();
277 // Check if we are entering the EXIT block.
278 if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
280 assert (L.getLocationContext()->getCFG()->getExit().size() == 0
281 && "EXIT block cannot contain Stmts.");
283 // Process the final state transition.
284 EndOfFunctionNodeBuilder Builder(Blk, Pred, this);
285 SubEng.processEndOfFunction(Builder);
287 // This path is done. Don't enqueue any more nodes.
288 return;
291 // Call into the subengine to process entering the CFGBlock.
292 ExplodedNodeSet dstNodes;
293 BlockEntrance BE(Blk, Pred->getLocationContext());
294 GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
295 SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
297 if (dstNodes.empty()) {
298 if (!nodeBuilder.hasGeneratedNode) {
299 // Auto-generate a node and enqueue it to the worklist.
300 generateNode(BE, Pred->State, Pred);
303 else {
304 for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
305 I != E; ++I) {
306 WList->enqueue(*I);
310 for (llvm::SmallVectorImpl<ExplodedNode*>::const_iterator
311 I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
312 I != E; ++I) {
313 blocksAborted.push_back(std::make_pair(L, *I));
317 void CoreEngine::HandleBlockEntrance(const BlockEntrance& L,
318 ExplodedNode* Pred) {
320 // Increment the block counter.
321 BlockCounter Counter = WList->getBlockCounter();
322 Counter = BCounterFactory.IncrementCount(Counter,
323 Pred->getLocationContext()->getCurrentStackFrame(),
324 L.getBlock()->getBlockID());
325 WList->setBlockCounter(Counter);
327 // Process the entrance of the block.
328 if (CFGElement E = L.getFirstElement()) {
329 StmtNodeBuilder Builder(L.getBlock(), 0, Pred, this,
330 SubEng.getStateManager());
331 SubEng.processCFGElement(E, Builder);
333 else
334 HandleBlockExit(L.getBlock(), Pred);
337 void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode* Pred) {
339 if (const Stmt* Term = B->getTerminator()) {
340 switch (Term->getStmtClass()) {
341 default:
342 assert(false && "Analysis for this terminator not implemented.");
343 break;
345 case Stmt::BinaryOperatorClass: // '&&' and '||'
346 HandleBranch(cast<BinaryOperator>(Term)->getLHS(), Term, B, Pred);
347 return;
349 case Stmt::ConditionalOperatorClass:
350 HandleBranch(cast<ConditionalOperator>(Term)->getCond(), Term, B, Pred);
351 return;
353 // FIXME: Use constant-folding in CFG construction to simplify this
354 // case.
356 case Stmt::ChooseExprClass:
357 HandleBranch(cast<ChooseExpr>(Term)->getCond(), Term, B, Pred);
358 return;
360 case Stmt::DoStmtClass:
361 HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
362 return;
364 case Stmt::ForStmtClass:
365 HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
366 return;
368 case Stmt::ContinueStmtClass:
369 case Stmt::BreakStmtClass:
370 case Stmt::GotoStmtClass:
371 break;
373 case Stmt::IfStmtClass:
374 HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
375 return;
377 case Stmt::IndirectGotoStmtClass: {
378 // Only 1 successor: the indirect goto dispatch block.
379 assert (B->succ_size() == 1);
381 IndirectGotoNodeBuilder
382 builder(Pred, B, cast<IndirectGotoStmt>(Term)->getTarget(),
383 *(B->succ_begin()), this);
385 SubEng.processIndirectGoto(builder);
386 return;
389 case Stmt::ObjCForCollectionStmtClass: {
390 // In the case of ObjCForCollectionStmt, it appears twice in a CFG:
392 // (1) inside a basic block, which represents the binding of the
393 // 'element' variable to a value.
394 // (2) in a terminator, which represents the branch.
396 // For (1), subengines will bind a value (i.e., 0 or 1) indicating
397 // whether or not collection contains any more elements. We cannot
398 // just test to see if the element is nil because a container can
399 // contain nil elements.
400 HandleBranch(Term, Term, B, Pred);
401 return;
404 case Stmt::SwitchStmtClass: {
405 SwitchNodeBuilder builder(Pred, B, cast<SwitchStmt>(Term)->getCond(),
406 this);
408 SubEng.processSwitch(builder);
409 return;
412 case Stmt::WhileStmtClass:
413 HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
414 return;
418 assert (B->succ_size() == 1 &&
419 "Blocks with no terminator should have at most 1 successor.");
421 generateNode(BlockEdge(B, *(B->succ_begin()), Pred->getLocationContext()),
422 Pred->State, Pred);
425 void CoreEngine::HandleBranch(const Stmt* Cond, const Stmt* Term,
426 const CFGBlock * B, ExplodedNode* Pred) {
427 assert(B->succ_size() == 2);
428 BranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
429 Pred, this);
430 SubEng.processBranch(Cond, Term, Builder);
433 void CoreEngine::HandlePostStmt(const CFGBlock* B, unsigned StmtIdx,
434 ExplodedNode* Pred) {
435 assert (!B->empty());
437 if (StmtIdx == B->size())
438 HandleBlockExit(B, Pred);
439 else {
440 StmtNodeBuilder Builder(B, StmtIdx, Pred, this,
441 SubEng.getStateManager());
442 SubEng.processCFGElement((*B)[StmtIdx], Builder);
446 /// generateNode - Utility method to generate nodes, hook up successors,
447 /// and add nodes to the worklist.
448 void CoreEngine::generateNode(const ProgramPoint& Loc,
449 const GRState* State, ExplodedNode* Pred) {
451 bool IsNew;
452 ExplodedNode* Node = G->getNode(Loc, State, &IsNew);
454 if (Pred)
455 Node->addPredecessor(Pred, *G); // Link 'Node' with its predecessor.
456 else {
457 assert (IsNew);
458 G->addRoot(Node); // 'Node' has no predecessor. Make it a root.
461 // Only add 'Node' to the worklist if it was freshly generated.
462 if (IsNew) WList->enqueue(Node);
465 ExplodedNode *
466 GenericNodeBuilderImpl::generateNodeImpl(const GRState *state,
467 ExplodedNode *pred,
468 ProgramPoint programPoint,
469 bool asSink) {
471 hasGeneratedNode = true;
472 bool isNew;
473 ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
474 if (pred)
475 node->addPredecessor(pred, engine.getGraph());
476 if (isNew) {
477 if (asSink) {
478 node->markAsSink();
479 sinksGenerated.push_back(node);
481 return node;
483 return 0;
486 StmtNodeBuilder::StmtNodeBuilder(const CFGBlock* b, unsigned idx,
487 ExplodedNode* N, CoreEngine* e,
488 GRStateManager &mgr)
489 : Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr),
490 PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
491 PointKind(ProgramPoint::PostStmtKind), Tag(0) {
492 Deferred.insert(N);
493 CleanedState = Pred->getState();
496 StmtNodeBuilder::~StmtNodeBuilder() {
497 for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
498 if (!(*I)->isSink())
499 GenerateAutoTransition(*I);
502 void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode* N) {
503 assert (!N->isSink());
505 // Check if this node entered a callee.
506 if (isa<CallEnter>(N->getLocation())) {
507 // Still use the index of the CallExpr. It's needed to create the callee
508 // StackFrameContext.
509 Eng.WList->enqueue(N, &B, Idx);
510 return;
513 // Do not create extra nodes. Move to the next CFG element.
514 if (isa<PostInitializer>(N->getLocation())) {
515 Eng.WList->enqueue(N, &B, Idx+1);
516 return;
519 PostStmt Loc(getStmt(), N->getLocationContext());
521 if (Loc == N->getLocation()) {
522 // Note: 'N' should be a fresh node because otherwise it shouldn't be
523 // a member of Deferred.
524 Eng.WList->enqueue(N, &B, Idx+1);
525 return;
528 bool IsNew;
529 ExplodedNode* Succ = Eng.G->getNode(Loc, N->State, &IsNew);
530 Succ->addPredecessor(N, *Eng.G);
532 if (IsNew)
533 Eng.WList->enqueue(Succ, &B, Idx+1);
536 ExplodedNode* StmtNodeBuilder::MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
537 ExplodedNode* Pred, const GRState* St,
538 ProgramPoint::Kind K) {
540 ExplodedNode* N = generateNode(S, St, Pred, K);
542 if (N) {
543 if (BuildSinks)
544 N->markAsSink();
545 else
546 Dst.Add(N);
549 return N;
552 static ProgramPoint GetProgramPoint(const Stmt *S, ProgramPoint::Kind K,
553 const LocationContext *LC, const void *tag){
554 switch (K) {
555 default:
556 assert(false && "Unhandled ProgramPoint kind");
557 case ProgramPoint::PreStmtKind:
558 return PreStmt(S, LC, tag);
559 case ProgramPoint::PostStmtKind:
560 return PostStmt(S, LC, tag);
561 case ProgramPoint::PreLoadKind:
562 return PreLoad(S, LC, tag);
563 case ProgramPoint::PostLoadKind:
564 return PostLoad(S, LC, tag);
565 case ProgramPoint::PreStoreKind:
566 return PreStore(S, LC, tag);
567 case ProgramPoint::PostStoreKind:
568 return PostStore(S, LC, tag);
569 case ProgramPoint::PostLValueKind:
570 return PostLValue(S, LC, tag);
571 case ProgramPoint::PostPurgeDeadSymbolsKind:
572 return PostPurgeDeadSymbols(S, LC, tag);
576 ExplodedNode*
577 StmtNodeBuilder::generateNodeInternal(const Stmt* S, const GRState* state,
578 ExplodedNode* Pred,
579 ProgramPoint::Kind K,
580 const void *tag) {
582 const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),tag);
583 return generateNodeInternal(L, state, Pred);
586 ExplodedNode*
587 StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
588 const GRState* State,
589 ExplodedNode* Pred) {
590 bool IsNew;
591 ExplodedNode* N = Eng.G->getNode(Loc, State, &IsNew);
592 N->addPredecessor(Pred, *Eng.G);
593 Deferred.erase(Pred);
595 if (IsNew) {
596 Deferred.insert(N);
597 return N;
600 return NULL;
603 ExplodedNode* BranchNodeBuilder::generateNode(const GRState* State,
604 bool branch) {
606 // If the branch has been marked infeasible we should not generate a node.
607 if (!isFeasible(branch))
608 return NULL;
610 bool IsNew;
612 ExplodedNode* Succ =
613 Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()),
614 State, &IsNew);
616 Succ->addPredecessor(Pred, *Eng.G);
618 if (branch)
619 GeneratedTrue = true;
620 else
621 GeneratedFalse = true;
623 if (IsNew) {
624 Deferred.push_back(Succ);
625 return Succ;
628 return NULL;
631 BranchNodeBuilder::~BranchNodeBuilder() {
632 if (!GeneratedTrue) generateNode(Pred->State, true);
633 if (!GeneratedFalse) generateNode(Pred->State, false);
635 for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
636 if (!(*I)->isSink()) Eng.WList->enqueue(*I);
640 ExplodedNode*
641 IndirectGotoNodeBuilder::generateNode(const iterator& I, const GRState* St,
642 bool isSink) {
643 bool IsNew;
645 ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
646 Pred->getLocationContext()), St, &IsNew);
648 Succ->addPredecessor(Pred, *Eng.G);
650 if (IsNew) {
652 if (isSink)
653 Succ->markAsSink();
654 else
655 Eng.WList->enqueue(Succ);
657 return Succ;
660 return NULL;
664 ExplodedNode*
665 SwitchNodeBuilder::generateCaseStmtNode(const iterator& I, const GRState* St){
667 bool IsNew;
669 ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
670 Pred->getLocationContext()), St, &IsNew);
671 Succ->addPredecessor(Pred, *Eng.G);
673 if (IsNew) {
674 Eng.WList->enqueue(Succ);
675 return Succ;
678 return NULL;
682 ExplodedNode*
683 SwitchNodeBuilder::generateDefaultCaseNode(const GRState* St, bool isSink) {
685 // Get the block for the default case.
686 assert (Src->succ_rbegin() != Src->succ_rend());
687 CFGBlock* DefaultBlock = *Src->succ_rbegin();
689 bool IsNew;
691 ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
692 Pred->getLocationContext()), St, &IsNew);
693 Succ->addPredecessor(Pred, *Eng.G);
695 if (IsNew) {
696 if (isSink)
697 Succ->markAsSink();
698 else
699 Eng.WList->enqueue(Succ);
701 return Succ;
704 return NULL;
707 EndOfFunctionNodeBuilder::~EndOfFunctionNodeBuilder() {
708 // Auto-generate an EOP node if one has not been generated.
709 if (!hasGeneratedNode) {
710 // If we are in an inlined call, generate CallExit node.
711 if (Pred->getLocationContext()->getParent())
712 GenerateCallExitNode(Pred->State);
713 else
714 generateNode(Pred->State);
718 ExplodedNode*
719 EndOfFunctionNodeBuilder::generateNode(const GRState* State, const void *tag,
720 ExplodedNode* P) {
721 hasGeneratedNode = true;
722 bool IsNew;
724 ExplodedNode* Node = Eng.G->getNode(BlockEntrance(&B,
725 Pred->getLocationContext(), tag), State, &IsNew);
727 Node->addPredecessor(P ? P : Pred, *Eng.G);
729 if (IsNew) {
730 Eng.G->addEndOfPath(Node);
731 return Node;
734 return NULL;
737 void EndOfFunctionNodeBuilder::GenerateCallExitNode(const GRState *state) {
738 hasGeneratedNode = true;
739 // Create a CallExit node and enqueue it.
740 const StackFrameContext *LocCtx
741 = cast<StackFrameContext>(Pred->getLocationContext());
742 const Stmt *CE = LocCtx->getCallSite();
744 // Use the the callee location context.
745 CallExit Loc(CE, LocCtx);
747 bool isNew;
748 ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
749 Node->addPredecessor(Pred, *Eng.G);
751 if (isNew)
752 Eng.WList->enqueue(Node);
756 void CallEnterNodeBuilder::generateNode(const GRState *state) {
757 // Check if the callee is in the same translation unit.
758 if (CalleeCtx->getTranslationUnit() !=
759 Pred->getLocationContext()->getTranslationUnit()) {
760 // Create a new engine. We must be careful that the new engine should not
761 // reference data structures owned by the old engine.
763 AnalysisManager &OldMgr = Eng.SubEng.getAnalysisManager();
765 // Get the callee's translation unit.
766 idx::TranslationUnit *TU = CalleeCtx->getTranslationUnit();
768 // Create a new AnalysisManager with components of the callee's
769 // TranslationUnit.
770 // The Diagnostic is actually shared when we create ASTUnits from AST files.
771 AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(),
772 OldMgr.getLangOptions(),
773 OldMgr.getPathDiagnosticClient(),
774 OldMgr.getStoreManagerCreator(),
775 OldMgr.getConstraintManagerCreator(),
776 OldMgr.getIndexer(),
777 OldMgr.getMaxNodes(), OldMgr.getMaxVisit(),
778 OldMgr.shouldVisualizeGraphviz(),
779 OldMgr.shouldVisualizeUbigraph(),
780 OldMgr.shouldPurgeDead(),
781 OldMgr.shouldEagerlyAssume(),
782 OldMgr.shouldTrimGraph(),
783 OldMgr.shouldInlineCall(),
784 OldMgr.getAnalysisContextManager().getUseUnoptimizedCFG(),
785 OldMgr.getAnalysisContextManager().getAddImplicitDtors(),
786 OldMgr.getAnalysisContextManager().getAddInitializers());
787 llvm::OwningPtr<TransferFuncs> TF(MakeCFRefCountTF(AMgr.getASTContext(),
788 /* GCEnabled */ false,
789 AMgr.getLangOptions()));
790 // Create the new engine.
791 ExprEngine NewEng(AMgr, TF.take());
793 // Create the new LocationContext.
794 AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(),
795 CalleeCtx->getTranslationUnit());
796 const StackFrameContext *OldLocCtx = CalleeCtx;
797 const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx,
798 OldLocCtx->getParent(),
799 OldLocCtx->getCallSite(),
800 OldLocCtx->getCallSiteBlock(),
801 OldLocCtx->getIndex());
803 // Now create an initial state for the new engine.
804 const GRState *NewState = NewEng.getStateManager().MarshalState(state,
805 NewLocCtx);
806 ExplodedNodeSet ReturnNodes;
807 NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(),
808 NewState, ReturnNodes);
809 return;
812 // Get the callee entry block.
813 const CFGBlock *Entry = &(CalleeCtx->getCFG()->getEntry());
814 assert(Entry->empty());
815 assert(Entry->succ_size() == 1);
817 // Get the solitary successor.
818 const CFGBlock *SuccB = *(Entry->succ_begin());
820 // Construct an edge representing the starting location in the callee.
821 BlockEdge Loc(Entry, SuccB, CalleeCtx);
823 bool isNew;
824 ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
825 Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
827 if (isNew)
828 Eng.WList->enqueue(Node);
831 void CallExitNodeBuilder::generateNode(const GRState *state) {
832 // Get the callee's location context.
833 const StackFrameContext *LocCtx
834 = cast<StackFrameContext>(Pred->getLocationContext());
835 // When exiting an implicit automatic obj dtor call, the callsite is the Stmt
836 // that triggers the dtor.
837 PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
838 bool isNew;
839 ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
840 Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
841 if (isNew)
842 Eng.WList->enqueue(Node, LocCtx->getCallSiteBlock(),
843 LocCtx->getIndex() + 1);