SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, const GRState *state, 
                             BinaryOperator::Opcode Op, Loc L, NonLoc R) {
  
  // Special case: 'R' is an integer that has the same width as a pointer and
  // we are using the integer location in a comparison.  Normally this cannot be
  // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32
  // can generate comparisons that trigger this code.
  // FIXME: Are all locations guaranteed to have pointer width?
  if (BinaryOperator::isEqualityOp(Op)) {
    if (nonloc::ConcreteInt *RInt = dyn_cast<nonloc::ConcreteInt>(&R)) {
      const llvm::APSInt *X = &RInt->getValue();
      ASTContext &C = Eng.getContext();
      if (C.getTypeSize(C.VoidPtrTy) == X->getBitWidth()) {
        // Convert the signedness of the integer (if necessary).
        if (X->isSigned())
          X = &Eng.getBasicVals().getValue(*X, true);          
        
        return EvalBinOp(Eng, Op, L, loc::ConcreteInt(*X));
      }
    }
  }
  
  // Delegate pointer arithmetic to store manager.
  return Eng.getStoreManager().EvalBinOp(state, Op, L, R);
}
Beispiel #2
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;
}