void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call) { // Try to inline the call. // The origin expression here is just used as a kind of checksum; // for CallEvents that do not have origin expressions, this should still be // safe. const Expr *E = Call.getOriginExpr(); ProgramStateRef state = getInlineFailedState(Pred, E); if (state == 0 && inlineCall(Dst, Call, Pred)) return; // If we can't inline it, handle the return value and invalidate the regions. NodeBuilder Bldr(Pred, Dst, *currentBuilderContext); // Invalidate any regions touched by the call. unsigned Count = currentBuilderContext->getCurrentBlockCount(); if (state == 0) state = Pred->getState(); state = Call.invalidateRegions(Count, state); // Conjure a symbol value to use as the result. if (E) { QualType ResultTy = Call.getResultType(); SValBuilder &SVB = getSValBuilder(); const LocationContext *LCtx = Pred->getLocationContext(); SVal RetVal = SVB.getConjuredSymbolVal(0, E, LCtx, ResultTy, Count); state = state->BindExpr(E, LCtx, RetVal); } // And make the result node. Bldr.generateNode(Call.getProgramPoint(), state, Pred); }
void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, const CallEvent &Call) { ProgramStateRef State = 0; const Expr *E = Call.getOriginExpr(); // Try to inline the call. // The origin expression here is just used as a kind of checksum; // for CallEvents that do not have origin expressions, this should still be // safe. if (!isa<ObjCMethodCall>(Call)) { State = getInlineFailedState(Pred->getState(), E); if (State == 0 && inlineCall(Call, Pred)) { // If we inlined the call, the successor has been manually added onto // the work list and we should not consider it for subsequent call // handling steps. Bldr.takeNodes(Pred); return; } } // If we can't inline it, handle the return value and invalidate the regions. if (State == 0) State = Pred->getState(); // Invalidate any regions touched by the call. unsigned Count = currentBuilderContext->getCurrentBlockCount(); State = Call.invalidateRegions(Count, State); // Construct and bind the return value. State = bindReturnValue(Call, Pred->getLocationContext(), State); // And make the result node. Bldr.generateNode(Call.getProgramPoint(), State, Pred); }
// Conservatively evaluate call by invalidating regions and binding // a conjured return value. void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State) { State = Call.invalidateRegions(currBldrCtx->blockCount(), State); State = bindReturnValue(Call, Pred->getLocationContext(), State); // And make the result node. Bldr.generateNode(Call.getProgramPoint(), State, Pred); }