ExprEngineCallAndReturn.cpp revision e90d3f847dcce76237078b67db8895eb7a24189e
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- C++ -*-===//
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
3c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt//                     The LLVM Compiler Infrastructure
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// This file is distributed under the University of Illinois Open Source
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// License. See LICENSE.TXT for details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===//
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//  This file defines ExprEngine's support for calls and returns.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===//
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define DEBUG_TYPE "ExprEngine"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Analysis/Analyses/LiveVariables.h"
171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "clang/StaticAnalyzer/Core/CheckerManager.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/AST/DeclCXX.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/SmallSet.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/Statistic.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/SaveAndRestore.h"
2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CXX_INLINING_ENABLED 1
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing namespace clang;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtusing namespace ento;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSTATISTIC(NumOfDynamicDispatchPathSplits,
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  "The # of times we split the path due to imprecise dynamic dispatch info");
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) {
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Get the entry block in the CFG of the callee.
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *calleeCtx = CE.getCalleeContext();
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const CFG *CalleeCFG = calleeCtx->getCFG();
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const CFGBlock *Entry = &(CalleeCFG->getEntry());
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Validate the CFG.
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(Entry->empty());
411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  assert(Entry->succ_size() == 1);
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Get the solitary sucessor.
4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  const CFGBlock *Succ = *(Entry->succ_begin());
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Construct an edge representing the starting location in the callee.
4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  BlockEdge Loc(Entry, Succ, calleeCtx);
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef state = Pred->getState();
501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  // Construct a new node and add it to the worklist.
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isNew;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Node->addPredecessor(Pred, G);
55a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt  if (isNew)
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Engine.getWorkList()->enqueue(Node);
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
58c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
59c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// Find the last statement on the path to the exploded node and the
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// corresponding Block.
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic std::pair<const Stmt*,
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                 const CFGBlock*> getLastStmt(const ExplodedNode *Node) {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Stmt *S = 0;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *SF =
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          Node->getLocation().getLocationContext()->getCurrentStackFrame();
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Back up through the ExplodedGraph until we reach a statement node.
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  while (Node) {
69c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    const ProgramPoint &PP = Node->getLocation();
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
71c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) {
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      S = SP->getStmt();
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      break;
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    } else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&PP)) {
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      S = CEE->getCalleeContext()->getCallSite();
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (S)
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        break;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // If we have an implicit call, we'll probably end up with a
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // StmtPoint inside the callee, which is acceptable.
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // (It's possible a function ONLY contains implicit calls -- such as an
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // implicitly-generated destructor -- so we shouldn't just skip back to
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // the CallEnter node and keep going.)
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    } else if (const CallEnter *CE = dyn_cast<CallEnter>(&PP)) {
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // If we reached the CallEnter for this function, it has no statements.
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (CE->getCalleeContext() == SF)
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        break;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    Node = *Node->pred_begin();
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const CFGBlock *Blk = 0;
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (S) {
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Now, get the enclosing basic block.
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    while (Node && Node->pred_size() >=1 ) {
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      const ProgramPoint &PP = Node->getLocation();
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (isa<BlockEdge>(PP) &&
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          (PP.getLocationContext()->getCurrentStackFrame() == SF)) {
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        BlockEdge &EPP = cast<BlockEdge>(PP);
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        Blk = EPP.getDst();
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        break;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Node = *Node->pred_begin();
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return std::pair<const Stmt*, const CFGBlock*>(S, Blk);
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// The call exit is simulated with a sequence of nodes, which occur between
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// CallExitBegin and CallExitEnd. The following operations occur between the
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// two program points:
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 1. CallExitBegin (triggers the start of call exit sequence)
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 2. Bind the return value
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 3. Run Remove dead bindings to clean up the dead symbols from the callee.
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 4. CallExitEnd (switch to the caller context)
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 5. PostStmt<CallExpr>
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::processCallExit(ExplodedNode *CEBNode) {
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Step 1 CEBNode was generated before the call.
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *calleeCtx =
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      CEBNode->getLocationContext()->getCurrentStackFrame();
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // The parent context might not be a stack frame, so make sure we
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // look up the first enclosing stack frame.
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *callerCtx =
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    calleeCtx->getParent()->getCurrentStackFrame();
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Stmt *CE = calleeCtx->getCallSite();
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef state = CEBNode->getState();
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Find the last statement in the function and the corresponding basic block.
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Stmt *LastSt = 0;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const CFGBlock *Blk = 0;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  llvm::tie(LastSt, Blk) = getLastStmt(CEBNode);
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Step 2: generate node with bound return value: CEBNode -> BindedRetNode.
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // If the callee returns an expression, bind its value to CallExpr.
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (CE) {
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      const LocationContext *LCtx = CEBNode->getLocationContext();
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      SVal V = state->getSVal(RS, LCtx);
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      state = state->BindExpr(CE, callerCtx, V);
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Bind the constructed object value to CXXConstructExpr.
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      loc::MemRegionVal This =
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      SVal ThisV = state->getSVal(This);
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // Always bind the region to the CXXConstructExpr.
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      state = state->BindExpr(CCE, callerCtx, ThisV);
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Step 3: BindedRetNode -> CleanedNodes
15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // If we can find a statement and a block in the inlined function, run remove
15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // dead bindings before returning from the call. This is important to ensure
16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // that we report the issues such as leaks in the stack contexts in which
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // they occurred.
16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  ExplodedNodeSet CleanedNodes;
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (LastSt && Blk) {
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    static SimpleProgramPointTag retValBind("ExprEngine : Bind Return Value");
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    PostStmt Loc(LastSt, calleeCtx, &retValBind);
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    bool isNew;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    BindedRetNode->addPredecessor(CEBNode, G);
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!isNew)
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return;
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    NodeBuilderContext Ctx(getCoreEngine(), Blk, BindedRetNode);
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    currentBuilderContext = &Ctx;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Here, we call the Symbol Reaper with 0 statement and caller location
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // context, telling it to clean up everything in the callee's context
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // (and it's children). We use LastStmt as a diagnostic statement, which
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // which the PreStmtPurge Dead point will be associated.
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    removeDead(BindedRetNode, CleanedNodes, 0, callerCtx, LastSt,
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt               ProgramPoint::PostStmtPurgeDeadSymbolsKind);
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    currentBuilderContext = 0;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  } else {
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CleanedNodes.Add(CEBNode);
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  for (ExplodedNodeSet::iterator I = CleanedNodes.begin(),
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                 E = CleanedNodes.end(); I != E; ++I) {
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Step 4: Generate the CallExit and leave the callee's context.
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // CleanedNodes -> CEENode
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CallExitEnd Loc(calleeCtx, callerCtx);
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    bool isNew;
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ProgramStateRef CEEState = (*I == CEBNode) ? state : (*I)->getState();
193d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt    ExplodedNode *CEENode = G.getNode(Loc, CEEState, false, &isNew);
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CEENode->addPredecessor(*I, G);
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!isNew)
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Step 5: Perform the post-condition check of the CallExpr and enqueue the
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // result onto the work list.
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // CEENode -> Dst -> WorkList
20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
20237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt    SaveAndRestore<const NodeBuilderContext*> NBCSave(currentBuilderContext,
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        &Ctx);
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CallEventManager &CEMgr = getStateManager().getCallEventManager();
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CallEventRef<> Call = CEMgr.getCaller(calleeCtx, CEEState);
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ExplodedNodeSet DstPostCall;
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    getCheckerManager().runCheckersForPostCall(DstPostCall, CEENode, *Call,
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                               *this, true);
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ExplodedNodeSet Dst;
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (isa<ObjCMethodCall>(Call)) {
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      getCheckerManager().runCheckersForPostObjCMessage(Dst, DstPostCall,
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                                    cast<ObjCMethodCall>(*Call),
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                                        *this, true);
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    } else if (CE) {
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                                 *this, true);
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    } else {
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Dst.insert(DstPostCall);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Enqueue the next element in the block.
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                   PSI != PSE; ++PSI) {
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Engine.getWorkList()->enqueue(*PSI, calleeCtx->getCallSiteBlock(),
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                    calleeCtx->getIndex()+1);
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned getNumberStackFrames(const LocationContext *LCtx) {
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned count = 0;
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  while (LCtx) {
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (isa<StackFrameContext>(LCtx))
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      ++count;
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    LCtx = LCtx->getParent();
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return count;
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Determine if we should inline the call.
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool ExprEngine::shouldInlineDecl(const Decl *D, ExplodedNode *Pred) {
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const CFG *CalleeCFG = CalleeADC->getCFG();
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // It is possible that the CFG cannot be constructed.
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Be safe, and check if the CalleeCFG is valid.
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!CalleeCFG)
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (getNumberStackFrames(Pred->getLocationContext())
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        == AMgr.InlineMaxStackDepth)
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (Engine.FunctionSummaries->hasReachedMaxBlockCount(D))
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (CalleeCFG->getNumBlockIDs() > AMgr.InlineMaxFunctionSize)
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Do not inline variadic calls (for now).
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (BD->isVariadic())
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (FD->isVariadic())
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // It is possible that the live variables analysis cannot be
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // run.  If so, bail out.
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!CalleeADC->getAnalysis<RelaxedLiveVariables>())
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return true;
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// The GDM component containing the dynamic dispatch bifurcation info. When
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// the exact type of the receiver is not known, we want to explore both paths -
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// one on which we do inline it and the other one on which we don't. This is
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// done to ensure we do not drop coverage.
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// This is the map from the receiver region to a bool, specifying either we
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// consider this region's information precise or not along the given path.
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace clang {
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace ento {
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct DynamicDispatchBifurcationMap {};
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef llvm::ImmutableMap<const MemRegion*,
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                           int> DynamicDispatchBifur;
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate<> struct ProgramStateTrait<DynamicDispatchBifurcationMap>
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    :  public ProgramStatePartialTrait<DynamicDispatchBifur> {
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  static void *GDMIndex() { static int index; return &index; }
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}}
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                            NodeBuilder &Bldr, ExplodedNode *Pred,
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                            ProgramStateRef State) {
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(D);
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const LocationContext *CurLC = Pred->getLocationContext();
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const LocationContext *ParentOfCallee = 0;
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // FIXME: Refactor this check into a hypothetical CallEvent::canInline.
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  switch (Call.getKind()) {
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_Function:
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    break;
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_CXXMember:
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_CXXMemberOperator:
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!CXX_INLINING_ENABLED)
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    break;
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_CXXConstructor: {
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!CXX_INLINING_ENABLED)
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Only inline constructors and destructors if we built the CFGs for them
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // properly.
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!ADC->getCFGBuildOptions().AddImplicitDtors ||
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        !ADC->getCFGBuildOptions().AddInitializers)
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // FIXME: We don't handle constructors or destructors for arrays properly.
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const MemRegion *Target = Ctor.getCXXThisVal().getAsRegion();
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (Target && isa<ElementRegion>(Target))
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // FIXME: This is a hack. We don't handle temporary destructors
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // right now, so we shouldn't inline their constructors.
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr();
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (CtorExpr->getConstructionKind() == CXXConstructExpr::CK_Complete)
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (!Target || !isa<DeclRegion>(Target))
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return false;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    break;
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_CXXDestructor: {
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!CXX_INLINING_ENABLED)
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // Only inline constructors and destructors if we built the CFGs for them
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // properly.
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!ADC->getCFGBuildOptions().AddImplicitDtors ||
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        !ADC->getCFGBuildOptions().AddInitializers)
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const CXXDestructorCall &Dtor = cast<CXXDestructorCall>(Call);
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // FIXME: We don't handle constructors or destructors for arrays properly.
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const MemRegion *Target = Dtor.getCXXThisVal().getAsRegion();
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (Target && isa<ElementRegion>(Target))
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    break;
3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  }
3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  case CE_CXXAllocator:
3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    if (!CXX_INLINING_ENABLED)
3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt      return false;
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    // Do not inline allocators until we model deallocators.
3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    // This is unfortunate, but basically necessary for smart pointers and such.
3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    return false;
3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  case CE_Block: {
3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    const BlockDataRegion *BR = cast<BlockCall>(Call).getBlockRegion();
3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    assert(BR && "If we have the block definition we should have its region");
3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC,
3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                                                         cast<BlockDecl>(D),
3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                                                         BR);
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    break;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  case CE_ObjCMessage:
38104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    if (!(getAnalysisManager().IPAMode == DynamicDispatch ||
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          getAnalysisManager().IPAMode == DynamicDispatchBifurcate))
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return false;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    break;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!shouldInlineDecl(D, Pred))
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return false;
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!ParentOfCallee)
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ParentOfCallee = CallerSFC;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // This may be NULL, but that's fine.
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Expr *CallE = Call.getOriginExpr();
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Construct a new stack frame for the callee.
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const StackFrameContext *CalleeSFC =
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    CalleeADC->getStackFrame(ParentOfCallee, CallE,
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                             currentBuilderContext->getBlock(),
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                             currentStmtIdx);
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  CallEnter Loc(CallE, CalleeSFC, CurLC);
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Construct a new state which contains the mapping from actual to
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // formal arguments.
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  State = State->enterStackFrame(Call, CalleeSFC);
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  bool isNew;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (ExplodedNode *N = G.getNode(Loc, State, false, &isNew)) {
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    N->addPredecessor(Pred, G);
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (isNew)
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      Engine.getWorkList()->enqueue(N);
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // If we decided to inline the call, the successor has been manually
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // added onto the work list so remove it from the node builder.
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Bldr.takeNodes(Pred);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return true;
4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic ProgramStateRef getInlineFailedState(ProgramStateRef State,
4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt                                            const Stmt *CallE) {
4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  void *ReplayState = State->get<ReplayWithoutInlining>();
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!ReplayState)
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return 0;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(ReplayState == (const void*)CallE && "Backtracked to the wrong call.");
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  (void)CallE;
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return State->remove<ReplayWithoutInlining>();
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                               ExplodedNodeSet &dst) {
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Perform the previsit of the CallExpr.
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ExplodedNodeSet dstPreVisit;
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Get the call in its initial state. We use this as a template to perform
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // all the checks.
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  CallEventManager &CEMgr = getStateManager().getCallEventManager();
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  CallEventRef<SimpleCall> CallTemplate
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // Evaluate the function call.  We try each of the checkers
4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // to see if the can evaluate the function call.
4491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  ExplodedNodeSet dstCallEvaluated;
4501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
4511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt       I != E; ++I) {
4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt    evalCall(dstCallEvaluated, *I, *CallTemplate);
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // Finally, perform the post-condition check of the CallExpr and store
4561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // the created nodes in 'Dst'.
4571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // Note that if the call was inlined, dstCallEvaluated will be empty.
4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // The post-CallExpr check will occur in processCallExit.
4591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
46004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                                             *this);
46104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
46204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
46304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
464d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt                          const SimpleCall &Call) {
465d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt  // WARNING: At this time, the state attached to 'Call' may be older than the
466d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt  // state in 'Pred'. This is a minor optimization since CheckerManager will
467d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt  // use an updated CallEvent instance when calling checkers, but if 'Call' is
468d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt  // ever used directly in this function all callers should be updated to pass
46904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  // the most recent state. (It is probably not worth doing the work here since
47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // for some callers this will not be necessary.)
47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
47261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  // Run any pre-call checks using the generic call interface.
47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  ExplodedNodeSet dstPreVisit;
47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
4759bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
4769bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt  // Actually evaluate the function call.  We try each of the checkers
4779bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt  // to see if the can evaluate the function call, and get a callback at
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // defaultEvalCall if all of them fail.
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ExplodedNodeSet dstCallEvaluated;
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                             Call, *this);
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Finally, run any post-call checks.
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  getCheckerManager().runCheckersForPostCall(Dst, dstCallEvaluated,
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                             Call, *this);
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                            const LocationContext *LCtx,
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                            ProgramStateRef State) {
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Expr *E = Call.getOriginExpr();
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (!E)
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return State;
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Some method families have known return values.
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    switch (Msg->getMethodFamily()) {
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    default:
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      break;
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    case OMF_autorelease:
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    case OMF_retain:
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    case OMF_self: {
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // These methods return their receivers.
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return State->BindExpr(E, LCtx, C->getCXXThisVal());
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Conjure a symbol if the return value is unknown.
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  QualType ResultTy = Call.getResultType();
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  SValBuilder &SVB = getSValBuilder();
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned Count = currentBuilderContext->getCurrentBlockCount();
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  SVal R = SVB.getConjuredSymbolVal(0, E, LCtx, ResultTy, Count);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return State->BindExpr(E, LCtx, R);
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Conservatively evaluate call by invalidating regions and binding
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// a conjured return value.
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                      ExplodedNode *Pred, ProgramStateRef State) {
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  unsigned Count = currentBuilderContext->getCurrentBlockCount();
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  State = Call.invalidateRegions(Count, State);
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  State = bindReturnValue(Call, Pred->getLocationContext(), State);
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // And make the result node.
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  Bldr.generateNode(Call.getProgramPoint(), State, Pred);
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                 const CallEvent &CallTemplate) {
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Make sure we have the most recent state attached to the call.
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef State = Pred->getState();
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  CallEventRef<> Call = CallTemplate.cloneWithState(State);
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Try to inline the call.
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // The origin expression here is just used as a kind of checksum;
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // this should still be safe even for CallEvents that don't come from exprs.
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  const Expr *E = Call->getOriginExpr();
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef InlinedFailedState = getInlineFailedState(State, E);
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  if (InlinedFailedState) {
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    // If we already tried once and failed, make sure we don't retry later.
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    State = InlinedFailedState;
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  } else if (getAnalysisManager().shouldInlineCall()) {
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    RuntimeDefinition RD = Call->getRuntimeDefinition();
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    const Decl *D = RD.Decl;
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (D) {
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      // Explore with and without inlining the call.
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      const MemRegion *BifurReg = RD.Reg;
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (BifurReg &&
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          getAnalysisManager().IPAMode == DynamicDispatchBifurcate) {
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        BifurcateCall(BifurReg, *Call, D, Bldr, Pred);
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      } else {
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        // We are not bifurcating and we do have a Decl, so just inline.
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (inlineCall(*Call, D, Bldr, Pred, State))
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt          return;
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      }
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  // If we can't inline it, handle the return value and invalidate the regions.
5651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt  conservativeEvalCall(*Call, Bldr, Pred, State);
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ExprEngine::BifurcateCall(const MemRegion *BifurReg,
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                               const CallEvent &Call, const Decl *D,
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                               NodeBuilder &Bldr, ExplodedNode *Pred) {
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  assert(BifurReg);
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // Check if we've performed the split already - note, we only want
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // to split the path once per memory region.
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef State = Pred->getState();
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  DynamicDispatchBifur BM = State->get<DynamicDispatchBifurcationMap>();
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  for (DynamicDispatchBifur::iterator I = BM.begin(),
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                                      E = BM.end(); I != E; ++I) {
57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    if (I->first == BifurReg) {
58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      // If we are on "inline path", keep inlining if possible.
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      if (I->second == true)
58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt        if (inlineCall(Call, D, Bldr, Pred, State))
58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt          return;
58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      // If inline failed, or we are on the path where we assume we
58561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      // don't have enough info about the receiver to inline, conjure the
58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      // return value and invalidate the regions.
58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      conservativeEvalCall(Call, Bldr, Pred, State);
58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt      return;
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  }
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // If we got here, this is the first time we process a message to this
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  // region, so split the path.
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef IState =
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      State->set<DynamicDispatchBifurcationMap>(BifurReg, true);
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  inlineCall(Call, D, Bldr, Pred, IState);
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  ProgramStateRef NoIState =
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt      State->set<DynamicDispatchBifurcationMap>(BifurReg, false);
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  conservativeEvalCall(Call, Bldr, Pred, NoIState);
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  NumOfDynamicDispatchPathSplits++;
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt  return;
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
60604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
60704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
60804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                                 ExplodedNodeSet &Dst) {
60904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  ExplodedNodeSet dstPreVisit;
61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext);
61404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  if (RS->getRetValue()) {
61604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
61704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt                                  ei = dstPreVisit.end(); it != ei; ++it) {
61804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt      B.generateNode(RS, *it, (*it)->getState());
61904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    }
62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt  }
62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt