673{
674
675
677 for (
const ICFGNode* node :
nodes)
678 {
679 if (node != nullptr && node->getFun() != nullptr)
680 {
681 keptFunctions.insert(node->getFun());
682 }
683 }
684
685
686 std::queue<const FunObjVar*> functionWorklist;
687 for (const FunObjVar* fun : keptFunctions)
688 functionWorklist.push(fun);
689
692 it != eit; ++it)
693 {
694 const CallGraphNode* node = it->second;
695 if (node !=
nullptr && node->
getFunction() !=
nullptr)
697 }
698
700 while (!functionWorklist.empty())
701 {
702 const FunObjVar* target = functionWorklist.front();
703 functionWorklist.pop();
704 const auto nodeIt = functionToNode.find(target);
705 if (nodeIt == functionToNode.end())
706 continue;
707
708 const CallGraphNode* node = nodeIt->second;
709 for (
const CallGraphEdge* inEdge : node->
getInEdges())
710 {
711 if (inEdge == nullptr)
712 continue;
713 const CallGraphNode* callerNode = inEdge->getSrcNode();
714 if (callerNode !=
nullptr && callerNode->
getFunction() !=
nullptr)
715 {
716 const FunObjVar* callerFun = callerNode->
getFunction();
717 if (visitedFunctions.find(callerFun) == visitedFunctions.end())
718 {
719 keptFunctions.insert(callerFun);
720 visitedFunctions.insert(callerFun);
721 functionWorklist.push(callerFun);
722 }
723 }
724 }
725 }
726
727
728 ICFG* icfg =
svfir->getICFG();
730 for (const FunObjVar* fun : keptFunctions)
731 {
732 if (fun == nullptr)
733 continue;
734
735
736 if (fun->hasBasicBlock())
737 {
739 expandedNodes.insert(entry);
741 expandedNodes.insert(exit);
742 }
743
744
745 const auto funNodeIt = functionToNode.find(fun);
746 if (funNodeIt != functionToNode.end())
747 {
748 const CallGraphNode* calleeNode = funNodeIt->second;
749
750
751 for (
const CallGraphEdge* inEdge : calleeNode->
getInEdges())
752 {
753 if (inEdge == nullptr)
754 continue;
755
757 inEdge->getDirectCalls();
759 inEdge->getIndirectCalls();
760
761 for (const CallICFGNode* callNode : directCalls)
762 {
763 if (callNode != nullptr)
764 {
765 expandedNodes.insert(callNode);
766 const RetICFGNode* retNode = callNode->getRetICFGNode();
767 if (retNode != nullptr)
768 expandedNodes.insert(retNode);
769 }
770 }
771
772 for (const CallICFGNode* callNode : indirectCalls)
773 {
774 if (callNode != nullptr)
775 {
776 expandedNodes.insert(callNode);
777 const RetICFGNode* retNode = callNode->getRetICFGNode();
778 if (retNode != nullptr)
779 expandedNodes.insert(retNode);
780 }
781 }
782 }
783 }
784 }
785
786 return expandedNodes;
787}
Set< const CallICFGNode * > CallInstSet
const FunObjVar * getFunction() const
Get function of this call node.
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)