Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFIR.cpp
Go to the documentation of this file.
1//===- SVFIR.cpp -- IR of SVF ---------------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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 * SVFIR.cpp
25 *
26 * Created on: 31, 12, 2021
27 * Author: Yulei Sui
28 */
29
30#include "Util/Options.h"
31#include "SVFIR/SVFIR.h"
32#include "Graphs/CHG.h"
33#include "Graphs/CallGraph.h"
34
35using namespace SVF;
36using namespace SVFUtil;
37
38
39std::unique_ptr<SVFIR> SVFIR::pag;
40
41std::string SVFIR::pagReadFromTxt = "";
42
43SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), icfg(nullptr), chgraph(nullptr)
44{
45}
46
47
48const FunObjVar *SVFIR::getFunObjVar(const std::string &name)
49{
50 for (const auto &item: *callGraph)
51 {
52 if (item.second->getName() == name)
53 {
54 return item.second->getFunction();
55 }
56 }
57 return nullptr;
58}
59
60
65{
66 SVFVar* srcNode = getGNode(src);
67 SVFVar* dstNode = getGNode(dst);
68 if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Addr))
69 return nullptr;
70 else
71 {
72 AddrStmt* addrPE = new AddrStmt(srcNode, dstNode);
73 addAddrStmt(addrPE);
74 return addrPE;
75 }
76}
78{
80 addEdge(getGNode(edge->getRHSVarID()),getGNode(edge->getLHSVarID()), edge);
81}
82
87{
88 SVFVar* srcNode = getGNode(src);
89 SVFVar* dstNode = getGNode(dst);
90 if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Copy))
91 return nullptr;
92 else
93 {
94 CopyStmt* copyPE = new CopyStmt(srcNode, dstNode, type);
95 addCopyStmt(copyPE);
96 return copyPE;
97 }
98}
99
101{
102 addToStmt2TypeMap(edge);
103 addEdge(getGNode(edge->getRHSVarID()),getGNode(edge->getLHSVarID()), edge);
104}
105
110{
111 ValVar* opNode = const_cast<ValVar*>(getValVar(opnd));
112 ValVar* resNode = const_cast<ValVar*>(getValVar(res));
113 PHINodeMap::iterator it = phiNodeMap.find(resNode);
114 if(it == phiNodeMap.end())
115 {
116 PhiStmt* phi = new PhiStmt(resNode, {opNode}, {pred});
117 addPhiStmt(phi, opNode, resNode);
118 return phi;
119 }
120 else
121 {
122 it->second->addOpVar(opNode,pred);
124 return nullptr;
125 }
126}
127
128void SVFIR::addPhiStmt(PhiStmt* edge, SVFVar* src, SVFVar* dst)
129{
130 SVFVar* opNode = src;
131 SVFVar* resNode = dst;
132
133 addToStmt2TypeMap(edge);
134 addEdge(opNode, resNode, edge);
135 phiNodeMap[resNode] = edge;
136
137}
138
143{
144 ValVar* op1Node = const_cast<ValVar*>(getValVar(op1));
145 ValVar* op2Node = const_cast<ValVar*>(getValVar(op2));
146 ValVar* dstNode = const_cast<ValVar*>(getValVar(res));
147 const SVFVar* condNode = getGNode(cond);
148 if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Select, op2Node))
149 return nullptr;
150 else
151 {
152 std::vector<ValVar*> opnds = {op1Node, op2Node};
153 SelectStmt* select = new SelectStmt(dstNode, opnds, condNode);
154 addSelectStmt(select, op1Node, dstNode);
155 return select;
156 }
157}
158
160{
161 addToStmt2TypeMap(edge);
162 addEdge(src, dst, edge);
163}
164
169{
170 ValVar* op1Node = const_cast<ValVar*>(getValVar(op1));
171 ValVar* op2Node = const_cast<ValVar*>(getValVar(op2));
172 ValVar* dstNode = const_cast<ValVar*>(getValVar(dst));
173 if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Cmp, op2Node))
174 return nullptr;
175 else
176 {
177 std::vector<ValVar*> opnds = {op1Node, op2Node};
178 CmpStmt* cmp = new CmpStmt(dstNode, opnds, predicate);
179 addCmpStmt(cmp, op1Node, dstNode);
180 return cmp;
181 }
182}
183
184void SVFIR::addCmpStmt(CmpStmt* edge, SVFVar* src, SVFVar* dst)
185{
186 addToStmt2TypeMap(edge);
187 addEdge(src, dst, edge);
188}
189
190
195{
196 ValVar* op1Node = const_cast<ValVar*>(getValVar(op1));
197 ValVar* op2Node = const_cast<ValVar*>(getValVar(op2));
198 ValVar* dstNode = const_cast<ValVar*>(getValVar(dst));
199 if(hasLabeledEdge(op1Node, dstNode, SVFStmt::BinaryOp, op2Node))
200 return nullptr;
201 else
202 {
203 std::vector<ValVar*> opnds = {op1Node, op2Node};
204 BinaryOPStmt* binaryOP = new BinaryOPStmt(dstNode, opnds, opcode);
205 addBinaryOPStmt(binaryOP,op1Node,dstNode);
206 return binaryOP;
207 }
208}
209
211{
212 addToStmt2TypeMap(edge);
213 addEdge(src, dst, edge);
214}
215
219{
220 ValVar* srcNode = const_cast<ValVar*>(getValVar(src));
221 ValVar* dstNode = const_cast<ValVar*>(getValVar(dst));
222 if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::UnaryOp))
223 return nullptr;
224 else
225 {
226 UnaryOPStmt* unaryOP = new UnaryOPStmt(srcNode, dstNode, opcode);
227 addUnaryOPStmt(unaryOP, srcNode,dstNode);
228 return unaryOP;
229 }
230}
231
233{
234 addToStmt2TypeMap(edge);
235 addEdge(src, dst, edge);
236}
237
238/*
239* Add BranchStmt
240*/
242{
243 ValVar* brNode = const_cast<ValVar*>(getValVar(br));
244 ValVar* condNode = const_cast<ValVar*>(getValVar(cond));
245 if(hasNonlabeledEdge(condNode,brNode, SVFStmt::Branch))
246 return nullptr;
247 else
248 {
249 BranchStmt* branch = new BranchStmt(brNode, condNode, succs);
250 addBranchStmt(branch,condNode,brNode);
251 return branch;
252 }
253}
254
256{
257 addToStmt2TypeMap(edge);
258 addEdge(src, dst, edge);
259}
260
265{
266 SVFVar* srcNode = getGNode(src);
267 SVFVar* dstNode = getGNode(dst);
268 if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Load))
269 return nullptr;
270 else
271 {
272 LoadStmt* loadPE = new LoadStmt(srcNode, dstNode);
273 addLoadStmt(loadPE);
274 return loadPE;
275 }
276}
277
279{
280 addToStmt2TypeMap(edge);
281 addEdge(getGNode(edge->getRHSVarID()),getGNode(edge->getLHSVarID()), edge);
282}
283
289{
290 SVFVar* srcNode = getGNode(src);
291 SVFVar* dstNode = getGNode(dst);
292 if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Store, curVal))
293 return nullptr;
294 else
295 {
296 StoreStmt* storePE = new StoreStmt(srcNode, dstNode, curVal);
297 addStoreStmt(storePE,srcNode,dstNode);
298 return storePE;
299 }
300}
301
303{
304 addToStmt2TypeMap(edge);
305 addEdge(src,dst, edge);
306}
307
312{
313 ValVar* opNode = const_cast<ValVar*>(getValVar(src));
314 ValVar* resNode = const_cast<ValVar*>(getValVar(dst));
315 FParmToCallPEMap::iterator it = fParmToCallPEMap.find(resNode);
316 // if first operand, create a new CallPE, otherwise add the operand to the existing CallPE
317 if(it == fParmToCallPEMap.end())
318 {
319 CallPE* callPE = new CallPE(resNode, {opNode}, {cs}, entry);
320 addCallPE(callPE, opNode, resNode);
321 return callPE;
322 }
323 else
324 {
325 it->second->addOpVar(opNode, cs);
327 return nullptr;
328 }
329}
330
331void SVFIR::addCallPE(CallPE* edge, SVFVar* src, SVFVar* dst)
332{
333 addToStmt2TypeMap(edge);
334 addEdge(src, dst, edge);
335 fParmToCallPEMap[dst] = edge;
336}
337
342{
343 SVFVar* srcNode = getGNode(src);
344 SVFVar* dstNode = getGNode(dst);
345 if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Ret, cs))
346 return nullptr;
347 else
348 {
349 RetPE* retPE = new RetPE(srcNode, dstNode, cs, exit);
350 addRetPE(retPE,srcNode,dstNode);
351 return retPE;
352 }
353}
354
355void SVFIR::addRetPE(RetPE* edge, SVFVar* src, SVFVar* dst)
356{
357 addToStmt2TypeMap(edge);
358 addEdge(src, dst, edge);
359}
360
365{
367 return pag->addAddrStmt(pag->getBlackHoleNode(), node);
368 else
369 return pag->addCopyStmt(pag->getNullPtr(), node, CopyStmt::COPYVAL);
370}
371
376{
377 ValVar* opNode = const_cast<ValVar*>(getValVar(src));
378 ValVar* resNode = const_cast<ValVar*>(getValVar(dst));
379 FParmToCallPEMap::iterator it = fParmToCallPEMap.find(resNode);
380 // if first operand, create a new TDForkPE, otherwise add the operand to the existing TDForkPE
381 if(it == fParmToCallPEMap.end())
382 {
383 TDForkPE* forkPE = new TDForkPE(resNode, {opNode}, {cs}, entry);
384 addToStmt2TypeMap(forkPE);
385 addEdge(opNode, resNode, forkPE);
386 fParmToCallPEMap[resNode] = forkPE;
387 return forkPE;
388 }
389 else
390 {
391 it->second->addOpVar(opNode, cs);
392 return nullptr;
393 }
394}
395
400{
401 SVFVar* srcNode = getGNode(src);
402 SVFVar* dstNode = getGNode(dst);
403 if(hasLabeledEdge(srcNode,dstNode, SVFStmt::ThreadJoin, cs))
404 return nullptr;
405 else
406 {
407 TDJoinPE* joinPE = new TDJoinPE(srcNode, dstNode, cs, exit);
408 addRetPE(joinPE,srcNode,dstNode);
409 return joinPE;
410 }
411}
412
413
419GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const AccessPath& ap, bool constGep)
420{
421
422 SVFVar* node = getGNode(src);
423 if (!constGep || node->hasIncomingVariantGepEdge())
424 {
427 return addVariantGepStmt(src, dst, ap);
428 }
429 else
430 {
431 return addNormalGepStmt(src, dst, ap);
432 }
433}
434
439{
440 SVFVar* baseNode = getGNode(src);
441 SVFVar* dstNode = getGNode(dst);
442 if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep))
443 return nullptr;
444 else
445 {
446 GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap);
447 addGepStmt(gepPE);
448 return gepPE;
449 }
450}
451
453{
454 SVFVar* baseNode = getGNode(gepPE->getRHSVarID());
455 SVFVar* dstNode = getGNode(gepPE->getLHSVarID());
456 addToStmt2TypeMap(gepPE);
457 addEdge(baseNode, dstNode, gepPE);
458
459}
460
466{
467 SVFVar* baseNode = getGNode(src);
468 SVFVar* dstNode = getGNode(dst);
469 if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep))
470 return nullptr;
471 else
472 {
473 GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap, true);
474 addToStmt2TypeMap(gepPE);
475 addEdge(baseNode, dstNode, gepPE);
476 return gepPE;
477 }
478}
479
480
481
486NodeID SVFIR::addGepValNode(NodeID curInst,const ValVar* baseVar, const AccessPath& ap, NodeID i, const SVFType* type, const ICFGNode* icn)
487{
488 NodeID base = baseVar->getId();
489 //assert(findPAGNode(i) == false && "this node should not be created before");
490 assert(0==GepValObjMap[curInst].count(std::make_pair(base, ap))
491 && "this node should not be created before");
492 GepValObjMap[curInst][std::make_pair(base, ap)] = i;
493 GepValVar *node = new GepValVar(baseVar, i, ap, type, icn);
494 node->setLLVMVarInstID(curInst);
495 return addValNode(node);
496}
497
502{
503 const SVFVar* node = pag->getSVFVar(id);
504 if (const GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
505 return getGepObjVar(gepNode->getBaseObj(), gepNode->getConstantFieldIdx() + apOffset);
506 else if (const BaseObjVar* baseNode = SVFUtil::dyn_cast<BaseObjVar>(node))
507 return getGepObjVar(baseNode, apOffset);
508 else if (const DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
509 return getGepObjVar(baseNode, apOffset);
510 else
511 {
512 assert(false && "new gep obj node kind?");
513 return id;
514 }
515}
516
523NodeID SVFIR::getGepObjVar(const BaseObjVar* baseObj, const APOffset& apOffset)
524{
525 NodeID base = baseObj->getId();
526
528 if (baseObj->isFieldInsensitive())
529 return getFIObjVar(baseObj);
530
531 APOffset newLS = pag->getModulusOffset(baseObj, apOffset);
532
533 // Base and first field are the same memory location.
534 if (Options::FirstFieldEqBase() && newLS == 0) return base;
535
536 OffsetToGepVarMap::iterator iter = GepObjVarMap.find(std::make_pair(base, newLS));
537 if (iter == GepObjVarMap.end())
538 {
540 return addGepObjNode(baseObj, newLS, gepId);
541 }
542 else
543 return iter->second;
544
545}
546
547NodeID SVFIR::addGepObjNode(GepObjVar* gepObj, NodeID base, const APOffset& apOffset)
548{
549 assert(0==GepObjVarMap.count(std::make_pair(base, apOffset))
550 && "this node should not be created before");
551 GepObjVarMap[std::make_pair(base, apOffset)] = gepObj->getId();
552 memToFieldsMap[base].set(gepObj->getId());
553 return addObjNode(gepObj);
554}
555
559NodeID SVFIR::addGepObjNode(const BaseObjVar* baseObj, const APOffset& apOffset, const NodeID gepId)
560{
561 //assert(findPAGNode(i) == false && "this node should not be created before");
562 NodeID base = baseObj->getId();
563 assert(0==GepObjVarMap.count(std::make_pair(base, apOffset))
564 && "this node should not be created before");
565 //ABTest
566 GepObjVar *node = new GepObjVar(baseObj, gepId, apOffset);
567 return addGepObjNode(node, base, apOffset);
568}
569
574{
575 NodeID base = obj->getId();
576 return memToFieldsMap[base];
577}
578
583{
584 const SVFVar* node = pag->getSVFVar(id);
585 (void)node; // Suppress warning of unused variable under release build
586 assert(SVFUtil::isa<ObjVar>(node) && "need an object node");
588}
589
596{
597 const SVFVar* node = pag->getSVFVar(id);
598 (void)node; // Suppress warning of unused variable under release build
599 assert(SVFUtil::isa<ObjVar>(node) && "need an object node");
600 const BaseObjVar* obj = getBaseObject(id);
601 if(obj->isFieldInsensitive())
602 {
603 NodeBS bs;
604 bs.set(getFIObjVar(obj));
605 return bs;
606 }
607 else
608 return getAllFieldsObjVars(obj);
609}
610
614NodeID SVFIR::getGepValVar(NodeID curInst, NodeID base, const AccessPath& ap) const
615{
616 GepValueVarMap::const_iterator iter = GepValObjMap.find(curInst);
617 if(iter==GepValObjMap.end())
618 {
619 return UINT_MAX;
620 }
621 else
622 {
623 NodeAccessPathMap::const_iterator lit =
624 iter->second.find(std::make_pair(base, ap));
625 if (lit == iter->second.end())
626 return UINT_MAX;
627 else
628 return lit->second;
629 }
630}
631
632
637{
638 delete icfg;
639 icfg = nullptr;
640 delete chgraph;
641 chgraph = nullptr;
642 delete callGraph;
643 callGraph = nullptr;
644}
645
650{
651
652 outs() << "-------------------SVFIR------------------------------------\n";
653 SVFStmt::SVFStmtSetTy& addrs = pag->getSVFStmtSet(SVFStmt::Addr);
654 for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
655 addrs.end(); iter != eiter; ++iter)
656 {
657 outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID()
658 << "\n";
659 }
660
661 SVFStmt::SVFStmtSetTy& copys = pag->getSVFStmtSet(SVFStmt::Copy);
662 for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
663 copys.end(); iter != eiter; ++iter)
664 {
665 outs() << (*iter)->getSrcID() << " -- Copy --> " << (*iter)->getDstID()
666 << "\n";
667 }
668
669 SVFStmt::SVFStmtSetTy& calls = pag->getSVFStmtSet(SVFStmt::Call);
670 for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
671 calls.end(); iter != eiter; ++iter)
672 {
673 outs() << (*iter)->getSrcID() << " -- Call --> " << (*iter)->getDstID()
674 << "\n";
675 }
676
677 SVFStmt::SVFStmtSetTy& rets = pag->getSVFStmtSet(SVFStmt::Ret);
678 for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter =
679 rets.end(); iter != eiter; ++iter)
680 {
681 outs() << (*iter)->getSrcID() << " -- Ret --> " << (*iter)->getDstID()
682 << "\n";
683 }
684
685 SVFStmt::SVFStmtSetTy& tdfks = pag->getSVFStmtSet(SVFStmt::ThreadFork);
686 for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
687 tdfks.end(); iter != eiter; ++iter)
688 {
689 outs() << (*iter)->getSrcID() << " -- ThreadFork --> "
690 << (*iter)->getDstID() << "\n";
691 }
692
693 SVFStmt::SVFStmtSetTy& tdjns = pag->getSVFStmtSet(SVFStmt::ThreadJoin);
694 for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter =
695 tdjns.end(); iter != eiter; ++iter)
696 {
697 outs() << (*iter)->getSrcID() << " -- ThreadJoin --> "
698 << (*iter)->getDstID() << "\n";
699 }
700
701 SVFStmt::SVFStmtSetTy& ngeps = pag->getSVFStmtSet(SVFStmt::Gep);
702 for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
703 ngeps.end(); iter != eiter; ++iter)
704 {
705 GepStmt* gep = SVFUtil::cast<GepStmt>(*iter);
706 if(gep->isVariantFieldGep())
707 outs() << (*iter)->getSrcID() << " -- VariantGep --> "
708 << (*iter)->getDstID() << "\n";
709 else
710 outs() << gep->getRHSVarID() << " -- Gep (" << gep->getConstantStructFldIdx()
711 << ") --> " << gep->getLHSVarID() << "\n";
712 }
713
714 SVFStmt::SVFStmtSetTy& loads = pag->getSVFStmtSet(SVFStmt::Load);
715 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
716 loads.end(); iter != eiter; ++iter)
717 {
718 outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID()
719 << "\n";
720 }
721
722 SVFStmt::SVFStmtSetTy& stores = pag->getSVFStmtSet(SVFStmt::Store);
723 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
724 stores.end(); iter != eiter; ++iter)
725 {
726 outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID()
727 << "\n";
728 }
729 outs() << "----------------------------------------------------------\n";
730
731}
732
735{
736 // collect candidate pointers for demand-driven analysis
737 for (iterator nIter = begin(); nIter != end(); ++nIter)
738 {
739 NodeID nodeId = nIter->first;
740 // do not compute points-to for isolated node
741 if (isValidPointer(nodeId) == false)
742 continue;
743 candidatePointers.insert(nodeId);
744 }
745}
746/*
747 * If this is a dummy node or node does not have incoming edges and outgoing edges we assume it is not a pointer here.
748 * However, if it is a pointer and it is an argument of a function definition, we assume it is a pointer here.
749 */
751{
752 const SVFVar* node = pag->getSVFVar(nodeId);
753
754 if(node->isPointer())
755 if (const ValVar* pVar = pag->getBaseValVar(nodeId))
756 if (const ArgValVar* arg = SVFUtil::dyn_cast<ArgValVar>(pVar))
757 if (!(arg->getParent()->isDeclaration()))
758 return true;
759
760 if ((node->getInEdges().empty() && node->getOutEdges().empty()))
761 return false;
762 return node->isPointer();
763}
764
766{
767 if (SVFUtil::isa<ValVar>(node))
768 {
769 if (isValidPointer(node->getId()))
770 {
771 const ValVar* baseVar = pag->getBaseValVar(node->getId());
773 return !SVFUtil::isArgOfUncalledFunction(baseVar);
774 }
775 }
776 return false;
777}
778
783{
784 Options::HandBlackHole.setValue(b);
785}
786
788{
789 assert(node && "node cannot be nullptr.");
790 assert(hasGNode(node->getId()) == false &&
791 "This NodeID clashes here. Please check NodeIDAllocator. Switch "
792 "Strategy::DBUG to SEQ or DENSE");
793 return addNode(node);
794}
795
797{
798 assert(node && "node cannot be nullptr.");
799 assert(hasGNode(node->getId()) == false &&
800 "This NodeID clashes here. Please check NodeIDAllocator. Switch "
801 "Strategy::DBUG to SEQ or DENSE");
802 NodeID id = addNode(node);
803 // An object's constness is fixed by the time its node is added: SymbolTableBuilder sets
804 // the constant flags before the SVFIR is built, and a field object (GepObjVar) shares
805 // the constness of its base object, which is added first.
806 const BaseObjVar* obj = getBaseObject(id);
807 assert(obj && "not an object node?");
808 if (isConstantSym(id) || obj->isConstDataOrConstGlobal())
809 constantObjs.insert(id);
810 return id;
811}
812
814{
815 return addObjNode(node);
816}
newitem type
Definition cJSON.cpp:2739
const cJSON *const b
Definition cJSON.h:255
const char *const name
Definition cJSON.h:264
cJSON * item
Definition cJSON.h:222
int count
Definition cJSON.h:216
Class representing a function argument variable in the SVFIR.
NodeID getRHSVarID() const
NodeID getLHSVarID() const
bool isConstDataOrConstGlobal() const
NodeID getId() const
Get the memory object id.
bool isFieldInsensitive() const
Return true if its field limit is 0.
std::vector< std::pair< const ICFGNode *, s64_t > > SuccAndCondPairVec
IDToNodeMapTy::iterator iterator
NodeType * getGNode(NodeID id) const
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
APOffset getConstantStructFldIdx() const
Field index of the gep statement if it access the field of a struct.
void setLLVMVarInstID(NodeID id)
Set the LLVM variable ID associated with this GepValVar.
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
Definition IRGraph.cpp:308
NodeID addNode(SVFVar *node)
Add a node into the graph.
Definition IRGraph.h:116
IRGraph(bool buildFromFile)
Definition IRGraph.h:139
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
Definition IRGraph.cpp:270
static bool isConstantSym(NodeID id)
Definition IRGraph.h:173
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
Definition IRGraph.cpp:285
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateGepObjectId(NodeID base, u32_t offset, u32_t maxFieldLimit)
static const Option< bool > FirstFieldEqBase
Definition Options.h:100
static Option< bool > HandBlackHole
Definition Options.h:98
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
GepStmt * addVariantGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Variant(Gep) edge.
Definition SVFIR.cpp:465
CopyStmt * addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type)
Add Copy edge.
Definition SVFIR.cpp:86
NodeID getGepValVar(NodeID curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
Definition SVFIR.cpp:614
RetPE * addRetPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
Definition SVFIR.cpp:341
GepStmt * addGepStmt(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
Definition SVFIR.cpp:419
void print()
Print SVFIR.
Definition SVFIR.cpp:649
static void handleBlackHole(bool b)
SVFIR build configurations.
Definition SVFIR.cpp:782
FParmToCallPEMap fParmToCallPEMap
Map a formal param to its CallPE.
Definition SVFIR.h:91
void addToStmt2TypeMap(SVFStmt *edge)
Map a SVFStatement type to a set of corresponding SVF statements.
Definition SVFIR.h:603
CommonCHGraph * chgraph
Definition SVFIR.h:102
SVFStmt * addBlackHoleAddrStmt(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr).
Definition SVFIR.cpp:364
LoadStmt * addLoadStmt(NodeID src, NodeID dst)
Add Load edge.
Definition SVFIR.cpp:264
NodeID addGepValNode(NodeID curInst, const ValVar *base, const AccessPath &ap, NodeID i, const SVFType *type, const ICFGNode *node)
Add a temp field value node, this method can only invoked by getGepValVar.
Definition SVFIR.cpp:486
GepStmt * addNormalGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Offset(Gep) edge.
Definition SVFIR.cpp:438
MemObjToFieldsMap memToFieldsMap
Map a mem object id to all its fields.
Definition SVFIR.h:87
PHINodeMap phiNodeMap
A set of phi copy edges.
Definition SVFIR.h:90
NodeBS getFieldsAfterCollapse(NodeID id)
Definition SVFIR.cpp:595
NodeID addObjNode(NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Add a memory obj node.
Definition SVFIR.h:718
CallPE * addCallPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge (phi-like: merges actual params from all call sites into formal param).
Definition SVFIR.cpp:311
bool isValidTopLevelPtr(const SVFVar *node)
Definition SVFIR.cpp:765
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Thread join edge for parameter passing.
Definition SVFIR.cpp:399
CallGraph * callGraph
all the callsites of a program
Definition SVFIR.h:104
NodeSet constantObjs
Constant objects and their fields, recorded when each object node is added.
Definition SVFIR.h:88
static std::string pagReadFromTxt
Definition SVFIR.h:107
void destroy()
Clean up memory.
Definition SVFIR.cpp:636
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:499
const FunObjVar * getFunObjVar(const std::string &name)
Definition SVFIR.cpp:48
CmpStmt * addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
Definition SVFIR.cpp:168
AddrStmt * addAddrStmt(NodeID src, NodeID dst)
Add an edge into SVFIR.
Definition SVFIR.cpp:64
UnaryOPStmt * addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
Definition SVFIR.cpp:218
TDForkPE * addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
Definition SVFIR.cpp:375
BinaryOPStmt * addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
Definition SVFIR.cpp:194
NodeBS & getAllFieldsObjVars(const BaseObjVar *obj)
Get all fields of an object.
Definition SVFIR.cpp:573
static std::unique_ptr< SVFIR > pag
Callgraph with direct calls only; no change allowed after init and use callgraph in PointerAnalysis f...
Definition SVFIR.h:106
NodeID addValNode(NodeID i, const SVFType *type, const ICFGNode *icfgNode)
add node into SVFIR
Definition SVFIR.h:665
StoreStmt * addStoreStmt(NodeID src, NodeID dst, const ICFGNode *val)
Add Store edge.
Definition SVFIR.cpp:288
NodeID addGepObjNode(GepObjVar *gepObj, NodeID base, const APOffset &apOffset)
Definition SVFIR.cpp:547
OffsetToGepVarMap GepObjVarMap
Map a pair<base,off> to a gep obj node id.
Definition SVFIR.h:86
PhiStmt * addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add phi node information.
Definition SVFIR.cpp:109
OrderedNodeSet candidatePointers
Definition SVFIR.h:100
ICFG * icfg
Definition SVFIR.h:101
SVFIR(bool buildFromFile)
Constructor.
Definition SVFIR.cpp:43
SelectStmt * addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
Definition SVFIR.cpp:142
GepValueVarMap GepValObjMap
Map a pair<base,off> to a gep value node id.
Definition SVFIR.h:84
const GepObjVar * getGepObjVar(NodeID id) const
Definition SVFIR.h:170
bool isValidPointer(NodeID nodeId) const
Whether a node is a valid pointer.
Definition SVFIR.cpp:750
BranchStmt * addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add BranchStmt.
Definition SVFIR.cpp:241
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:140
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition SVFIR.cpp:734
NodeID getFIObjVar(const BaseObjVar *obj) const
Get a field-insensitive obj SVFIR node according to a mem obj.
Definition SVFIR.h:525
NodeID addDummyObjNode(const SVFType *type)
Definition SVFIR.h:570
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual bool isPointer() const
Check if this variable represents a pointer.
bool hasIncomingVariantGepEdge() const
Check for incoming variable field GEP edges.
void set(unsigned Idx)
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition Casting.h:360
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
bool isArgOfUncalledFunction(const SVFVar *svfvar)
Definition SVFUtil.cpp:511
std::ostream & outs()
Overwrite llvm::outs().
Definition SVFUtil.h:58
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition Casting.h:405
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:76
s64_t APOffset
Definition GeneralType.h:80
SparseBitVector NodeBS
Definition GeneralType.h:82
unsigned u32_t
Definition GeneralType.h:67