Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFG.cpp
Go to the documentation of this file.
1//===- SVFG.cpp -- Sparse value-flow graph-----------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * SVFG.cpp
25 *
26 * Created on: Oct 28, 2013
27 * Author: Yulei Sui
28 */
29
30#include "SVFIR/SVFModule.h"
31#include "Util/SVFUtil.h"
32#include "Graphs/SVFG.h"
33#include "Graphs/SVFGOPT.h"
34#include "Graphs/SVFGStat.h"
35#include "Graphs/ICFG.h"
36#include "Util/Options.h"
38#include <fstream>
39#include "Util/Options.h"
40
41using namespace SVF;
42using namespace SVFUtil;
43
45{
46 return getPointsTo();
47}
48
49const std::string MRSVFGNode::toString() const
50{
51 std::string str;
52 std::stringstream rawstr(str);
53 rawstr << "MRSVFGNode ID: " << getId();
54 return rawstr.str();
55}
56
57const std::string FormalINSVFGNode::toString() const
58{
59 std::string str;
60 std::stringstream rawstr(str);
61 rawstr << "FormalINSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
62 rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() <<
63 " = ENCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
64 rawstr << getMRVer()->getMR()->dumpStr() << "\n";
65 return rawstr.str();
66}
67
68const std::string FormalOUTSVFGNode::toString() const
69{
70 std::string str;
71 std::stringstream rawstr(str);
72 rawstr << "FormalOUTSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
73 rawstr << "RETMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
74 rawstr << getMRVer()->getMR()->dumpStr() << "\n";
75 return rawstr.str();
76}
77
78const std::string ActualINSVFGNode::toString() const
79{
80 std::string str;
81 std::stringstream rawstr(str);
82 rawstr << "ActualINSVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
83 rawstr << "CSMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
84 rawstr << getMRVer()->getMR()->dumpStr() << "\n";
85 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
86 return rawstr.str();
87}
88
89const std::string ActualOUTSVFGNode::toString() const
90{
91 std::string str;
92 std::stringstream rawstr(str);
93 rawstr << "ActualOUTSVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
94 rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() <<
95 " = CSCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
96 rawstr << getMRVer()->getMR()->dumpStr() << "\n";
97 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]" ;
98 return rawstr.str();
99}
100
101const std::string MSSAPHISVFGNode::toString() const
102{
103 std::string str;
104 std::stringstream rawstr(str);
105 rawstr << "MSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
106 rawstr << "MR_" << getResVer()->getMR()->getMRID()
107 << "V_" << getResVer()->getSSAVersion() << " = PHI(";
108 for (MemSSA::PHI::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
109 it != eit; it++)
110 rawstr << "MR_" << it->second->getMR()->getMRID() << "V_" << it->second->getSSAVersion() << ", ";
111 rawstr << ")\n";
112
113 rawstr << getResVer()->getMR()->dumpStr();
114 if (const IntraICFGNode* intraNode =
115 dyn_cast<IntraICFGNode>(getICFGNode()->getBB()->back()))
116 {
117 rawstr << intraNode->getSourceLoc();
118 }
119 return rawstr.str();
120}
121
122const std::string IntraMSSAPHISVFGNode::toString() const
123{
124 std::string str;
125 std::stringstream rawstr(str);
126 rawstr << "IntraMSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
128 return rawstr.str();
129}
130
132{
133 NodeBS nb;
134 nb.set(object);
135 return nb;
136}
137
138const std::string InterMSSAPHISVFGNode::toString() const
139{
140 std::string str;
141 std::stringstream rawstr(str);
142 if(isFormalINPHI())
143 rawstr << "FormalINPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
144 else
145 rawstr << "ActualOUTPHISVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
147 return rawstr.str();
148}
149
150const std::string IndirectSVFGEdge::toString() const
151{
152 std::string str;
153 std::stringstream rawstr(str);
154 rawstr << "IndirectSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
155 return rawstr.str();
156}
157
158const std::string IntraIndSVFGEdge::toString() const
159{
160 std::string str;
161 std::stringstream rawstr(str);
162 rawstr << "IntraIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
163 return rawstr.str();
164}
165
166const std::string CallIndSVFGEdge::toString() const
167{
168 std::string str;
169 std::stringstream rawstr(str);
170 rawstr << "CallIndSVFGEdge CallSite ID: " << getCallSiteId() << " ";
171 rawstr << getDstID() << "<--" << getSrcID() << "\n";
172 return rawstr.str();
173}
174
175const std::string RetIndSVFGEdge::toString() const
176{
177 std::string str;
178 std::stringstream rawstr(str);
179 rawstr << "RetIndSVFGEdge CallSite ID: " << getCallSiteId() << " ";
180 rawstr << getDstID() << "<--" << getSrcID() << "\n";
181 return rawstr.str();
182}
183
184
185const std::string ThreadMHPIndSVFGEdge::toString() const
186{
187 std::string str;
188 std::stringstream rawstr(str);
189 rawstr << "ThreadMHPIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
190 return rawstr.str();
191}
192
193
195{
196 cpts = mrVer->getMR()->getPointsTo();
197 ver = mrVer;
199}
200
204SVFG::SVFG(std::unique_ptr<MemSSA> mssa, VFGK k): VFG(mssa->getPTA()->getCallGraph(),k),mssa(std::move(mssa)), pta(this->mssa->getPTA())
205{
206 stat = new SVFGStat(this);
207}
208
213{
214 delete stat;
215 stat = nullptr;
216 clearMSSA();
217}
218
229{
230 DBOUT(DGENERAL, outs() << pasMsg("Build Sparse Value-Flow Graph \n"));
231
232 stat->startClk();
233 if (!Options::ReadSVFG().empty())
234 {
236 }
237 else
238 {
239 DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Addr-taken Node\n"));
242 stat->ATVFNodeEnd();
243 DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Indirect Edge\n"));
247 if (!Options::WriteSVFG().empty())
249 }
250}
251
252/*
253 * Create SVFG nodes for address-taken variables
254 */
256{
257
258 // set defs for address-taken vars defined at store statements
260 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
261 stores.end(); iter != eiter; ++iter)
262 {
263 StoreStmt* store = SVFUtil::cast<StoreStmt>(*iter);
264 const StmtSVFGNode* sNode = getStmtVFGNode(store);
265 for(CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi!=epi; ++pi)
266 setDef((*pi)->getResVer(),sNode);
267 }
268
272 for(MemSSA::BBToPhiSetMap::iterator it = mssa->getBBToPhiSetMap().begin(),
273 eit = mssa->getBBToPhiSetMap().end(); it!=eit; ++it)
274 {
275 for(PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
276 {
277 MemSSA::PHI* phi = *pi;
278 const ICFGNode* inst = phi->getBasicBlock()->front();
279 addIntraMSSAPHISVFGNode(const_cast<ICFGNode*>(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++);
280 }
281 }
283 for(MemSSA::FunToEntryChiSetMap::iterator it = mssa->getFunToEntryChiSetMap().begin(),
284 eit = mssa->getFunToEntryChiSetMap().end(); it!=eit; ++it)
285 {
286 for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
287 {
288 const MemSSA::ENTRYCHI* chi = SVFUtil::cast<ENTRYCHI>(*pi);
289 addFormalINSVFGNode(pag->getICFG()->getFunEntryICFGNode(chi->getFunction()), chi->getResVer(), totalVFGNode++);
290 }
291 }
293 for(MemSSA::FunToReturnMuSetMap::iterator it = mssa->getFunToRetMuSetMap().begin(),
294 eit = mssa->getFunToRetMuSetMap().end(); it!=eit; ++it)
295 {
296 for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
297 {
298 const MemSSA::RETMU* mu = SVFUtil::cast<RETMU>(*pi);
299 addFormalOUTSVFGNode(pag->getICFG()->getFunExitICFGNode(mu->getFunction()), mu->getMRVer(), totalVFGNode++);
300 }
301 }
303 for(MemSSA::CallSiteToMUSetMap::iterator it = mssa->getCallSiteToMuSetMap().begin(),
304 eit = mssa->getCallSiteToMuSetMap().end();
305 it!=eit; ++it)
306 {
307 for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
308 {
309 const MemSSA::CALLMU* mu = SVFUtil::cast<CALLMU>(*pi);
310 addActualINSVFGNode(mu->getCallSite(), mu->getMRVer(), totalVFGNode++);
311 }
312 }
314 for(MemSSA::CallSiteToCHISetMap::iterator it = mssa->getCallSiteToChiSetMap().begin(),
315 eit = mssa->getCallSiteToChiSetMap().end();
316 it!=eit; ++it)
317 {
318 for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
319 {
320 const MemSSA::CALLCHI* chi = SVFUtil::cast<CALLCHI>(*pi);
321 addActualOUTSVFGNode(chi->getCallSite(), chi->getResVer(), totalVFGNode++);
322 }
323
324 }
325}
326
327/*
328 * Connect def-use chains for indirect value-flow, (value-flow of address-taken variables)
329 */
331{
332
333 for(iterator it = begin(), eit = end(); it!=eit; ++it)
334 {
335 NodeID nodeId = it->first;
336 const SVFGNode* node = it->second;
337 if(const LoadSVFGNode* loadNode = SVFUtil::dyn_cast<LoadSVFGNode>(node))
338 {
339 MUSet& muSet = mssa->getMUSet(SVFUtil::cast<LoadStmt>(loadNode->getPAGEdge()));
340 for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it)
341 {
342 if(LOADMU* mu = SVFUtil::dyn_cast<LOADMU>(*it))
343 {
344 NodeID def = getDef(mu->getMRVer());
345 addIntraIndirectVFEdge(def,nodeId, mu->getMRVer()->getMR()->getPointsTo());
346 }
347 }
348 }
349 else if(const StoreSVFGNode* storeNode = SVFUtil::dyn_cast<StoreSVFGNode>(node))
350 {
351 CHISet& chiSet = mssa->getCHISet(SVFUtil::cast<StoreStmt>(storeNode->getPAGEdge()));
352 for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it)
353 {
354 if(STORECHI* chi = SVFUtil::dyn_cast<STORECHI>(*it))
355 {
356 NodeID def = getDef(chi->getOpVer());
357 addIntraIndirectVFEdge(def,nodeId, chi->getOpVer()->getMR()->getPointsTo());
358 }
359 }
360 }
361 else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
362 {
364 mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet);
365 for(PTACallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
366 {
367 const CallICFGNode* cs = *it;
368 if(!mssa->hasMU(cs))
369 continue;
372 {
373 const ActualINSVFGNode* actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ait));
375 }
376 }
377 }
378 else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
379 {
381 // const MemSSA::RETMU* retMu = formalOut->getRetMU();
382 mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet);
383 for(PTACallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
384 {
385 const CallICFGNode* cs = *it;
386 if(!mssa->hasCHI(cs))
387 continue;
390 {
391 const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ait));
393 }
394 }
395 NodeID def = getDef(formalOut->getMRVer());
396 addIntraIndirectVFEdge(def,nodeId, formalOut->getMRVer()->getMR()->getPointsTo());
397 }
398 else if(const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
399 {
400 const MRVer* ver = actualIn->getMRVer();
401 NodeID def = getDef(ver);
403 }
404 else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
405 {
407 }
408 else if(const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
409 {
410 for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd();
411 it != eit; it++)
412 {
413 const MRVer* op = it->second;
414 NodeID def = getDef(op);
415 addIntraIndirectVFEdge(def,nodeId, op->getMR()->getPointsTo());
416 }
417 }
418 }
419
420
422}
423
424
429{
432 if (formalIns.empty())
433 return;
434
435 for (GlobalVFGNodeSet::const_iterator storeIt = globalVFGNodes.begin(), storeEit = globalVFGNodes.end();
437 {
438 if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(*storeIt))
439 {
441 const NodeBS& storePts = mssa->getPTA()->getPts(store->getPAGDstNodeID()).toNodeBS();
442
444 formalIns.end(); fiIt != fiEit; ++fiIt)
445 {
448
450 if (formalInPts.empty())
451 continue;
452
455 }
456 }
457 }
458}
459
460/*
461 * Add def-use edges of a memory region between two statements
462 */
464{
469 {
470 assert(SVFUtil::isa<IndirectSVFGEdge>(edge) && "this should be a indirect value flow edge!");
471 return (SVFUtil::cast<IndirectSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
472 }
473 else
474 {
476 indirectEdge->addPointsTo(cpts);
477 return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
478 }
479}
480
481
486{
490 {
491 assert(SVFUtil::isa<IndirectSVFGEdge>(edge) && "this should be a indirect value flow edge!");
492 return (SVFUtil::cast<IndirectSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
493 }
494 else
495 {
497 indirectEdge->addPointsTo(cpts);
498 return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
499 }
500}
501
502/*
503 * Add def-use call edges of a memory region between two statements
504 */
506{
510 {
511 assert(SVFUtil::isa<CallIndSVFGEdge>(edge) && "this should be a indirect value flow edge!");
512 return (SVFUtil::cast<CallIndSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
513 }
514 else
515 {
517 callEdge->addPointsTo(cpts);
518 return (addSVFGEdge(callEdge) ? callEdge : nullptr);
519 }
520}
521
522/*
523 * Add def-use return edges of a memory region between two statements
524 */
526{
530 {
531 assert(SVFUtil::isa<RetIndSVFGEdge>(edge) && "this should be a indirect value flow edge!");
532 return (SVFUtil::cast<RetIndSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
533 }
534 else
535 {
537 retEdge->addPointsTo(cpts);
538 return (addSVFGEdge(retEdge) ? retEdge : nullptr);
539 }
540}
541
546{
547 NodeBS cpts1 = src->getPointsTo();
548 NodeBS cpts2 = dst->getPointsTo();
549 if(cpts1.intersects(cpts2))
550 {
551 cpts1 &= cpts2;
552 return addCallIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId);
553 }
554 return nullptr;
555}
556
561{
562
563 NodeBS cpts1 = src->getPointsTo();
564 NodeBS cpts2 = dst->getPointsTo();
565 if(cpts1.intersects(cpts2))
566 {
567 cpts1 &= cpts2;
568 return addRetIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId);
569 }
570 return nullptr;
571}
572
576void SVFG::dump(const std::string& file, bool simple)
577{
579}
580
585{
587 const RetICFGNode* retICFGNode = callICFGNode->getRetICFGNode();
588
589 // Find inter direct call edges between actual param and formal param.
591 {
594 SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
595 SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
596 for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
597 {
598 const PAGNode *cs_arg = *csArgIt;
599 const PAGNode *fun_arg = *funArgIt;
602 }
603 assert(funArgIt == funArgEit && "function has more arguments than call site");
604 if (callee->isVarArg())
605 {
609 {
610 for (; csArgIt != csArgEit; csArgIt++)
611 {
612 const PAGNode *cs_arg = *csArgIt;
615 }
616 }
617 }
618 }
619
620 // Find inter direct return edges between actual return and formal return.
622 {
627 }
628
629 // Find inter indirect call edges between actual-in and formal-in svfg nodes.
631 {
635 {
636 ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
638 }
639 }
640
641 // Find inter indirect return edges between actual-out and formal-out svfg nodes.
643 {
647 {
648 ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
650 }
651 }
652}
653
659{
661
662 CallSiteID csId = getCallSiteID(cs, callee);
663
664 // connect actual in and formal in
666 {
671 {
672 const ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
675 {
676 const FormalINSVFGNode* formalIn = SVFUtil::cast<FormalINSVFGNode>(getSVFGNode(*fi_it));
678 }
679 }
680 }
681
682 // connect actual out and formal out
684 {
685 // connect formal out and actual out
690 {
691 const FormalOUTSVFGNode * formalOut = SVFUtil::cast<FormalOUTSVFGNode>(getSVFGNode(*fo_it));
694 {
695 const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
697 }
698 }
699 }
700}
701
702
707{
708 if(const FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
709 {
710 return fp->getFun();
711 }
712 else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast<InterPHISVFGNode>(node))
713 {
714 if(phi->isFormalParmPHI())
715 return phi->getFun();
716 }
717 else if(const FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
718 {
719 return fi->getFun();
720 }
721 else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<InterMSSAPHISVFGNode>(node))
722 {
723 if(mphi->isFormalINPHI())
724 return mphi->getFun();
725 }
726 return nullptr;
727}
728
733{
734 if(const ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
735 {
736 return ar->getCallSite();
737 }
738 else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast<InterPHISVFGNode>(node))
739 {
740 if(phi->isActualRetPHI())
741 return phi->getCallSite();
742 }
743 else if(const ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
744 {
745 return ao->getCallSite();
746 }
747 else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<InterMSSAPHISVFGNode>(node))
748 {
749 if(mphi->isActualOUTPHI())
750 return mphi->getCallSite();
751 }
752 return nullptr;
753}
754
759{
760 stat->performStat();
761}
762
766namespace SVF
767{
768template<>
770{
771
773 DOTGraphTraits(bool isSimple = false) :
774 DOTGraphTraits<SVFIR*>(isSimple)
775 {
776 }
777
779 static std::string getGraphName(SVFG*)
780 {
781 return "SVFG";
782 }
783
786 static bool isNodeHidden(SVFGNode *node, SVFG *)
787 {
788 if (Options::ShowHiddenNode()) return false;
789 else return node->getInEdges().empty() && node->getOutEdges().empty();
790 }
791
792 std::string getNodeLabel(NodeType *node, SVFG *graph)
793 {
794 if (isSimple())
795 return getSimpleNodeLabel(node, graph);
796 else
797 return getCompleteNodeLabel(node, graph);
798 }
799
801 static std::string getSimpleNodeLabel(NodeType *node, SVFG*)
802 {
803 std::string str;
804 std::stringstream rawstr(str);
805 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
806 {
807 rawstr << stmtNode->toString();
808 }
809 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
810 {
811 rawstr << tphi->toString();
812 }
813 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
814 {
815 rawstr << fp->toString();
816 }
817 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
818 {
819 rawstr << ap->toString();
820 }
821 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
822 {
823 rawstr << ar->toString();
824 }
825 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
826 {
827 rawstr << fr->toString();
828 }
829 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
830 {
831 rawstr << fi->toString();
832 }
833 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
834 {
835 rawstr << fo->toString();
836 }
837 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
838 {
839 rawstr << ai->toString();
840 }
841 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
842 {
843 rawstr << ao->toString();
844 }
845 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
846 {
847 rawstr << mphi->toString();
848 }
849 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
850 {
851 rawstr << "NullPtr";
852 }
853 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
854 {
855 rawstr << bop->toString();
856 }
857 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
858 {
859 rawstr << uop->toString();
860 }
861 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
862 {
863 rawstr << cmp->toString();
864 }
865 else
866 assert(false && "what else kinds of nodes do we have??");
867
868 return rawstr.str();
869 }
870
872 static std::string getCompleteNodeLabel(NodeType *node, SVFG*)
873 {
874
875 std::string str;
876 std::stringstream rawstr(str);
877 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
878 {
879 rawstr << stmtNode->toString();
880 }
881 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
882 {
883 rawstr << bop->toString();
884 }
885 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
886 {
887 rawstr << uop->toString();
888 }
889 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
890 {
891 rawstr << cmp->toString();
892 }
893 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
894 {
895 rawstr << mphi->toString();
896 }
897 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
898 {
899 rawstr << tphi->toString();
900 }
901 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
902 {
903 rawstr << fi->toString();
904 }
905 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
906 {
907 rawstr << fo->toString();
908 }
909 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
910 {
911 rawstr << fp->toString();
912 }
913 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
914 {
915 rawstr << ai->toString();
916 }
917 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
918 {
919 rawstr << ao->toString();
920 }
921 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
922 {
923 rawstr << ap->toString();
924 }
925 else if(NullPtrSVFGNode* nptr = SVFUtil::dyn_cast<NullPtrSVFGNode>(node))
926 {
927 rawstr << nptr->toString();
928 }
929 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
930 {
931 rawstr << ar->toString();
932 }
933 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
934 {
935 rawstr << fr->toString();
936 }
937 else if (BranchVFGNode* br = SVFUtil::dyn_cast<BranchVFGNode>(node))
938 {
939 rawstr << br->toString();
940 }
941 else
942 assert(false && "what else kinds of nodes do we have??");
943
944 return rawstr.str();
945 }
946
947 static std::string getNodeAttributes(NodeType *node, SVFG *graph)
948 {
949 std::string str;
950 std::stringstream rawstr(str);
951
952 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
953 {
954 const PAGEdge* edge = stmtNode->getPAGEdge();
955 if (SVFUtil::isa<AddrStmt>(edge))
956 {
957 rawstr << "color=green";
958 }
959 else if (SVFUtil::isa<CopyStmt>(edge))
960 {
961 rawstr << "color=black";
962 }
963 else if (SVFUtil::isa<RetPE>(edge))
964 {
965 rawstr << "color=black,style=dotted";
966 }
967 else if (SVFUtil::isa<GepStmt>(edge))
968 {
969 rawstr << "color=purple";
970 }
971 else if (SVFUtil::isa<StoreStmt>(edge))
972 {
973 rawstr << "color=blue";
974 }
975 else if (SVFUtil::isa<LoadStmt>(edge))
976 {
977 rawstr << "color=red";
978 }
979 else
980 {
981 assert(0 && "No such kind edge!!");
982 }
983 rawstr << "";
984 }
985 else if(SVFUtil::isa<MSSAPHISVFGNode>(node))
986 {
987 rawstr << "color=black";
988 }
989 else if(SVFUtil::isa<PHISVFGNode>(node))
990 {
991 rawstr << "color=black";
992 }
993 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
994 {
995 rawstr << "color=grey";
996 }
997 else if(SVFUtil::isa<FormalINSVFGNode>(node))
998 {
999 rawstr << "color=yellow,penwidth=2";
1000 }
1001 else if(SVFUtil::isa<FormalOUTSVFGNode>(node))
1002 {
1003 rawstr << "color=yellow,penwidth=2";
1004 }
1005 else if(SVFUtil::isa<FormalParmSVFGNode>(node))
1006 {
1007 rawstr << "color=yellow,penwidth=2";
1008 }
1009 else if(SVFUtil::isa<ActualINSVFGNode>(node))
1010 {
1011 rawstr << "color=yellow,penwidth=2";
1012 }
1013 else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
1014 {
1015 rawstr << "color=yellow,penwidth=2";
1016 }
1017 else if(SVFUtil::isa<ActualParmSVFGNode>(node))
1018 {
1019 rawstr << "color=yellow,penwidth=2";
1020 }
1021 else if (SVFUtil::isa<ActualRetSVFGNode>(node))
1022 {
1023 rawstr << "color=yellow,penwidth=2";
1024 }
1025 else if (SVFUtil::isa<FormalRetSVFGNode>(node))
1026 {
1027 rawstr << "color=yellow,penwidth=2";
1028 }
1029 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1030 {
1031 rawstr << "color=black,penwidth=2";
1032 }
1033 else if (SVFUtil::isa<CmpVFGNode>(node))
1034 {
1035 rawstr << "color=black,penwidth=2";
1036 }
1037 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1038 {
1039 rawstr << "color=black,penwidth=2";
1040 }
1041 else if (SVFUtil::isa<BranchVFGNode>(node))
1042 {
1043 rawstr << "color=gold,penwidth=2";
1044 }
1045 else
1046 assert(false && "no such kind of node!!");
1047
1049 if(graph->getStat()->isSource(node))
1050 {
1051 rawstr << ",style=filled, fillcolor=red";
1052 }
1053 else if(graph->getStat()->isSink(node))
1054 {
1055 rawstr << ",style=filled, fillcolor=blue";
1056 }
1057 else if(graph->getStat()->inBackwardSlice(node))
1058 {
1059 rawstr << ",style=filled, fillcolor=yellow";
1060 }
1061 else if(graph->getStat()->inForwardSlice(node))
1062 rawstr << ",style=filled, fillcolor=gray";
1063
1064 rawstr << "";
1065
1066 return rawstr.str();
1067 }
1068
1069 template<class EdgeIter>
1071 {
1072 SVFGEdge* edge = *(EI.getCurrent());
1073 assert(edge && "No edge found!!");
1074 if (SVFUtil::isa<DirectSVFGEdge>(edge))
1075 {
1076 if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1077 return "style=solid,color=red";
1078 else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1079 return "style=solid,color=blue";
1080 else
1081 return "style=solid";
1082 }
1083 else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1084 {
1085 if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1086 return "style=dashed,color=red";
1087 else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1088 return "style=dashed,color=blue";
1089 else
1090 return "style=dashed";
1091 }
1092 return "";
1093 }
1094
1095 template<class EdgeIter>
1097 {
1098 SVFGEdge* edge = *(EI.getCurrent());
1099 assert(edge && "No edge found!!");
1100
1101 std::string str;
1102 std::stringstream rawstr(str);
1103 if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1104 rawstr << dirCall->getCallSiteId();
1105 else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1106 rawstr << dirRet->getCallSiteId();
1107 else if (CallIndSVFGEdge* indCall = SVFUtil::dyn_cast<CallIndSVFGEdge>(edge))
1108 rawstr << indCall->getCallSiteId();
1109 else if (RetIndSVFGEdge* indRet = SVFUtil::dyn_cast<RetIndSVFGEdge>(edge))
1110 rawstr << indRet->getCallSiteId();
1111
1112 return rawstr.str();
1113 }
1114};
1115} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define DGENERAL
Definition SVFType.h:490
const MRVer * getMRVer() const
Ver.
Definition SVFGNode.h:188
virtual const std::string toString() const
Definition SVFG.cpp:78
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:182
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:232
virtual const std::string toString() const
Definition SVFG.cpp:89
const MRVer * getMRVer() const
Ver.
Definition SVFGNode.h:237
const std::string getSourceLoc() const override
Definition ICFGNode.h:588
virtual const std::string toString() const
Definition SVFG.cpp:166
CallSiteID getCallSiteId() const
Definition SVFGEdge.h:136
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition SVFG.cpp:131
const MRVer * getMRVer() const
Definition SVFGNode.h:95
virtual const std::string toString() const
Definition SVFG.cpp:57
virtual const std::string toString() const
Definition SVFG.cpp:68
const MRVer * getMRVer() const
Definition SVFGNode.h:141
FormalOUTSVFGNode(NodeID id, const MRVer *ver, const FunExitICFGNode *funExitNode)
Constructor.
Definition SVFG.cpp:194
const MRVer * ver
Definition SVFGNode.h:129
const FunExitICFGNode * funExitNode
Definition SVFGNode.h:130
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:76
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
Definition ICFG.cpp:234
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
Definition ICFG.cpp:241
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.h:157
virtual const std::string toString() const
Definition SVFG.cpp:150
virtual const std::string toString() const
Definition SVFG.cpp:138
bool isFormalINPHI() const
Definition SVFGNode.h:401
const CallICFGNode * getCallSite() const
Definition SVFGNode.h:417
const SVFFunction * getFun() const
Get the function of this SVFGNode.
Definition SVFGNode.h:411
virtual const std::string toString() const
Definition SVFG.cpp:158
virtual const std::string toString() const
Definition SVFG.cpp:122
virtual const std::string toString() const override
Definition SVFG.cpp:49
const NodeBS & getPointsTo() const
Return points-to of the MR.
Definition SVFGNode.h:52
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition SVFG.cpp:44
MRVERSION getSSAVersion() const
Return SSA version.
Definition MSSAMuChi.h:69
const MemRegion * getMR() const
Return the memory region.
Definition MSSAMuChi.h:63
virtual const std::string toString() const
Definition SVFG.cpp:101
OPVers::const_iterator opVerEnd() const
Definition SVFGNode.h:305
const MRVer * getResVer() const
Ver.
Definition SVFGNode.h:281
OPVers::const_iterator opVerBegin() const
Definition SVFGNode.h:301
MRID getMRID() const
Return memory region ID.
Definition MemRegion.h:78
const NodeBS & getPointsTo() const
Return points-to.
Definition MemRegion.h:83
std::string dumpStr() const
Dump string.
Definition MemRegion.h:93
CallCHI< Condition > CALLCHI
Definition MemSSA.h:66
EntryCHI< Condition > ENTRYCHI
Definition MemSSA.h:64
CallMU< Condition > CALLMU
Definition MemSSA.h:62
RetMU< Condition > RETMU
Definition MemSSA.h:60
static const Option< std::string > ReadSVFG
Definition Options.h:152
static const Option< std::string > WriteSVFG
Definition Options.h:151
static const Option< bool > ShowHiddenNode
Definition Options.h:228
Set< const CallICFGNode * > CallInstSet
CallSiteID getCallSiteId() const
Definition SVFGEdge.h:175
virtual const std::string toString() const
Definition SVFG.cpp:175
NodeID getId() const
Get ID.
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:746
virtual void performStat() override
Definition SVFGStat.cpp:178
void ATVFNodeStart()
Definition SVFGStat.h:139
bool inBackwardSlice(const SVFGNode *node) const
Definition SVFGStat.h:257
bool isSource(const SVFGNode *node) const
Definition SVFGStat.h:261
void indVFEdgeEnd()
Definition SVFGStat.h:124
void ATVFNodeEnd()
Definition SVFGStat.h:144
bool inForwardSlice(const SVFGNode *node) const
Definition SVFGStat.h:253
void indVFEdgeStart()
Definition SVFGStat.h:119
bool isSink(const SVFGNode *node) const
Definition SVFGStat.h:265
SVFG(std::unique_ptr< MemSSA > mssa, VFGK k)
Constructor.
Definition SVFG.cpp:204
virtual void buildSVFG()
Start building SVFG.
Definition SVFG.cpp:228
void connectIndirectSVFGEdges()
Connect direct SVFG edges between two SVFG nodes (value-flow of top address-taken variables)
Definition SVFG.cpp:330
SVFGEdge * addThreadMHPIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Definition SVFG.cpp:485
ActualOUTSVFGNodeSet & getActualOUTSVFGNodes(const CallICFGNode *cs)
Definition SVFG.h:215
bool hasFuncEntryChi(const SVFFunction *func) const
Has function for EntryCHI/RetMU/CallCHI/CallMU.
Definition SVFG.h:449
bool hasFuncRetMu(const SVFFunction *func) const
Definition SVFG.h:453
SVFGStat * getStat() const
Return statistics.
Definition SVFG.h:126
virtual void connectFOutAndAOut(const FormalOUTSVFGNode *formalOut, const ActualOUTSVFGNode *actualOut, CallSiteID csId, SVFGEdgeSetTy &edges)
Connect formal-out and actual-out.
Definition SVFG.h:300
void getInterVFEdgesForIndirectCallSite(const CallICFGNode *cs, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Get all inter value flow edges of a indirect call site.
Definition SVFG.cpp:584
SVFGEdge * addInterIndirectVFCallEdge(const ActualINSVFGNode *src, const FormalINSVFGNode *dst, CallSiteID csId)
Add inter VF edge from callsite mu to function entry chi.
Definition SVFG.cpp:545
void connectFromGlobalToProgEntry()
Connect indirect SVFG edges from global initializers (store) to main function entry.
Definition SVFG.cpp:428
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition SVFG.cpp:576
void addIntraMSSAPHISVFGNode(ICFGNode *BlockICFGNode, const Map< u32_t, const MRVer * >::const_iterator opVerBegin, const Map< u32_t, const MRVer * >::const_iterator opVerEnd, const MRVer *resVer, const NodeID nodeId)
Add memory SSA PHI SVFG node.
Definition SVFG.h:437
ActualINSVFGNodeSet & getActualINSVFGNodes(const CallICFGNode *cs)
Get SVFGNode set.
Definition SVFG.h:210
bool addSVFGEdge(SVFGEdge *edge)
Add SVFG edge.
Definition SVFG.h:249
void addActualOUTSVFGNode(const CallICFGNode *callsite, const MRVer *resVer, const NodeID nodeId)
Add memory callsite chi SVFG node.
Definition SVFG.h:428
FormalINSVFGNodeSet & getFormalINSVFGNodes(const SVFFunction *fun)
Definition SVFG.h:220
virtual void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode *actualOut, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:338
virtual void writeToFile(const std::string &filename)
void addFormalOUTSVFGNode(const FunExitICFGNode *funExit, const MRVer *ver, const NodeID nodeId)
Add memory Function return mu SVFG node.
Definition SVFG.h:412
void destroy()
Clean up memory.
Definition SVFG.cpp:212
bool hasCallSiteMu(const CallICFGNode *cs) const
Definition SVFG.h:461
MemSSA::LOADMU LOADMU
Definition SVFG.h:92
MemSSA::CHISet CHISet
Definition SVFG.h:88
SVFGEdge * addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:525
void addActualINSVFGNode(const CallICFGNode *callsite, const MRVer *ver, const NodeID nodeId)
Add memory callsite mu SVFG node.
Definition SVFG.h:420
virtual void readFile(const std::string &filename)
std::unique_ptr< MemSSA > mssa
Definition SVFG.h:106
virtual void getInterVFEdgeAtIndCSFromFRToAR(const PAGNode *fun_ret, const PAGNode *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges)
Definition SVFG.h:319
void addFormalINSVFGNode(const FunEntryICFGNode *funEntry, const MRVer *resVer, const NodeID nodeId)
Add memory Function entry chi SVFG node.
Definition SVFG.h:403
NodeID getDef(const PAGNode *pagNode) const
Definition SVFG.h:356
void addSVFGNodesForAddrTakenVars()
Create SVFG nodes for address-taken variables.
Definition SVFG.cpp:255
virtual void getInterVFEdgeAtIndCSFromAPToFP(const PAGNode *cs_arg, const PAGNode *fun_arg, const CallICFGNode *, CallSiteID csId, SVFGEdgeSetTy &edges)
Get inter value flow edges between indirect call site and callee.
Definition SVFG.h:310
SVFGEdge * addInterIndirectVFRetEdge(const FormalOUTSVFGNode *src, const ActualOUTSVFGNode *dst, CallSiteID csId)
Add inter VF edge from function exit mu to callsite chi.
Definition SVFG.cpp:560
virtual void connectAInAndFIn(const ActualINSVFGNode *actualIn, const FormalINSVFGNode *formalIn, CallSiteID csId, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition SVFG.h:293
void setDef(const PAGNode *pagNode, const SVFGNode *node)
Given a PAGNode, set/get its def SVFG node (definition of top level pointers)
Definition SVFG.h:352
MemSSA::MUSet MUSet
Definition SVFG.h:87
SVFGEdge * addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Add indirect def-use edges of a memory region between two statements,.
Definition SVFG.cpp:463
MemSSA::STORECHI STORECHI
Definition SVFG.h:93
const CallICFGNode * isCallSiteRetSVFGNode(const SVFGNode *node) const
Whether a node is callsite return SVFGNode.
Definition SVFG.cpp:732
SVFGStat * stat
Definition SVFG.h:105
bool hasCallSiteChi(const CallICFGNode *cs) const
Definition SVFG.h:457
void performStat()
Perform statistics.
Definition SVFG.cpp:758
FormalOUTSVFGNodeSet & getFormalOUTSVFGNodes(const SVFFunction *fun)
Definition SVFG.h:225
const SVFFunction * isFunEntrySVFGNode(const SVFGNode *node) const
Whether a node is function entry SVFGNode.
Definition SVFG.cpp:706
void clearMSSA()
Clear MSSA.
Definition SVFG.h:132
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition SVFG.cpp:658
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:505
virtual void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode *actualIn, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:328
std::vector< const SVFVar * > SVFVarList
Definition SVFIR.h:60
const SVFVarList & getFunArgsList(const SVFFunction *func) const
Get function arguments list.
Definition SVFIR.h:276
ICFG * getICFG() const
Definition SVFIR.h:172
const SVFVar * getFunRet(const SVFFunction *func) const
Get function return list.
Definition SVFIR.h:321
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:283
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:311
bool hasFunArgsList(const SVFFunction *func) const
Function has arguments list.
Definition SVFIR.h:266
const SVFVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:293
const SVFVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:305
bool funHasRet(const SVFFunction *func) const
Definition SVFIR.h:327
virtual void startClk()
Definition SVFStat.h:58
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
const std::string & getName() const
Definition SVFValue.h:243
void set(unsigned Idx)
virtual const std::string toString() const
Definition SVFG.cpp:185
@ IntraIndirectVF
Definition VFGEdge.h:54
@ TheadMHPIndirectVF
Definition VFGEdge.h:59
virtual const SVFFunction * getFun() const
Get the function of this SVFGNode.
Definition VFGNode.h:79
virtual const ICFGNode * getICFGNode() const
Return corresponding ICFG node.
Definition VFGNode.h:67
Definition VFG.h:51
virtual SVFStmt::SVFStmtSetTy & getPAGEdgeSet(SVFStmt::PEDGEK kind)
Get PAGEdge set.
Definition VFG.h:436
VFGNodeIDToNodeMapTy::iterator iterator
Definition VFG.h:80
SVFIR * pag
Definition VFG.h:104
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition VFG.h:351
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *func) const
Get callsite given a callsiteID.
Definition VFG.h:178
GlobalVFGNodeSet globalVFGNodes
set of global store VFG nodes
Definition VFG.h:102
virtual bool isInterestedPAGNode(const SVFVar *node) const
Definition VFG.h:444
StmtVFGNode * getStmtVFGNode(const PAGEdge *pagEdge) const
Get an VFGNode.
Definition VFG.h:199
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition VFG.cpp:973
VFGK
VFG kind.
Definition VFG.h:56
VFGEdge * hasIntraVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Whether we has a SVFG edge.
Definition VFG.cpp:875
VFGEdge::SVFGEdgeSetTy SVFGEdgeSetTy
Definition VFG.h:78
NodeID totalVFGNode
Definition VFG.h:88
VFGEdge * hasInterVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind, CallSiteID csId)
Definition VFG.cpp:910
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition VFG.cpp:893
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition SVFUtil.h:447
const SVFFunction * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:416
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
u32_t NodeID
Definition GeneralType.h:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
static std::string getGraphName(SVFG *)
Return name of the graph.
Definition SVFG.cpp:779
std::string getNodeLabel(NodeType *node, SVFG *graph)
Definition SVFG.cpp:792
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition SVFG.cpp:1096
static std::string getSimpleNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node without MemSSA information.
Definition SVFG.cpp:801
static bool isNodeHidden(SVFGNode *node, SVFG *)
Definition SVFG.cpp:786
DOTGraphTraits(bool isSimple=false)
Definition SVFG.cpp:773
static std::string getNodeAttributes(NodeType *node, SVFG *graph)
Definition SVFG.cpp:947
static std::string getCompleteNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node with MemSSA information.
Definition SVFG.cpp:872
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVFG *)
Definition SVFG.cpp:1070