ExprEngineCallAndReturn.cpp revision 01561d1039bfdda61edd20eed939011a8632c7c7
12cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- C++ -*-===//
22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//                     The LLVM Compiler Infrastructure
42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This file is distributed under the University of Illinois Open Source
62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// License. See LICENSE.TXT for details.
72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===//
92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//  This file defines ExprEngine's support for calls and returns.
112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===//
132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/StaticAnalyzer/Core/CheckerManager.h"
15e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/DeclCXX.h"
182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/ADT/SmallSet.h"
192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/SaveAndRestore.h"
200b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorusing namespace clang;
22a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallusing namespace ento;
237c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner
247c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattnervoid ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) {
2583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  // Get the entry block in the CFG of the callee.
2614f79002e58556798e86168c63e48d533287eda5Douglas Gregor  const StackFrameContext *calleeCtx = CE.getCalleeContext();
273251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  const CFG *CalleeCFG = calleeCtx->getCFG();
2814f79002e58556798e86168c63e48d533287eda5Douglas Gregor  const CFGBlock *Entry = &(CalleeCFG->getEntry());
29bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor
302bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor  // Validate the CFG.
31ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor  assert(Entry->empty());
3217fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  assert(Entry->succ_size() == 1);
3317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
342596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar  // Get the solitary sucessor.
352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const CFGBlock *Succ = *(Entry->succ_begin());
362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
3714f79002e58556798e86168c63e48d533287eda5Douglas Gregor  // Construct an edge representing the starting location in the callee.
38b64c19365deab788753d29c9bc881253c3f16f37Douglas Gregor  BlockEdge Loc(Entry, Succ, calleeCtx);
393c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattner
402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Construct a new state which contains the mapping from actual to
412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // formal arguments.
422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const LocationContext *callerCtx = Pred->getLocationContext();
432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ProgramStateRef state = Pred->getState()->enterStackFrame(callerCtx,
442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                                                                calleeCtx);
4512b1c7615d4f9a2edc544be499f895f16ac100edChris Lattner
462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Construct a new node and add it to the worklist.
472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  bool isNew;
482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  Node->addPredecessor(Pred, G);
502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (isNew)
512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    Engine.getWorkList()->enqueue(Node);
522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const ReturnStmt *getReturnStmt(const ExplodedNode *Node) {
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  while (Node) {
564fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor    const ProgramPoint &PP = Node->getLocation();
572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    // Skip any BlockEdges.
582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (isa<BlockEdge>(PP) || isa<CallExit>(PP)) {
592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      assert(Node->pred_size() == 1);
602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      Node = *Node->pred_begin();
612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      continue;
622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    }
632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) {
642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      const Stmt *S = SP->getStmt();
652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      return dyn_cast<ReturnStmt>(S);
662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    }
672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    break;
682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  return 0;
702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid ExprEngine::processCallExit(ExplodedNode *Pred) {
732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ProgramStateRef state = Pred->getState();
742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const StackFrameContext *calleeCtx =
752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    Pred->getLocationContext()->getCurrentStackFrame();
762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const LocationContext *callerCtx = calleeCtx->getParent();
772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const Stmt *CE = calleeCtx->getCallSite();
782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // If the callee returns an expression, bind its value to CallExpr.
802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (const ReturnStmt *RS = getReturnStmt(Pred)) {
812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    const LocationContext *LCtx = Pred->getLocationContext();
822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    SVal V = state->getSVal(RS, LCtx);
832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    state = state->BindExpr(CE, callerCtx, V);
842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Bind the constructed object value to CXXConstructExpr.
872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    const CXXThisRegion *ThisR =
892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    SVal ThisV = state->getSVal(ThisR);
922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    // Always bind the region to the CXXConstructExpr.
932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    state = state->BindExpr(CCE, Pred->getLocationContext(), ThisV);
942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  static SimpleProgramPointTag returnTag("ExprEngine : Call Return");
972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  PostStmt Loc(CE, callerCtx, &returnTag);
982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  bool isNew;
992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ExplodedNode *N = G.getNode(Loc, state, false, &isNew);
1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  N->addPredecessor(Pred, G);
1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (!isNew)
1022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return;
1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Perform the post-condition check of the CallExpr.
1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNodeSet Dst;
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), N);
1072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  SaveAndRestore<const NodeBuilderContext*> NBCSave(currentBuilderContext,
1082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                                                    &Ctx);
1092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());
1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  getCheckerManager().runCheckersForPostStmt(Dst, N, CE, *this,
1122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                                             /* wasInlined */ true);
1130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Enqueue the next element in the block.
1152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); I != E; ++I) {
1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    Engine.getWorkList()->enqueue(*I,
1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                                  calleeCtx->getCallSiteBlock(),
1182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                                  calleeCtx->getIndex()+1);
1192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
1202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic unsigned getNumberStackFrames(const LocationContext *LCtx) {
1232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  unsigned count = 0;
1242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  while (LCtx) {
1252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (isa<StackFrameContext>(LCtx))
1262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      ++count;
1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    LCtx = LCtx->getParent();
1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
1297e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor  return count;
1307e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor}
131c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor
1322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// Determine if we should inline the call.
1332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorbool ExprEngine::shouldInlineDecl(const FunctionDecl *FD, ExplodedNode *Pred) {
1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(FD);
1352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const CFG *CalleeCFG = CalleeADC->getCFG();
1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // It is possible that the CFG cannot be constructed.
1382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Be safe, and check if the CalleeCFG is valid.
1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (!CalleeCFG)
1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (getNumberStackFrames(Pred->getLocationContext())
1432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        == AMgr.InlineMaxStackDepth)
1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (Engine.FunctionSummaries->hasReachedMaxBlockCount(FD))
1472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (CalleeCFG->getNumBlockIDs() > AMgr.InlineMaxFunctionSize)
1502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  return true;
1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
1542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// For now, skip inlining variadic functions.
1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// We also don't inline blocks.
1572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic bool shouldInlineCallExpr(const CallExpr *CE, ExprEngine *E) {
1582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (!E->getAnalysisManager().shouldInlineCall())
1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  QualType callee = CE->getCallee()->getType();
1612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  const FunctionProtoType *FT = 0;
162465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  if (const PointerType *PT = callee->getAs<PointerType>())
163465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    FT = dyn_cast<FunctionProtoType>(PT->getPointeeType());
164465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl  else if (const BlockPointerType *BT = callee->getAs<BlockPointerType>()) {
165465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    // FIXME: inline blocks.
166465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl    // FT = dyn_cast<FunctionProtoType>(BT->getPointeeType());
1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    (void) BT;
1682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
1702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // If we have no prototype, assume the function is okay.
1712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (!FT)
1722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return true;
1732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Skip inlining of variadic functions.
1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  return !FT->isVariadic();
176c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor}
1772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorbool ExprEngine::InlineCall(ExplodedNodeSet &Dst,
1792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                            const CallExpr *CE,
1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                            ExplodedNode *Pred) {
1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (!shouldInlineCallExpr(CE, this))
1822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ProgramStateRef state = Pred->getState();
185395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  const Expr *Callee = CE->getCallee();
186395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  const FunctionDecl *FD =
187395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson    state->getSVal(Callee, Pred->getLocationContext()).getAsFunctionDecl();
188395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson  if (!FD || !FD->hasBody(FD))
189395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson    return false;
1902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  switch (CE->getStmtClass()) {
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    default:
1932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      // FIXME: Handle C++.
1942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      break;
1952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    case Stmt::CallExprClass: {
1962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      if (!shouldInlineDecl(FD, Pred))
1972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        return false;
1982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      // Construct a new stack frame for the callee.
2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(FD);
2012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      const StackFrameContext *CallerSFC =
2022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      Pred->getLocationContext()->getCurrentStackFrame();
2032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      const StackFrameContext *CalleeSFC =
2042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      CalleeADC->getStackFrame(CallerSFC, CE,
2052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                               currentBuilderContext->getBlock(),
2067da2431c23ef1ee8acb114e39692246e1801afc2John McCall                               currentStmtIdx);
2077da2431c23ef1ee8acb114e39692246e1801afc2John McCall
2087da2431c23ef1ee8acb114e39692246e1801afc2John McCall      CallEnter Loc(CE, CalleeSFC, Pred->getLocationContext());
2097da2431c23ef1ee8acb114e39692246e1801afc2John McCall      bool isNew;
2107da2431c23ef1ee8acb114e39692246e1801afc2John McCall      if (ExplodedNode *N = G.getNode(Loc, state, false, &isNew)) {
2117da2431c23ef1ee8acb114e39692246e1801afc2John McCall        N->addPredecessor(Pred, G);
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if (isNew)
21349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall          Engine.getWorkList()->enqueue(N);
21449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall      }
21549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall      return true;
21649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    }
21749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
21849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  return false;
21949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall}
22049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall
2212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic bool isPointerToConst(const ParmVarDecl *ParamDecl) {
2222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  QualType PointeeTy = ParamDecl->getOriginalType()->getPointeeType();
2236a2bfb2ead4489db37e80b696a6d7cc073c76fd7Douglas Gregor  if (PointeeTy != QualType() && PointeeTy.isConstQualified() &&
2242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      !PointeeTy->isAnyPointerType() && !PointeeTy->isReferenceType()) {
2252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return true;
2262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
2272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  return false;
2286a2bfb2ead4489db37e80b696a6d7cc073c76fd7Douglas Gregor}
2292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
2302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// Try to retrieve the function declaration and find the function parameter
2312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// types which are pointers/references to a non-pointer const.
2322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// We do not invalidate the corresponding argument regions.
2332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
2342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor                       const CallOrObjCMessage &Call) {
235446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff  const Decl *CallDecl = Call.getDecl();
236446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff  if (!CallDecl)
237446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff    return;
238c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff
2392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(CallDecl)) {
2402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    const IdentifierInfo *II = FDecl->getIdentifier();
241d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff
242d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    // List the cases, where the region should be invalidated even if the
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // argument is const.
2442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (II) {
245d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      StringRef FName = II->getName();
246446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff      //  - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
247446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff      // value into thread local storage. The value can later be retrieved with
248d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      // 'void *ptheread_getspecific(pthread_key)'. So even thought the
2492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      // parameter is 'const void *', the region escapes through the call.
2502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      //  - funopen - sets a buffer for future IO calls.
251a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      //  - ObjC functions that end with "NoCopy" can free memory, of the passed
252a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // in buffer.
253a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // - Many CF containers allow objects to escape through custom
254a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // allocators/deallocators upon container construction.
255a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
256a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // be deallocated by NSMapRemove.
257a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      if (FName == "pthread_setspecific" ||
258a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          FName == "funopen" ||
259a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          FName.endswith("NoCopy") ||
260a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          (FName.startswith("NS") &&
26151bd803fbdade51d674598ed45da3d54190a656cJohn McCall            (FName.find("Insert") != StringRef::npos)) ||
262a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          Call.isCFCGAllowingEscape(FName))
26351bd803fbdade51d674598ed45da3d54190a656cJohn McCall        return;
264a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
265a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
26651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    for (unsigned Idx = 0, E = Call.getNumArgs(); Idx != E; ++Idx) {
26751bd803fbdade51d674598ed45da3d54190a656cJohn McCall      if (FDecl && Idx < FDecl->getNumParams()) {
268a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall        if (isPointerToConst(FDecl->getParamDecl(Idx)))
269a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          PreserveArgs.insert(Idx);
270a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      }
271a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall    }
27251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    return;
27351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  }
27451bd803fbdade51d674598ed45da3d54190a656cJohn McCall
27551bd803fbdade51d674598ed45da3d54190a656cJohn McCall  if (const ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(CallDecl)) {
27651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    assert(MDecl->param_size() <= Call.getNumArgs());
27751bd803fbdade51d674598ed45da3d54190a656cJohn McCall    unsigned Idx = 0;
27851bd803fbdade51d674598ed45da3d54190a656cJohn McCall    for (clang::ObjCMethodDecl::param_const_iterator
27951bd803fbdade51d674598ed45da3d54190a656cJohn McCall         I = MDecl->param_begin(), E = MDecl->param_end(); I != E; ++I, ++Idx) {
28051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      if (isPointerToConst(*I))
28151bd803fbdade51d674598ed45da3d54190a656cJohn McCall        PreserveArgs.insert(Idx);
28251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
28351bd803fbdade51d674598ed45da3d54190a656cJohn McCall    return;
28451bd803fbdade51d674598ed45da3d54190a656cJohn McCall  }
28551bd803fbdade51d674598ed45da3d54190a656cJohn McCall}
28651bd803fbdade51d674598ed45da3d54190a656cJohn McCall
28751bd803fbdade51d674598ed45da3d54190a656cJohn McCallProgramStateRef
28851bd803fbdade51d674598ed45da3d54190a656cJohn McCallExprEngine::invalidateArguments(ProgramStateRef State,
28951bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                const CallOrObjCMessage &Call,
29051bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                const LocationContext *LC) {
29151bd803fbdade51d674598ed45da3d54190a656cJohn McCall  SmallVector<const MemRegion *, 8> RegionsToInvalidate;
29251bd803fbdade51d674598ed45da3d54190a656cJohn McCall
29351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  if (Call.isObjCMessage()) {
29451bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // Invalidate all instance variables of the receiver of an ObjC message.
29551bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // FIXME: We should be able to do better with inter-procedural analysis.
29651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (const MemRegion *MR = Call.getInstanceMessageReceiver(LC).getAsRegion())
29751bd803fbdade51d674598ed45da3d54190a656cJohn McCall      RegionsToInvalidate.push_back(MR);
29851bd803fbdade51d674598ed45da3d54190a656cJohn McCall
29951bd803fbdade51d674598ed45da3d54190a656cJohn McCall  } else if (Call.isCXXCall()) {
30051bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // Invalidate all instance variables for the callee of a C++ method call.
30151bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // FIXME: We should be able to do better with inter-procedural analysis.
30251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // FIXME: We can probably do better for const versus non-const methods.
30351bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (const MemRegion *Callee = Call.getCXXCallee().getAsRegion())
30451bd803fbdade51d674598ed45da3d54190a656cJohn McCall      RegionsToInvalidate.push_back(Callee);
30551bd803fbdade51d674598ed45da3d54190a656cJohn McCall
30651bd803fbdade51d674598ed45da3d54190a656cJohn McCall  } else if (Call.isFunctionCall()) {
30751bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // Block calls invalidate all captured-by-reference values.
30851bd803fbdade51d674598ed45da3d54190a656cJohn McCall    SVal CalleeVal = Call.getFunctionCallee();
30951bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (const MemRegion *Callee = CalleeVal.getAsRegion()) {
31051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      if (isa<BlockDataRegion>(Callee))
31151bd803fbdade51d674598ed45da3d54190a656cJohn McCall        RegionsToInvalidate.push_back(Callee);
31251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
31351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  }
31451bd803fbdade51d674598ed45da3d54190a656cJohn McCall
31551bd803fbdade51d674598ed45da3d54190a656cJohn McCall  // Indexes of arguments whose values will be preserved by the call.
31651bd803fbdade51d674598ed45da3d54190a656cJohn McCall  llvm::SmallSet<unsigned, 1> PreserveArgs;
31751bd803fbdade51d674598ed45da3d54190a656cJohn McCall  findPtrToConstParams(PreserveArgs, Call);
31851bd803fbdade51d674598ed45da3d54190a656cJohn McCall
31951bd803fbdade51d674598ed45da3d54190a656cJohn McCall  for (unsigned idx = 0, e = Call.getNumArgs(); idx != e; ++idx) {
32051bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (PreserveArgs.count(idx))
32151bd803fbdade51d674598ed45da3d54190a656cJohn McCall      continue;
32251bd803fbdade51d674598ed45da3d54190a656cJohn McCall
32351bd803fbdade51d674598ed45da3d54190a656cJohn McCall    SVal V = Call.getArgSVal(idx);
32451bd803fbdade51d674598ed45da3d54190a656cJohn McCall
32551bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // If we are passing a location wrapped as an integer, unwrap it and
32651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    // invalidate the values referred by the location.
32751bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
32851bd803fbdade51d674598ed45da3d54190a656cJohn McCall      V = Wrapped->getLoc();
32951bd803fbdade51d674598ed45da3d54190a656cJohn McCall    else if (!isa<Loc>(V))
33051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      continue;
33151bd803fbdade51d674598ed45da3d54190a656cJohn McCall
33251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    if (const MemRegion *R = V.getAsRegion()) {
33351bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // Invalidate the value of the variable passed by reference.
33451bd803fbdade51d674598ed45da3d54190a656cJohn McCall
33551bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // Are we dealing with an ElementRegion?  If the element type is
33651bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // a basic integer type (e.g., char, int) and the underlying region
33751bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // is a variable region then strip off the ElementRegion.
33851bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // FIXME: We really need to think about this for the general case
33951bd803fbdade51d674598ed45da3d54190a656cJohn McCall      //   as sometimes we are reasoning about arrays and other times
34051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      //   about (char*), etc., is just a form of passing raw bytes.
34151bd803fbdade51d674598ed45da3d54190a656cJohn McCall      //   e.g., void *p = alloca(); foo((char*)p);
34251bd803fbdade51d674598ed45da3d54190a656cJohn McCall      if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
34351bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // Checking for 'integral type' is probably too promiscuous, but
34451bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // we'll leave it in for now until we have a systematic way of
34551bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // handling all of these cases.  Eventually we need to come up
34651bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // with an interface to StoreManager so that this logic can be
34751bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // appropriately delegated to the respective StoreManagers while
34851bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // still allowing us to do checker-specific logic (e.g.,
34951bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // invalidating reference counts), probably via callbacks.
35051bd803fbdade51d674598ed45da3d54190a656cJohn McCall        if (ER->getElementType()->isIntegralOrEnumerationType()) {
35151bd803fbdade51d674598ed45da3d54190a656cJohn McCall          const MemRegion *superReg = ER->getSuperRegion();
352a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall          if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
35351bd803fbdade51d674598ed45da3d54190a656cJohn McCall              isa<ObjCIvarRegion>(superReg))
35451bd803fbdade51d674598ed45da3d54190a656cJohn McCall            R = cast<TypedRegion>(superReg);
355a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall        }
35651bd803fbdade51d674598ed45da3d54190a656cJohn McCall        // FIXME: What about layers of ElementRegions?
35751bd803fbdade51d674598ed45da3d54190a656cJohn McCall      }
358a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
35951bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // Mark this region for invalidation.  We batch invalidate regions
36051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // below for efficiency.
361a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      RegionsToInvalidate.push_back(R);
36251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    } else {
36351bd803fbdade51d674598ed45da3d54190a656cJohn McCall      // Nuke all other arguments passed by reference.
364a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall      // FIXME: is this necessary or correct? This handles the non-Region
36549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall      //  cases.  Is it ever valid to store to these?
36649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall      State = State->unbindLoc(cast<Loc>(V));
36749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall    }
36849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall  }
36951bd803fbdade51d674598ed45da3d54190a656cJohn McCall
37051bd803fbdade51d674598ed45da3d54190a656cJohn McCall  // Invalidate designated regions using the batch invalidation API.
371833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
372833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  // FIXME: We can have collisions on the conjured symbol if the
373833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  //  expression *I also creates conjured symbols.  We probably want
374833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  //  to identify conjured symbols by an expression pair: the enclosing
375833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  //  expression (the context) and the expression itself.  This should
376a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall  //  disambiguate conjured symbols.
37751bd803fbdade51d674598ed45da3d54190a656cJohn McCall  unsigned Count = currentBuilderContext->getCurrentBlockCount();
37851bd803fbdade51d674598ed45da3d54190a656cJohn McCall  StoreManager::InvalidatedSymbols IS;
379a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
38051bd803fbdade51d674598ed45da3d54190a656cJohn McCall  // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
38151bd803fbdade51d674598ed45da3d54190a656cJohn McCall  //  global variables.
382a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall  return State->invalidateRegions(RegionsToInvalidate,
38351bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                  Call.getOriginExpr(), Count, LC,
38451bd803fbdade51d674598ed45da3d54190a656cJohn McCall                                  &IS, &Call);
38554e14c4db764c0636160d26c5bbf491637c83a76John McCall
38654e14c4db764c0636160d26c5bbf491637c83a76John McCall}
38754e14c4db764c0636160d26c5bbf491637c83a76John McCall
38854e14c4db764c0636160d26c5bbf491637c83a76John McCallstatic ProgramStateRef getReplayWithoutInliningState(ExplodedNode *&N,
389a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall                                                     const CallExpr *CE) {
39051bd803fbdade51d674598ed45da3d54190a656cJohn McCall  void *ReplayState = N->getState()->get<ReplayWithoutInlining>();
39151bd803fbdade51d674598ed45da3d54190a656cJohn McCall  if (!ReplayState)
39251bd803fbdade51d674598ed45da3d54190a656cJohn McCall    return 0;
39351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  const CallExpr *ReplayCE = reinterpret_cast<const CallExpr*>(ReplayState);
39454e14c4db764c0636160d26c5bbf491637c83a76John McCall  if (CE == ReplayCE) {
39554e14c4db764c0636160d26c5bbf491637c83a76John McCall    return N->getState()->remove<ReplayWithoutInlining>();
39654e14c4db764c0636160d26c5bbf491637c83a76John McCall  }
39754e14c4db764c0636160d26c5bbf491637c83a76John McCall  return 0;
39854e14c4db764c0636160d26c5bbf491637c83a76John McCall}
399a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
400a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
4014dcf151a555ff51e4d643e8e6eeb80f121d11d1bChris Lattner                               ExplodedNodeSet &dst) {
4022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  // Perform the previsit of the CallExpr.
4032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ExplodedNodeSet dstPreVisit;
4042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
405b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
406b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner  // Now evaluate the call itself.
407b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner  class DefaultEval : public GraphExpander {
408b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    ExprEngine &Eng;
409b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    const CallExpr *CE;
410b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner  public:
411b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
412b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    DefaultEval(ExprEngine &eng, const CallExpr *ce)
413b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    : Eng(eng), CE(ce) {}
414b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner    virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) {
415b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
416b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      ProgramStateRef state = getReplayWithoutInliningState(Pred, CE);
417b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
418b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      // First, try to inline the call.
419b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      if (state == 0 && Eng.InlineCall(Dst, CE, Pred))
420b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner        return;
421b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
422b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      // First handle the return value.
423b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      StmtNodeBuilder Bldr(Pred, Dst, *Eng.currentBuilderContext);
424b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner
425b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      // Get the callee.
426b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      const Expr *Callee = CE->getCallee()->IgnoreParens();
427b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner      if (state == 0)
4280558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        state = Pred->getState();
4290558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      SVal L = state->getSVal(Callee, Pred->getLocationContext());
4300558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4310558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      // Figure out the result type. We do this dance to handle references.
4320558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      QualType ResultTy;
4330558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      if (const FunctionDecl *FD = L.getAsFunctionDecl())
4340558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        ResultTy = FD->getResultType();
4350558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      else
4360558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        ResultTy = CE->getType();
4370558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4380558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      if (CE->isLValue())
4390558df2da807646e65d4fa290f4e92114af1a746Chris Lattner        ResultTy = Eng.getContext().getPointerType(ResultTy);
4400558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4410558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      // Conjure a symbol value to use as the result.
4420558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      SValBuilder &SVB = Eng.getSValBuilder();
4430558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      unsigned Count = Eng.currentBuilderContext->getCurrentBlockCount();
4440558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      const LocationContext *LCtx = Pred->getLocationContext();
4450558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      SVal RetVal = SVB.getConjuredSymbolVal(0, CE, LCtx, ResultTy, Count);
4460558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4470558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      // Generate a new state with the return value set.
4480558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      state = state->BindExpr(CE, LCtx, RetVal);
4490558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4500558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      // Invalidate the arguments.
4510558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      state = Eng.invalidateArguments(state, CallOrObjCMessage(CE, state, LCtx),
4520558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                      LCtx);
4530558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4540558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      // And make the result node.
4550558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      Bldr.generateNode(CE, Pred, state);
4560558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
4570558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  };
4580558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4590558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  // Finally, evaluate the function call.  We try each of the checkers
4600558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  // to see if the can evaluate the function call.
4610558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  ExplodedNodeSet dstCallEvaluated;
4620558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  DefaultEval defEval(*this, CE);
4630558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated,
4640558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                             dstPreVisit,
4650558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                             CE, *this, &defEval);
4660558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4670558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  // Finally, perform the post-condition check of the CallExpr and store
4680558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  // the created nodes in 'Dst'.
4690558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
4700558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                             *this);
4710558df2da807646e65d4fa290f4e92114af1a746Chris Lattner}
4720558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4730558df2da807646e65d4fa290f4e92114af1a746Chris Lattnervoid ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
4740558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                 ExplodedNodeSet &Dst) {
4750558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4760558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  ExplodedNodeSet dstPreVisit;
4770558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
4780558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4790558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext);
4800558df2da807646e65d4fa290f4e92114af1a746Chris Lattner
4810558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  if (RS->getRetValue()) {
4820558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
4830558df2da807646e65d4fa290f4e92114af1a746Chris Lattner                                  ei = dstPreVisit.end(); it != ei; ++it) {
4840558df2da807646e65d4fa290f4e92114af1a746Chris Lattner      B.generateNode(RS, *it, (*it)->getState());
4850558df2da807646e65d4fa290f4e92114af1a746Chris Lattner    }
4860558df2da807646e65d4fa290f4e92114af1a746Chris Lattner  }
4870558df2da807646e65d4fa290f4e92114af1a746Chris Lattner}
4880558df2da807646e65d4fa290f4e92114af1a746Chris Lattner