Beispiel #1
0
void CallInliner::EvalCall(ExplodedNodeSet& Dst, GRExprEngine& Engine,
                           GRStmtNodeBuilder& Builder, CallExpr* CE, SVal L,
                           ExplodedNode* Pred) {
  FunctionDecl const *FD = L.getAsFunctionDecl();
  if (!FD)
    return; // GRExprEngine is responsible for the autotransition.

  // Make a new LocationContext.
  StackFrameContext const *LocCtx =
  Engine.getAnalysisManager().getStackFrame(FD, Pred->getLocationContext(), CE);

  CFGBlock const *Entry = &(LocCtx->getCFG()->getEntry());

  assert (Entry->empty() && "Entry block must be empty.");

  assert (Entry->succ_size() == 1 && "Entry block must have 1 successor.");

  // Get the solitary successor.
  CFGBlock const *SuccB = *(Entry->succ_begin());

  // Construct an edge representing the starting location in the function.
  BlockEdge Loc(Entry, SuccB, LocCtx);

  GRState const *state = Builder.GetState(Pred);  
  state = Engine.getStoreManager().EnterStackFrame(state, LocCtx);

  bool isNew;
  ExplodedNode *SuccN = Engine.getGraph().getNode(Loc, state, &isNew);
  SuccN->addPredecessor(Pred, Engine.getGraph());

  Builder.Deferred.erase(Pred);

  // This is a hack. We really should not use the GRStmtNodeBuilder.
  if (isNew)
    Builder.getWorkList()->Enqueue(SuccN);

  Builder.HasGeneratedNode = true;
}
void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
                                       GRExprEngine& Eng,
                                       GRStmtNodeBuilder<GRState>& Builder,
                                       ObjCMessageExpr* ME,
                                       ExplodedNode<GRState>* Pred) {
  
  
  // The basic transfer function logic for message expressions does nothing.
  // We just invalidate all arguments passed in by references.
  
  GRStateManager& StateMgr = Eng.getStateManager();
  const GRState* St = Builder.GetState(Pred);
  
  for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
       I != E; ++I) {
    
    SVal V = StateMgr.GetSVal(St, *I);
    
    if (isa<Loc>(V))
      St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal());
  }
  
  Builder.MakeNode(Dst, ME, Pred, St);
}
void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<GRState>& Builder,
                            CallExpr* CE, SVal L,
                            ExplodedNode<GRState>* Pred) {
  
  GRStateManager& StateMgr = Eng.getStateManager();
  const GRState* St = Builder.GetState(Pred);
  
  // Invalidate all arguments passed in by reference (Locs).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    SVal V = StateMgr.GetSVal(St, *I);
    
    if (isa<loc::MemRegionVal>(V))
      St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal());
    else if (isa<nonloc::LocAsInteger>(V))
      St = StateMgr.BindLoc(St, cast<nonloc::LocAsInteger>(V).getLoc(),
                            UnknownVal());
    
  }
  
  // Make up a symbol for the return value of this function.  
  // FIXME: We eventually should handle structs and other compound types
  // that are returned by value.
  QualType T = CE->getType();  
  if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {    
    unsigned Count = Builder.getCurrentBlockCount();
    SVal X = Eng.getValueManager().getConjuredSymbolVal(CE, Count);
    St = StateMgr.BindExpr(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }  
    
  Builder.MakeNode(Dst, CE, Pred, St);
}