CfgConstEdgeSet findCallReturnEdges(const ControlFlowGraph::ConstVertexIterator &callSite) { CfgConstEdgeSet retval; for (ControlFlowGraph::ConstEdgeIterator ei=callSite->outEdges().begin(); ei!=callSite->outEdges().end(); ++ei) { if (ei->value().type() == E_CALL_RETURN) retval.insert(ei); } return retval; }
// Internal: Run the may-return analysis on the callees and return true if any of them have a positive or indeterminate // may-return property. boost::logic::tribool Partitioner::mayReturnDoesCalleeReturn(const ControlFlowGraph::ConstVertexIterator &caller, std::vector<MayReturnVertexInfo> &vertexInfo) const { ASSERT_require(caller != cfg_.vertices().end()); if (!vertexInfo[caller->id()].processedCallees) { vertexInfo[caller->id()].anyCalleesReturn = false; bool hasPositiveCallee = false, hasIndeterminateCallee = false; BOOST_FOREACH (const ControlFlowGraph::Edge &edge, caller->outEdges()) { if (edge.value().type() == E_FUNCTION_CALL) { ControlFlowGraph::ConstVertexIterator callee = edge.target(); bool mayReturn = false; if (!basicBlockOptionalMayReturn(callee, vertexInfo).assignTo(mayReturn)) { hasIndeterminateCallee = true; } else if (mayReturn) { hasPositiveCallee = true; break; } } } if (hasPositiveCallee) { vertexInfo[caller->id()].anyCalleesReturn = true; } else if (hasIndeterminateCallee) { vertexInfo[caller->id()].anyCalleesReturn = boost::logic::indeterminate; } vertexInfo[caller->id()].processedCallees = true; }