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
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->getSVFStmt()));
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->getSVFStmt()));
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(CallGraphEdge::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(CallGraphEdge::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->getDstNodeID()).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::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
595 SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
596 for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
597 {
598 const ValVar *cs_arg = *csArgIt;
599 const ValVar *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 ValVar *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
766{
767 return getDefSVFGNode(var);
768}
769
773{
775 for (auto it = vNode->InEdgeBegin(), eit = vNode->InEdgeEnd(); it != eit; ++it)
776 {
777 if (const IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
778 {
779 if (indEdge->getPointsTo().test(obj->getId()))
780 {
781 defSites.insert(indEdge->getSrcNode());
782 }
783 }
784 }
785 return defSites;
786}
787
791{
794 for (auto it = defNode->OutEdgeBegin(), eit = defNode->OutEdgeEnd(); it != eit; ++it)
795 {
796 const VFGEdge* edge = *it;
797 if (edge->isDirectVFGEdge())
798 {
799 useSites.insert(edge->getDstNode());
800 }
801 }
802 return useSites;
803}
804
808{
810 for (auto it = vNode->OutEdgeBegin(), eit = vNode->OutEdgeEnd(); it != eit; ++it)
811 {
812 if (const IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
813 {
814 if (indEdge->getPointsTo().test(obj->getId()))
815 {
816 useSites.insert(indEdge->getDstNode());
817 }
818 }
819 }
820
821 return useSites;
822}
823
827namespace SVF
828{
829template<>
831{
832
834 DOTGraphTraits(bool isSimple = false) :
835 DOTGraphTraits<SVFIR*>(isSimple)
836 {
837 }
838
840 static std::string getGraphName(SVFG*)
841 {
842 return "SVFG";
843 }
844
847 static bool isNodeHidden(SVFGNode *node, SVFG *)
848 {
849 if (Options::ShowHiddenNode()) return false;
850 else return node->getInEdges().empty() && node->getOutEdges().empty();
851 }
852
853 std::string getNodeLabel(NodeType *node, SVFG *graph)
854 {
855 if (isSimple())
856 return getSimpleNodeLabel(node, graph);
857 else
858 return getCompleteNodeLabel(node, graph);
859 }
860
862 static std::string getSimpleNodeLabel(NodeType *node, SVFG*)
863 {
864 std::string str;
865 std::stringstream rawstr(str);
866 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
867 {
868 rawstr << stmtNode->toString();
869 }
870 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
871 {
872 rawstr << tphi->toString();
873 }
874 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
875 {
876 rawstr << fp->toString();
877 }
878 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
879 {
880 rawstr << ap->toString();
881 }
882 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
883 {
884 rawstr << ar->toString();
885 }
886 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
887 {
888 rawstr << fr->toString();
889 }
890 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
891 {
892 rawstr << fi->toString();
893 }
894 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
895 {
896 rawstr << fo->toString();
897 }
898 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
899 {
900 rawstr << ai->toString();
901 }
902 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
903 {
904 rawstr << ao->toString();
905 }
906 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
907 {
908 rawstr << mphi->toString();
909 }
910 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
911 {
912 rawstr << "NullPtr";
913 }
914 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
915 {
916 rawstr << bop->toString();
917 }
918 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
919 {
920 rawstr << uop->toString();
921 }
922 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
923 {
924 rawstr << cmp->toString();
925 }
926 else
927 assert(false && "what else kinds of nodes do we have??");
928
929 return rawstr.str();
930 }
931
933 static std::string getCompleteNodeLabel(NodeType *node, SVFG*)
934 {
935
936 std::string str;
937 std::stringstream rawstr(str);
938 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
939 {
940 rawstr << stmtNode->toString();
941 }
942 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
943 {
944 rawstr << bop->toString();
945 }
946 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
947 {
948 rawstr << uop->toString();
949 }
950 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
951 {
952 rawstr << cmp->toString();
953 }
954 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
955 {
956 rawstr << mphi->toString();
957 }
958 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
959 {
960 rawstr << tphi->toString();
961 }
962 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
963 {
964 rawstr << fi->toString();
965 }
966 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
967 {
968 rawstr << fo->toString();
969 }
970 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
971 {
972 rawstr << fp->toString();
973 }
974 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
975 {
976 rawstr << ai->toString();
977 }
978 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
979 {
980 rawstr << ao->toString();
981 }
982 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
983 {
984 rawstr << ap->toString();
985 }
986 else if(NullPtrSVFGNode* nptr = SVFUtil::dyn_cast<NullPtrSVFGNode>(node))
987 {
988 rawstr << nptr->toString();
989 }
990 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
991 {
992 rawstr << ar->toString();
993 }
994 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
995 {
996 rawstr << fr->toString();
997 }
998 else if (BranchVFGNode* br = SVFUtil::dyn_cast<BranchVFGNode>(node))
999 {
1000 rawstr << br->toString();
1001 }
1002 else
1003 assert(false && "what else kinds of nodes do we have??");
1004
1005 return rawstr.str();
1006 }
1007
1008 static std::string getNodeAttributes(NodeType *node, SVFG *graph)
1009 {
1010 std::string str;
1011 std::stringstream rawstr(str);
1012
1013 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
1014 {
1015 const SVFStmt* edge = stmtNode->getSVFStmt();
1016 if (SVFUtil::isa<AddrStmt>(edge))
1017 {
1018 rawstr << "color=green";
1019 }
1020 else if (SVFUtil::isa<CopyStmt>(edge))
1021 {
1022 rawstr << "color=black";
1023 }
1024 else if (SVFUtil::isa<RetPE>(edge))
1025 {
1026 rawstr << "color=black,style=dotted";
1027 }
1028 else if (SVFUtil::isa<GepStmt>(edge))
1029 {
1030 rawstr << "color=purple";
1031 }
1032 else if (SVFUtil::isa<StoreStmt>(edge))
1033 {
1034 rawstr << "color=blue";
1035 }
1036 else if (SVFUtil::isa<LoadStmt>(edge))
1037 {
1038 rawstr << "color=red";
1039 }
1040 else
1041 {
1042 assert(0 && "No such kind edge!!");
1043 }
1044 rawstr << "";
1045 }
1046 else if(SVFUtil::isa<MSSAPHISVFGNode>(node))
1047 {
1048 rawstr << "color=black";
1049 }
1050 else if(SVFUtil::isa<PHISVFGNode>(node))
1051 {
1052 rawstr << "color=black";
1053 }
1054 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
1055 {
1056 rawstr << "color=grey";
1057 }
1058 else if(SVFUtil::isa<FormalINSVFGNode>(node))
1059 {
1060 rawstr << "color=yellow,penwidth=2";
1061 }
1062 else if(SVFUtil::isa<FormalOUTSVFGNode>(node))
1063 {
1064 rawstr << "color=yellow,penwidth=2";
1065 }
1066 else if(SVFUtil::isa<FormalParmSVFGNode>(node))
1067 {
1068 rawstr << "color=yellow,penwidth=2";
1069 }
1070 else if(SVFUtil::isa<ActualINSVFGNode>(node))
1071 {
1072 rawstr << "color=yellow,penwidth=2";
1073 }
1074 else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
1075 {
1076 rawstr << "color=yellow,penwidth=2";
1077 }
1078 else if(SVFUtil::isa<ActualParmSVFGNode>(node))
1079 {
1080 rawstr << "color=yellow,penwidth=2";
1081 }
1082 else if (SVFUtil::isa<ActualRetSVFGNode>(node))
1083 {
1084 rawstr << "color=yellow,penwidth=2";
1085 }
1086 else if (SVFUtil::isa<FormalRetSVFGNode>(node))
1087 {
1088 rawstr << "color=yellow,penwidth=2";
1089 }
1090 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1091 {
1092 rawstr << "color=black,penwidth=2";
1093 }
1094 else if (SVFUtil::isa<CmpVFGNode>(node))
1095 {
1096 rawstr << "color=black,penwidth=2";
1097 }
1098 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1099 {
1100 rawstr << "color=black,penwidth=2";
1101 }
1102 else if (SVFUtil::isa<BranchVFGNode>(node))
1103 {
1104 rawstr << "color=gold,penwidth=2";
1105 }
1106 else
1107 assert(false && "no such kind of node!!");
1108
1110 if(graph->getStat()->isSource(node))
1111 {
1112 rawstr << ",style=filled, fillcolor=red";
1113 }
1114 else if(graph->getStat()->isSink(node))
1115 {
1116 rawstr << ",style=filled, fillcolor=blue";
1117 }
1118 else if(graph->getStat()->inBackwardSlice(node))
1119 {
1120 rawstr << ",style=filled, fillcolor=yellow";
1121 }
1122 else if(graph->getStat()->inForwardSlice(node))
1123 rawstr << ",style=filled, fillcolor=gray";
1124
1125 rawstr << "";
1126
1127 return rawstr.str();
1128 }
1129
1130 template<class EdgeIter>
1132 {
1133 SVFGEdge* edge = *(EI.getCurrent());
1134 assert(edge && "No edge found!!");
1135 if (SVFUtil::isa<DirectSVFGEdge>(edge))
1136 {
1137 if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1138 return "style=solid,color=red";
1139 else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1140 return "style=solid,color=blue";
1141 else
1142 return "style=solid";
1143 }
1144 else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1145 {
1146 if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1147 return "style=dashed,color=red";
1148 else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1149 return "style=dashed,color=blue";
1150 else
1151 return "style=dashed";
1152 }
1153 return "";
1154 }
1155
1156 template<class EdgeIter>
1158 {
1159 SVFGEdge* edge = *(EI.getCurrent());
1160 assert(edge && "No edge found!!");
1161
1162 std::string str;
1163 std::stringstream rawstr(str);
1164 if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1165 rawstr << dirCall->getCallSiteId();
1166 else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1167 rawstr << dirRet->getCallSiteId();
1168 else if (CallIndSVFGEdge* indCall = SVFUtil::dyn_cast<CallIndSVFGEdge>(edge))
1169 rawstr << indCall->getCallSiteId();
1170 else if (RetIndSVFGEdge* indRet = SVFUtil::dyn_cast<RetIndSVFGEdge>(edge))
1171 rawstr << indRet->getCallSiteId();
1172
1173 return rawstr.str();
1174 }
1175};
1176} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DGENERAL
Definition SVFType.h:599
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
Set< const CallICFGNode * > CallInstSet
Definition CallGraph.h:55
const std::string getSourceLoc() const override
Definition ICFGNode.h:570
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.
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 FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:74
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
Definition ICFG.cpp:249
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:242
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:67
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 FunObjVar * getFun() const
Get the function of this SVFGNode.
Definition SVFGNode.h:411
const CallICFGNode * getCallSite() const
Definition SVFGNode.h:417
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:149
static const Option< std::string > WriteSVFG
Definition Options.h:148
static const Option< bool > ShowHiddenNode
Definition Options.h:225
CallSiteID getCallSiteId() const
Definition SVFGEdge.h:175
virtual const std::string toString() const
Definition SVFG.cpp:175
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
virtual void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode *actualOut, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:354
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:231
FormalOUTSVFGNodeSet & getFormalOUTSVFGNodes(const FunObjVar *fun)
Definition SVFG.h:241
FormalINSVFGNodeSet & getFormalINSVFGNodes(const FunObjVar *fun)
Definition SVFG.h:236
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:316
virtual void getInterVFEdgeAtIndCSFromAPToFP(const ValVar *cs_arg, const ValVar *fun_arg, const CallICFGNode *, CallSiteID csId, SVFGEdgeSetTy &edges)
Get inter value flow edges between indirect call site and callee.
Definition SVFG.h:326
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
virtual void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode *actualIn, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:344
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 getInterVFEdgesForIndirectCallSite(const CallICFGNode *cs, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Get all inter value flow edges of a indirect call site.
Definition SVFG.cpp:584
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:453
ActualINSVFGNodeSet & getActualINSVFGNodes(const CallICFGNode *cs)
Get SVFGNode set.
Definition SVFG.h:226
bool addSVFGEdge(SVFGEdge *edge)
Add SVFG edge.
Definition SVFG.h:265
void addActualOUTSVFGNode(const CallICFGNode *callsite, const MRVer *resVer, const NodeID nodeId)
Add memory callsite chi SVFG node.
Definition SVFG.h:444
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:428
void destroy()
Clean up memory.
Definition SVFG.cpp:212
virtual void connectCallerAndCallee(const CallICFGNode *cs, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition SVFG.cpp:658
bool hasCallSiteMu(const CallICFGNode *cs) const
Definition SVFG.h:477
MemSSA::LOADMU LOADMU
Definition SVFG.h:92
MemSSA::CHISet CHISet
Definition SVFG.h:88
void setDef(const ValVar *valVar, const SVFGNode *node)
Given a ValVar, set/get its def SVFG node (definition of top level pointers)
Definition SVFG.h:368
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:436
bool hasFuncRetMu(const FunObjVar *func) const
Definition SVFG.h:469
NodeID getDef(const ValVar *valVar) const
Definition SVFG.h:372
const Set< const SVFGNode * > getDefSiteOfObjVar(const ObjVar *obj, const SVFGNode *node) const
Definition SVFG.cpp:772
virtual void readFile(const std::string &filename)
std::unique_ptr< MemSSA > mssa
Definition SVFG.h:106
void addFormalINSVFGNode(const FunEntryICFGNode *funEntry, const MRVer *resVer, const NodeID nodeId)
Add memory Function entry chi SVFG node.
Definition SVFG.h:419
const Set< const SVFGNode * > getUseSitesOfObjVar(const ObjVar *obj, const SVFGNode *node) const
Definition SVFG.cpp:807
void addSVFGNodesForAddrTakenVars()
Create SVFG nodes for address-taken variables.
Definition SVFG.cpp:255
const Set< const SVFGNode * > getUseSitesOfValVar(const ValVar *var) const
Definition SVFG.cpp:790
virtual void getInterVFEdgeAtIndCSFromFRToAR(const ValVar *fun_ret, const ValVar *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges)
Definition SVFG.h:335
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:309
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
const SVFGNode * getDefSiteOfValVar(const ValVar *var) const
Definition SVFG.cpp:765
bool hasCallSiteChi(const CallICFGNode *cs) const
Definition SVFG.h:473
bool hasFuncEntryChi(const FunObjVar *func) const
Has function for EntryCHI/RetMU/CallCHI/CallMU.
Definition SVFG.h:465
void performStat()
Perform statistics.
Definition SVFG.cpp:758
const FunObjVar * isFunEntrySVFGNode(const SVFGNode *node) const
Whether a node is function entry SVFGNode.
Definition SVFG.cpp:706
void clearMSSA()
Clear MSSA.
Definition SVFG.h:132
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
Definition SVFG.h:171
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:505
bool funHasRet(const FunObjVar *func) const
Definition SVFIR.h:427
bool hasFunArgsList(const FunObjVar *func) const
Function has arguments list.
Definition SVFIR.h:366
const ValVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:405
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:376
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:58
ICFG * getICFG() const
Definition SVFIR.h:229
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:383
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:411
const ValVar * getFunRet(const FunObjVar *func) const
Get function return list.
Definition SVFIR.h:421
const ValVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:393
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:137
virtual void startClk()
Definition SVFStat.h:58
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
NodeID getId() const
Get ID.
Definition SVFValue.h:163
virtual const std::string & getName() const
Definition SVFValue.h:189
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:740
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 FunObjVar * 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
VFGNodeIDToNodeMapTy::iterator iterator
Definition VFG.h:80
SVFIR * pag
Definition VFG.h:104
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *func) const
Get callsite given a callsiteID.
Definition VFG.h:178
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition VFG.h:413
GlobalVFGNodeSet globalVFGNodes
set of global store VFG nodes
Definition VFG.h:102
StmtVFGNode * getStmtVFGNode(const SVFStmt *svfStmt) const
Get an VFGNode.
Definition VFG.h:261
virtual SVFStmt::SVFStmtSetTy & getSVFStmtSet(SVFStmt::PEDGEK kind)
Get SVFStmt set.
Definition VFG.h:498
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:852
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:887
virtual bool isInterestedSVFVar(const SVFVar *node) const
Definition VFG.h:506
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition VFG.cpp:870
virtual void connectCallerAndCallee(const CallICFGNode *cs, const FunObjVar *callee, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition VFG.cpp:950
const FunObjVar * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:410
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:101
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition SVFUtil.h:420
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:58
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
static std::string getGraphName(SVFG *)
Return name of the graph.
Definition SVFG.cpp:840
std::string getNodeLabel(NodeType *node, SVFG *graph)
Definition SVFG.cpp:853
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition SVFG.cpp:1157
static std::string getSimpleNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node without MemSSA information.
Definition SVFG.cpp:862
static bool isNodeHidden(SVFGNode *node, SVFG *)
Definition SVFG.cpp:847
DOTGraphTraits(bool isSimple=false)
Definition SVFG.cpp:834
static std::string getNodeAttributes(NodeType *node, SVFG *graph)
Definition SVFG.cpp:1008
static std::string getCompleteNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node with MemSSA information.
Definition SVFG.cpp:933
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVFG *)
Definition SVFG.cpp:1131