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.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
17 #include "clang/StaticAnalyzer/Core/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 using namespace clang;
23 using namespace ento;
24 
25 //===----------------------------------------------------------------------===//
26 // Worklist classes for exploration of reachable states.
27 //===----------------------------------------------------------------------===//
28 
29 WorkList::Visitor::~Visitor() {}
30 
31 namespace {
32 class DFS : public WorkList {
33   SmallVector<WorkListUnit,20> Stack;
34 public:
35   virtual bool hasWork() const {
36     return !Stack.empty();
37   }
38 
39   virtual void enqueue(const WorkListUnit& U) {
40     Stack.push_back(U);
41   }
42 
43   virtual WorkListUnit dequeue() {
44     assert (!Stack.empty());
45     const WorkListUnit& U = Stack.back();
46     Stack.pop_back(); // This technically "invalidates" U, but we are fine.
47     return U;
48   }
49 
50   virtual bool visitItemsInWorkList(Visitor &V) {
51     for (SmallVectorImpl<WorkListUnit>::iterator
52          I = Stack.begin(), E = Stack.end(); I != E; ++I) {
53       if (V.visit(*I))
54         return true;
55     }
56     return false;
57   }
58 };
59 
60 class BFS : public WorkList {
61   std::deque<WorkListUnit> Queue;
62 public:
63   virtual bool hasWork() const {
64     return !Queue.empty();
65   }
66 
67   virtual void enqueue(const WorkListUnit& U) {
68     Queue.push_front(U);
69   }
70 
71   virtual WorkListUnit dequeue() {
72     WorkListUnit U = Queue.front();
73     Queue.pop_front();
74     return U;
75   }
76 
77   virtual bool visitItemsInWorkList(Visitor &V) {
78     for (std::deque<WorkListUnit>::iterator
79          I = Queue.begin(), E = Queue.end(); I != E; ++I) {
80       if (V.visit(*I))
81         return true;
82     }
83     return false;
84   }
85 };
86 
87 } // end anonymous namespace
88 
89 // Place the dstor for WorkList here because it contains virtual member
90 // functions, and we the code for the dstor generated in one compilation unit.
91 WorkList::~WorkList() {}
92 
93 WorkList *WorkList::makeDFS() { return new DFS(); }
94 WorkList *WorkList::makeBFS() { return new BFS(); }
95 
96 namespace {
97   class BFSBlockDFSContents : public WorkList {
98     std::deque<WorkListUnit> Queue;
99     SmallVector<WorkListUnit,20> Stack;
100   public:
101     virtual bool hasWork() const {
102       return !Queue.empty() || !Stack.empty();
103     }
104 
105     virtual void enqueue(const WorkListUnit& U) {
106       if (isa<BlockEntrance>(U.getNode()->getLocation()))
107         Queue.push_front(U);
108       else
109         Stack.push_back(U);
110     }
111 
112     virtual WorkListUnit dequeue() {
113       // Process all basic blocks to completion.
114       if (!Stack.empty()) {
115         const WorkListUnit& U = Stack.back();
116         Stack.pop_back(); // This technically "invalidates" U, but we are fine.
117         return U;
118       }
119 
120       assert(!Queue.empty());
121       // Don't use const reference.  The subsequent pop_back() might make it
122       // unsafe.
123       WorkListUnit U = Queue.front();
124       Queue.pop_front();
125       return U;
126     }
127     virtual bool visitItemsInWorkList(Visitor &V) {
128       for (SmallVectorImpl<WorkListUnit>::iterator
129            I = Stack.begin(), E = Stack.end(); I != E; ++I) {
130         if (V.visit(*I))
131           return true;
132       }
133       for (std::deque<WorkListUnit>::iterator
134            I = Queue.begin(), E = Queue.end(); I != E; ++I) {
135         if (V.visit(*I))
136           return true;
137       }
138       return false;
139     }
140 
141   };
142 } // end anonymous namespace
143 
144 WorkList* WorkList::makeBFSBlockDFSContents() {
145   return new BFSBlockDFSContents();
146 }
147 
148 //===----------------------------------------------------------------------===//
149 // Core analysis engine.
150 //===----------------------------------------------------------------------===//
151 
152 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
153 bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps,
154                                    const ProgramState *InitState) {
155 
156   if (G->num_roots() == 0) { // Initialize the analysis by constructing
157     // the root if none exists.
158 
159     const CFGBlock *Entry = &(L->getCFG()->getEntry());
160 
161     assert (Entry->empty() &&
162             "Entry block must be empty.");
163 
164     assert (Entry->succ_size() == 1 &&
165             "Entry block must have 1 successor.");
166 
167     // Get the solitary successor.
168     const CFGBlock *Succ = *(Entry->succ_begin());
169 
170     // Construct an edge representing the
171     // starting location in the function.
172     BlockEdge StartLoc(Entry, Succ, L);
173 
174     // Set the current block counter to being empty.
175     WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
176 
177     if (!InitState)
178       // Generate the root.
179       generateNode(StartLoc, SubEng.getInitialState(L), 0);
180     else
181       generateNode(StartLoc, InitState, 0);
182   }
183 
184   // Check if we have a steps limit
185   bool UnlimitedSteps = Steps == 0;
186 
187   while (WList->hasWork()) {
188     if (!UnlimitedSteps) {
189       if (Steps == 0)
190         break;
191       --Steps;
192     }
193 
194     const WorkListUnit& WU = WList->dequeue();
195 
196     // Set the current block counter.
197     WList->setBlockCounter(WU.getBlockCounter());
198 
199     // Retrieve the node.
200     ExplodedNode *Node = WU.getNode();
201 
202     // Dispatch on the location type.
203     switch (Node->getLocation().getKind()) {
204       case ProgramPoint::BlockEdgeKind:
205         HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
206         break;
207 
208       case ProgramPoint::BlockEntranceKind:
209         HandleBlockEntrance(cast<BlockEntrance>(Node->getLocation()), Node);
210         break;
211 
212       case ProgramPoint::BlockExitKind:
213         assert (false && "BlockExit location never occur in forward analysis.");
214         break;
215 
216       case ProgramPoint::CallEnterKind:
217         HandleCallEnter(cast<CallEnter>(Node->getLocation()), WU.getBlock(),
218                         WU.getIndex(), Node);
219         break;
220 
221       case ProgramPoint::CallExitKind:
222         HandleCallExit(cast<CallExit>(Node->getLocation()), Node);
223         break;
224 
225       default:
226         assert(isa<PostStmt>(Node->getLocation()) ||
227                isa<PostInitializer>(Node->getLocation()));
228         HandlePostStmt(WU.getBlock(), WU.getIndex(), Node);
229         break;
230     }
231   }
232 
233   SubEng.processEndWorklist(hasWorkRemaining());
234   return WList->hasWork();
235 }
236 
237 void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
238                                                  unsigned Steps,
239                                                  const ProgramState *InitState,
240                                                  ExplodedNodeSet &Dst) {
241   ExecuteWorkList(L, Steps, InitState);
242   for (SmallVectorImpl<ExplodedNode*>::iterator I = G->EndNodes.begin(),
243                                            E = G->EndNodes.end(); I != E; ++I) {
244     Dst.Add(*I);
245   }
246 }
247 
248 void CoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
249                                    unsigned Index, ExplodedNode *Pred) {
250   CallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(),
251                                  L.getCalleeContext(), Block, Index);
252   SubEng.processCallEnter(Builder);
253 }
254 
255 void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
256   CallExitNodeBuilder Builder(*this, Pred);
257   SubEng.processCallExit(Builder);
258 }
259 
260 void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
261 
262   const CFGBlock *Blk = L.getDst();
263 
264   // Check if we are entering the EXIT block.
265   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
266 
267     assert (L.getLocationContext()->getCFG()->getExit().size() == 0
268             && "EXIT block cannot contain Stmts.");
269 
270     // Process the final state transition.
271     EndOfFunctionNodeBuilder Builder(Blk, Pred, this);
272     SubEng.processEndOfFunction(Builder);
273 
274     // This path is done. Don't enqueue any more nodes.
275     return;
276   }
277 
278   // Call into the subengine to process entering the CFGBlock.
279   ExplodedNodeSet dstNodes;
280   BlockEntrance BE(Blk, Pred->getLocationContext());
281   GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
282   SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
283 
284   if (dstNodes.empty()) {
285     if (!nodeBuilder.hasGeneratedNode) {
286       // Auto-generate a node and enqueue it to the worklist.
287       generateNode(BE, Pred->State, Pred);
288     }
289   }
290   else {
291     for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
292          I != E; ++I) {
293       WList->enqueue(*I);
294     }
295   }
296 
297   for (SmallVectorImpl<ExplodedNode*>::const_iterator
298        I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
299        I != E; ++I) {
300     blocksExhausted.push_back(std::make_pair(L, *I));
301   }
302 }
303 
304 void CoreEngine::HandleBlockEntrance(const BlockEntrance &L,
305                                        ExplodedNode *Pred) {
306 
307   // Increment the block counter.
308   BlockCounter Counter = WList->getBlockCounter();
309   Counter = BCounterFactory.IncrementCount(Counter,
310                              Pred->getLocationContext()->getCurrentStackFrame(),
311                                            L.getBlock()->getBlockID());
312   WList->setBlockCounter(Counter);
313 
314   // Process the entrance of the block.
315   if (CFGElement E = L.getFirstElement()) {
316     StmtNodeBuilder Builder(L.getBlock(), 0, Pred, this,
317                               SubEng.getStateManager());
318     SubEng.processCFGElement(E, Builder);
319   }
320   else
321     HandleBlockExit(L.getBlock(), Pred);
322 }
323 
324 void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) {
325 
326   if (const Stmt *Term = B->getTerminator()) {
327     switch (Term->getStmtClass()) {
328       default:
329         llvm_unreachable("Analysis for this terminator not implemented.");
330 
331       case Stmt::BinaryOperatorClass: // '&&' and '||'
332         HandleBranch(cast<BinaryOperator>(Term)->getLHS(), Term, B, Pred);
333         return;
334 
335       case Stmt::BinaryConditionalOperatorClass:
336       case Stmt::ConditionalOperatorClass:
337         HandleBranch(cast<AbstractConditionalOperator>(Term)->getCond(),
338                      Term, B, Pred);
339         return;
340 
341         // FIXME: Use constant-folding in CFG construction to simplify this
342         // case.
343 
344       case Stmt::ChooseExprClass:
345         HandleBranch(cast<ChooseExpr>(Term)->getCond(), Term, B, Pred);
346         return;
347 
348       case Stmt::DoStmtClass:
349         HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
350         return;
351 
352       case Stmt::ForStmtClass:
353         HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
354         return;
355 
356       case Stmt::ContinueStmtClass:
357       case Stmt::BreakStmtClass:
358       case Stmt::GotoStmtClass:
359         break;
360 
361       case Stmt::IfStmtClass:
362         HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
363         return;
364 
365       case Stmt::IndirectGotoStmtClass: {
366         // Only 1 successor: the indirect goto dispatch block.
367         assert (B->succ_size() == 1);
368 
369         IndirectGotoNodeBuilder
370            builder(Pred, B, cast<IndirectGotoStmt>(Term)->getTarget(),
371                    *(B->succ_begin()), this);
372 
373         SubEng.processIndirectGoto(builder);
374         return;
375       }
376 
377       case Stmt::ObjCForCollectionStmtClass: {
378         // In the case of ObjCForCollectionStmt, it appears twice in a CFG:
379         //
380         //  (1) inside a basic block, which represents the binding of the
381         //      'element' variable to a value.
382         //  (2) in a terminator, which represents the branch.
383         //
384         // For (1), subengines will bind a value (i.e., 0 or 1) indicating
385         // whether or not collection contains any more elements.  We cannot
386         // just test to see if the element is nil because a container can
387         // contain nil elements.
388         HandleBranch(Term, Term, B, Pred);
389         return;
390       }
391 
392       case Stmt::SwitchStmtClass: {
393         SwitchNodeBuilder builder(Pred, B, cast<SwitchStmt>(Term)->getCond(),
394                                     this);
395 
396         SubEng.processSwitch(builder);
397         return;
398       }
399 
400       case Stmt::WhileStmtClass:
401         HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
402         return;
403     }
404   }
405 
406   assert (B->succ_size() == 1 &&
407           "Blocks with no terminator should have at most 1 successor.");
408 
409   generateNode(BlockEdge(B, *(B->succ_begin()), Pred->getLocationContext()),
410                Pred->State, Pred);
411 }
412 
413 void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
414                                 const CFGBlock * B, ExplodedNode *Pred) {
415   assert(B->succ_size() == 2);
416   BranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
417                             Pred, this);
418   SubEng.processBranch(Cond, Term, Builder);
419 }
420 
421 void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
422                                   ExplodedNode *Pred) {
423   assert (!B->empty());
424 
425   if (StmtIdx == B->size())
426     HandleBlockExit(B, Pred);
427   else {
428     StmtNodeBuilder Builder(B, StmtIdx, Pred, this,
429                               SubEng.getStateManager());
430     SubEng.processCFGElement((*B)[StmtIdx], Builder);
431   }
432 }
433 
434 /// generateNode - Utility method to generate nodes, hook up successors,
435 ///  and add nodes to the worklist.
436 void CoreEngine::generateNode(const ProgramPoint &Loc,
437                               const ProgramState *State,
438                               ExplodedNode *Pred) {
439 
440   bool IsNew;
441   ExplodedNode *Node = G->getNode(Loc, State, &IsNew);
442 
443   if (Pred)
444     Node->addPredecessor(Pred, *G);  // Link 'Node' with its predecessor.
445   else {
446     assert (IsNew);
447     G->addRoot(Node);  // 'Node' has no predecessor.  Make it a root.
448   }
449 
450   // Only add 'Node' to the worklist if it was freshly generated.
451   if (IsNew) WList->enqueue(Node);
452 }
453 
454 ExplodedNode *
455 GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state,
456                                          ExplodedNode *pred,
457                                          ProgramPoint programPoint,
458                                          bool asSink) {
459 
460   hasGeneratedNode = true;
461   bool isNew;
462   ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
463   if (pred)
464     node->addPredecessor(pred, engine.getGraph());
465   if (isNew) {
466     if (asSink) {
467       node->markAsSink();
468       sinksGenerated.push_back(node);
469     }
470     return node;
471   }
472   return 0;
473 }
474 
475 StmtNodeBuilder::StmtNodeBuilder(const CFGBlock *b,
476                                  unsigned idx,
477                                  ExplodedNode *N,
478                                  CoreEngine* e,
479                                  ProgramStateManager &mgr)
480   : Eng(*e), B(*b), Idx(idx), Pred(N), Mgr(mgr),
481     PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
482     PointKind(ProgramPoint::PostStmtKind), Tag(0) {
483   Deferred.insert(N);
484 }
485 
486 StmtNodeBuilder::~StmtNodeBuilder() {
487   for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
488     if (!(*I)->isSink())
489       GenerateAutoTransition(*I);
490 }
491 
492 void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) {
493   assert (!N->isSink());
494 
495   // Check if this node entered a callee.
496   if (isa<CallEnter>(N->getLocation())) {
497     // Still use the index of the CallExpr. It's needed to create the callee
498     // StackFrameContext.
499     Eng.WList->enqueue(N, &B, Idx);
500     return;
501   }
502 
503   // Do not create extra nodes. Move to the next CFG element.
504   if (isa<PostInitializer>(N->getLocation())) {
505     Eng.WList->enqueue(N, &B, Idx+1);
506     return;
507   }
508 
509   PostStmt Loc(getStmt(), N->getLocationContext());
510 
511   if (Loc == N->getLocation()) {
512     // Note: 'N' should be a fresh node because otherwise it shouldn't be
513     // a member of Deferred.
514     Eng.WList->enqueue(N, &B, Idx+1);
515     return;
516   }
517 
518   bool IsNew;
519   ExplodedNode *Succ = Eng.G->getNode(Loc, N->State, &IsNew);
520   Succ->addPredecessor(N, *Eng.G);
521 
522   if (IsNew)
523     Eng.WList->enqueue(Succ, &B, Idx+1);
524 }
525 
526 ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst,
527                                         const Stmt *S,
528                                         ExplodedNode *Pred,
529                                         const ProgramState *St,
530                                         ProgramPoint::Kind K) {
531 
532   ExplodedNode *N = generateNode(S, St, Pred, K);
533 
534   if (N) {
535     if (BuildSinks)
536       N->markAsSink();
537     else
538       Dst.Add(N);
539   }
540 
541   return N;
542 }
543 
544 static ProgramPoint GetProgramPoint(const Stmt *S, ProgramPoint::Kind K,
545                                     const LocationContext *LC,
546                                     const ProgramPointTag *tag){
547   switch (K) {
548     default:
549       llvm_unreachable("Unhandled ProgramPoint kind");
550     case ProgramPoint::PreStmtKind:
551       return PreStmt(S, LC, tag);
552     case ProgramPoint::PostStmtKind:
553       return PostStmt(S, LC, tag);
554     case ProgramPoint::PreLoadKind:
555       return PreLoad(S, LC, tag);
556     case ProgramPoint::PostLoadKind:
557       return PostLoad(S, LC, tag);
558     case ProgramPoint::PreStoreKind:
559       return PreStore(S, LC, tag);
560     case ProgramPoint::PostStoreKind:
561       return PostStore(S, LC, tag);
562     case ProgramPoint::PostLValueKind:
563       return PostLValue(S, LC, tag);
564     case ProgramPoint::PostPurgeDeadSymbolsKind:
565       return PostPurgeDeadSymbols(S, LC, tag);
566   }
567 }
568 
569 ExplodedNode*
570 StmtNodeBuilder::generateNodeInternal(const Stmt *S,
571                                       const ProgramState *state,
572                                       ExplodedNode *Pred,
573                                       ProgramPoint::Kind K,
574                                       const ProgramPointTag *tag) {
575 
576   const ProgramPoint &L = GetProgramPoint(S, K, Pred->getLocationContext(),
577                                           tag);
578   return generateNodeInternal(L, state, Pred);
579 }
580 
581 ExplodedNode*
582 StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
583                                       const ProgramState *State,
584                                       ExplodedNode *Pred) {
585   bool IsNew;
586   ExplodedNode *N = Eng.G->getNode(Loc, State, &IsNew);
587   N->addPredecessor(Pred, *Eng.G);
588   Deferred.erase(Pred);
589 
590   if (IsNew) {
591     Deferred.insert(N);
592     return N;
593   }
594 
595   return NULL;
596 }
597 
598 // This function generate a new ExplodedNode but not a new branch(block edge).
599 ExplodedNode *BranchNodeBuilder::generateNode(const Stmt *Condition,
600                                               const ProgramState *State) {
601   bool IsNew;
602 
603   ExplodedNode *Succ
604     = Eng.G->getNode(PostCondition(Condition, Pred->getLocationContext()), State,
605                      &IsNew);
606 
607   Succ->addPredecessor(Pred, *Eng.G);
608 
609   Pred = Succ;
610 
611   if (IsNew)
612     return Succ;
613 
614   return NULL;
615 }
616 
617 ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
618                                               bool branch) {
619 
620   // If the branch has been marked infeasible we should not generate a node.
621   if (!isFeasible(branch))
622     return NULL;
623 
624   bool IsNew;
625 
626   ExplodedNode *Succ =
627     Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()),
628                    State, &IsNew);
629 
630   Succ->addPredecessor(Pred, *Eng.G);
631 
632   if (branch)
633     GeneratedTrue = true;
634   else
635     GeneratedFalse = true;
636 
637   if (IsNew) {
638     Deferred.push_back(Succ);
639     return Succ;
640   }
641 
642   return NULL;
643 }
644 
645 BranchNodeBuilder::~BranchNodeBuilder() {
646   if (!GeneratedTrue) generateNode(Pred->State, true);
647   if (!GeneratedFalse) generateNode(Pred->State, false);
648 
649   for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
650     if (!(*I)->isSink()) Eng.WList->enqueue(*I);
651 }
652 
653 
654 ExplodedNode*
655 IndirectGotoNodeBuilder::generateNode(const iterator &I,
656                                       const ProgramState *St,
657                                       bool isSink) {
658   bool IsNew;
659 
660   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
661                                       Pred->getLocationContext()), St, &IsNew);
662 
663   Succ->addPredecessor(Pred, *Eng.G);
664 
665   if (IsNew) {
666 
667     if (isSink)
668       Succ->markAsSink();
669     else
670       Eng.WList->enqueue(Succ);
671 
672     return Succ;
673   }
674 
675   return NULL;
676 }
677 
678 
679 ExplodedNode*
680 SwitchNodeBuilder::generateCaseStmtNode(const iterator &I,
681                                         const ProgramState *St) {
682 
683   bool IsNew;
684   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock(),
685                                       Pred->getLocationContext()),
686                                       St, &IsNew);
687   Succ->addPredecessor(Pred, *Eng.G);
688   if (IsNew) {
689     Eng.WList->enqueue(Succ);
690     return Succ;
691   }
692   return NULL;
693 }
694 
695 
696 ExplodedNode*
697 SwitchNodeBuilder::generateDefaultCaseNode(const ProgramState *St,
698                                            bool isSink) {
699   // Get the block for the default case.
700   assert(Src->succ_rbegin() != Src->succ_rend());
701   CFGBlock *DefaultBlock = *Src->succ_rbegin();
702 
703   // Sanity check for default blocks that are unreachable and not caught
704   // by earlier stages.
705   if (!DefaultBlock)
706     return NULL;
707 
708   bool IsNew;
709 
710   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
711                                       Pred->getLocationContext()), St, &IsNew);
712   Succ->addPredecessor(Pred, *Eng.G);
713 
714   if (IsNew) {
715     if (isSink)
716       Succ->markAsSink();
717     else
718       Eng.WList->enqueue(Succ);
719 
720     return Succ;
721   }
722 
723   return NULL;
724 }
725 
726 EndOfFunctionNodeBuilder::~EndOfFunctionNodeBuilder() {
727   // Auto-generate an EOP node if one has not been generated.
728   if (!hasGeneratedNode) {
729     // If we are in an inlined call, generate CallExit node.
730     if (Pred->getLocationContext()->getParent())
731       GenerateCallExitNode(Pred->State);
732     else
733       generateNode(Pred->State);
734   }
735 }
736 
737 ExplodedNode*
738 EndOfFunctionNodeBuilder::generateNode(const ProgramState *State,
739                                        ExplodedNode *P,
740                                        const ProgramPointTag *tag) {
741   hasGeneratedNode = true;
742   bool IsNew;
743 
744   ExplodedNode *Node = Eng.G->getNode(BlockEntrance(&B,
745                                Pred->getLocationContext(), tag ? tag : Tag),
746                                State, &IsNew);
747 
748   Node->addPredecessor(P ? P : Pred, *Eng.G);
749 
750   if (IsNew) {
751     Eng.G->addEndOfPath(Node);
752     return Node;
753   }
754 
755   return NULL;
756 }
757 
758 void EndOfFunctionNodeBuilder::GenerateCallExitNode(const ProgramState *state) {
759   hasGeneratedNode = true;
760   // Create a CallExit node and enqueue it.
761   const StackFrameContext *LocCtx
762                          = cast<StackFrameContext>(Pred->getLocationContext());
763   const Stmt *CE = LocCtx->getCallSite();
764 
765   // Use the the callee location context.
766   CallExit Loc(CE, LocCtx);
767 
768   bool isNew;
769   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
770   Node->addPredecessor(Pred, *Eng.G);
771 
772   if (isNew)
773     Eng.WList->enqueue(Node);
774 }
775 
776 
777 void CallEnterNodeBuilder::generateNode(const ProgramState *state) {
778   // Check if the callee is in the same translation unit.
779   if (CalleeCtx->getTranslationUnit() !=
780       Pred->getLocationContext()->getTranslationUnit()) {
781     // Create a new engine. We must be careful that the new engine should not
782     // reference data structures owned by the old engine.
783 
784     AnalysisManager &OldMgr = Eng.SubEng.getAnalysisManager();
785 
786     // Get the callee's translation unit.
787     idx::TranslationUnit *TU = CalleeCtx->getTranslationUnit();
788 
789     // Create a new AnalysisManager with components of the callee's
790     // TranslationUnit.
791     // The Diagnostic is  actually shared when we create ASTUnits from AST files.
792     AnalysisManager AMgr(TU->getASTContext(), TU->getDiagnostic(), OldMgr);
793 
794     // Create the new engine.
795     // FIXME: This cast isn't really safe.
796     bool GCEnabled = static_cast<ExprEngine&>(Eng.SubEng).isObjCGCEnabled();
797     ExprEngine NewEng(AMgr, GCEnabled);
798 
799     // Create the new LocationContext.
800     AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(),
801                                                CalleeCtx->getTranslationUnit());
802     const StackFrameContext *OldLocCtx = CalleeCtx;
803     const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx,
804                                                OldLocCtx->getParent(),
805                                                OldLocCtx->getCallSite(),
806                                                OldLocCtx->getCallSiteBlock(),
807                                                OldLocCtx->getIndex());
808 
809     // Now create an initial state for the new engine.
810     const ProgramState *NewState =
811       NewEng.getStateManager().MarshalState(state, NewLocCtx);
812     ExplodedNodeSet ReturnNodes;
813     NewEng.ExecuteWorkListWithInitialState(NewLocCtx, AMgr.getMaxNodes(),
814                                            NewState, ReturnNodes);
815     return;
816   }
817 
818   // Get the callee entry block.
819   const CFGBlock *Entry = &(CalleeCtx->getCFG()->getEntry());
820   assert(Entry->empty());
821   assert(Entry->succ_size() == 1);
822 
823   // Get the solitary successor.
824   const CFGBlock *SuccB = *(Entry->succ_begin());
825 
826   // Construct an edge representing the starting location in the callee.
827   BlockEdge Loc(Entry, SuccB, CalleeCtx);
828 
829   bool isNew;
830   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
831   Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
832 
833   if (isNew)
834     Eng.WList->enqueue(Node);
835 }
836 
837 void CallExitNodeBuilder::generateNode(const ProgramState *state) {
838   // Get the callee's location context.
839   const StackFrameContext *LocCtx
840                          = cast<StackFrameContext>(Pred->getLocationContext());
841   // When exiting an implicit automatic obj dtor call, the callsite is the Stmt
842   // that triggers the dtor.
843   PostStmt Loc(LocCtx->getCallSite(), LocCtx->getParent());
844   bool isNew;
845   ExplodedNode *Node = Eng.G->getNode(Loc, state, &isNew);
846   Node->addPredecessor(const_cast<ExplodedNode*>(Pred), *Eng.G);
847   if (isNew)
848     Eng.WList->enqueue(Node, LocCtx->getCallSiteBlock(),
849                        LocCtx->getIndex() + 1);
850 }
851