46 bb = f->getEntryBlock();
53 std::stringstream rawstr(str);
54 rawstr <<
"ICFGNode" <<
getId();
66 std::stringstream rawstr(str);
67 rawstr <<
"GlobalICFGNode" <<
getId();
69 rawstr <<
"\n" << stmt->toString();
77 std::stringstream rawstr(str);
78 rawstr <<
"IntraICFGNode" <<
getId();
81 rawstr <<
"\n" << stmt->toString();
91 std::stringstream rawstr(str);
92 rawstr <<
"FunEntryICFGNode" <<
getId();
98 rawstr <<
"\n" << stmt->toString();
104 return "function entry: " +
fun->getSourceLoc();
111 std::stringstream rawstr(str);
112 rawstr <<
"FunExitICFGNode" <<
getId();
113 rawstr <<
" {fun: " <<
fun->getName();
117 rawstr << intraICFGNode->getSourceLoc();
120 rawstr <<
"\n" << stmt->toString();
126 return "function ret: " +
fun->getSourceLoc();
132 std::stringstream rawstr(str);
133 rawstr <<
"CallICFGNode" <<
getId();
136 rawstr <<
"\n" << stmt->toString();
145 std::stringstream rawstr(str);
146 rawstr <<
"RetICFGNode" <<
getId();
149 rawstr <<
"\n" << stmt->toString();
158 std::stringstream rawstr(str);
159 rawstr <<
"ICFGEdge: [ICFGNode" <<
getDstID() <<
" <-- ICFGNode" <<
getSrcID() <<
"]\t";
166 std::stringstream rawstr(str);
168 rawstr <<
"IntraCFGEdge: [ICFGNode" <<
getDstID() <<
" <-- ICFGNode" <<
getSrcID() <<
"]\t";
178 std::stringstream rawstr(str);
179 rawstr <<
"CallCFGEdge " <<
" [ICFGNode";
187 std::stringstream rawstr(str);
188 rawstr <<
"RetCFGEdge " <<
" [ICFGNode";
217 for (
const auto &loop: it.second)
223 for (
const auto &it: loops)
246 assert (entry &&
"fun entry not created in ICFGBuilder?");
253 assert (exit &&
"fun exit not created in ICFGBuilder?");
265 if (outEdge && inEdge)
267 assert(outEdge == inEdge &&
"edges not match");
282 if (outEdge && inEdge)
284 assert(outEdge == inEdge &&
"edges not match");
299 if (outEdge && inEdge)
301 assert(outEdge == inEdge &&
"edges not match");
317 for (ICFGEdge::ICFGEdgeSetTy::iterator iter = src->
OutEdgeBegin();
320 if ((*iter)->getDstID() == dst->
getId() && (*iter)->getEdgeKind() == kind)
326 assert(counter <= 1 &&
"there's more than one edge between two ICFG nodes");
340 assert(edge->
isIntraCFGEdge() &&
"this should be an intra CFG edge!");
346 return (
addICFGEdge(intraEdge) ? intraEdge :
nullptr);
360 assert(edge->
isIntraCFGEdge() &&
"this should be an intra CFG edge!");
367 return (
addICFGEdge(intraEdge) ? intraEdge :
nullptr);
380 assert(edge->
isCallCFGEdge() &&
"this should be a call CFG edge!");
386 return (
addICFGEdge(callEdge) ? callEdge :
nullptr);
398 assert(edge->
isRetCFGEdge() &&
"this should be a return CFG edge!");
430 CallGraph::CallEdgeMap::const_iterator iter = callgraph->
getIndCallMap().begin();
431 CallGraph::CallEdgeMap::const_iterator eiter = callgraph->
getIndCallMap().end();
432 for (; iter != eiter; iter++)
435 assert(callBlockNode->
isIndirectCall() &&
"this is not an indirect call?");
437 for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
455 if(retPE->getFunExitICFGNode() == calleeExitNode)
518 std::stringstream rawstr(str);
520 rawstr <<
"shape=record";
524 rawstr <<
",color=black";
528 rawstr <<
",color=yellow";
532 rawstr <<
",color=green";
536 rawstr <<
",color=red";
540 rawstr <<
",color=blue";
544 rawstr <<
",color=purple";
547 assert(
false &&
"no such kind of node!!");
552 template<
class EdgeIter>
555 ICFGEdge* edge = *(EI.getCurrent());
556 assert(edge &&
"No edge found!!");
558 return "style=solid,color=red";
560 return "style=solid,color=blue";
562 return "style=solid";
566 template<
class EdgeIter>
569 ICFGEdge* edge = *(EI.getCurrent());
570 assert(edge &&
"No edge found!!");
573 std::stringstream rawstr(str);
575 rawstr << dirCall->getSrcNode();
579 rawstr << ret->getCallICFGNode();
virtual const std::string toString() const
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const FunObjVar * > FunctionSet
const std::string toString() const override
const RetICFGNode * getRetICFGNode() const
Return callsite.
bool isIndirectCall() const
Return true if this is an indirect call.
FunEntryICFGNode(NodeID id, const FunObjVar *f)
const FunObjVar * getFun() const override
Return function.
const std::string toString() const override
const std::string getSourceLoc() const override
const std::string toString() const override
const FunObjVar * getFun() const override
Return function.
const std::string getSourceLoc() const override
const_bb_iterator begin() const
const_bb_iterator end() const
NodeType * getSrcNode() const
NodeType * getDstNode() const
void addGNode(NodeID id, NodeType *node)
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
const std::string toString() const override
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType >, bool simple=false)
bool isCallCFGEdge() const
bool isIntraCFGEdge() const
virtual const std::string toString() const
bool isRetCFGEdge() const
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
virtual const std::string toString() const
const SVFStmtList & getSVFStmts() const
void view()
View graph from the debugger.
ICFGEdge * hasThreadICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
void removeICFGEdge(ICFGEdge *edge)
Remove a ICFG edge.
ICFGEdge * getICFGEdge(const ICFGNode *src, const ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Get a SVFG edge according to src and dst.
void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec
map ICFG node to the SVF loops where it resides
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
GlobalICFGNode * globalBlockNode
unique basic block for all globals
virtual void addGlobalICFGNode(GlobalICFGNode *globalICFGNode)
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
void updateCallGraph(CallGraph *callgraph)
update ICFG for indirect calls
ICFGEdge * hasIntraICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Whether we has a SVFG edge.
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
FunExitICFGNode * getFunExitBlock(const FunObjVar *fun)
Get/Add a function exit node.
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
~ICFG() override
Destructor.
virtual void addICFGNode(ICFGNode *node)
Add a ICFG node.
FunEntryICFGNode * getFunEntryBlock(const FunObjVar *fun)
Get/Add a function entry node.
InterICFGNode(NodeID id, ICFGNodeK k)
Constructor.
s64_t getSuccessorCondValue() const
virtual const std::string toString() const
void setBranchCondVal(s64_t bVal)
const SVFVar * getCondition() const
const std::string toString() const override
static const Option< bool > ShowHiddenNode
static const Option< bool > DumpICFG
const CallICFGNode * getCallSite() const
Return call ICFGNode at the callsite.
virtual const std::string toString() const
const std::string toString() const override
NodeID getId() const
Get ID.
virtual const std::string getSourceLoc() const
virtual const std::string & getName() const
const std::string valueOnlyToString() const
virtual const std::string toString() const
Get string representation.
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
LLVM_NODISCARD bool isa(const Y &Val)
bool isExtCall(const FunObjVar *fun)
std::ostream & outs()
Overwrite llvm::outs().
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
std::string getNodeLabel(NodeType *node, ICFG *graph)
static std::string getGraphName(ICFG *)
Return name of the graph.
static bool isNodeHidden(ICFGNode *node, ICFG *)
static std::string getSimpleNodeLabel(NodeType *node, ICFG *)
Return the label of an ICFG node.
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, ICFG *)
static std::string getNodeAttributes(NodeType *node, ICFG *)
DOTGraphTraits(bool isSimple=false)