Static Value-Flow Analysis
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 
33 using namespace SVF;
34 using namespace SVFUtil;
35 
36 
37 std::unique_ptr<SVFIR> SVFIR::pag;
38 
39 SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), svfModule(nullptr), icfg(nullptr), chgraph(nullptr)
40 {
41 }
42 
47 {
48  SVFVar* srcNode = getGNode(src);
49  SVFVar* dstNode = getGNode(dst);
50  if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Addr))
51  return nullptr;
52  else
53  {
54  AddrStmt* addrPE = new AddrStmt(srcNode, dstNode);
55  addToStmt2TypeMap(addrPE);
56  addEdge(srcNode,dstNode, addrPE);
57  return addrPE;
58  }
59 }
60 
65 {
66  SVFVar* srcNode = getGNode(src);
67  SVFVar* dstNode = getGNode(dst);
68  if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Copy))
69  return nullptr;
70  else
71  {
72  CopyStmt* copyPE = new CopyStmt(srcNode, dstNode, type);
73  addToStmt2TypeMap(copyPE);
74  addEdge(srcNode,dstNode, copyPE);
75  return copyPE;
76  }
77 }
78 
83 {
84  SVFVar* opNode = getGNode(opnd);
85  SVFVar* resNode = getGNode(res);
86  PHINodeMap::iterator it = phiNodeMap.find(resNode);
87  if(it == phiNodeMap.end())
88  {
89  PhiStmt* phi = new PhiStmt(resNode, {opNode}, {pred});
90  addToStmt2TypeMap(phi);
91  addEdge(opNode, resNode, phi);
92  phiNodeMap[resNode] = phi;
93  return phi;
94  }
95  else
96  {
97  it->second->addOpVar(opNode,pred);
99  return nullptr;
100  }
101 }
102 
107 {
108  SVFVar* op1Node = getGNode(op1);
109  SVFVar* op2Node = getGNode(op2);
110  SVFVar* dstNode = getGNode(res);
111  SVFVar* condNode = getGNode(cond);
112  if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Select, op2Node))
113  return nullptr;
114  else
115  {
116  std::vector<SVFVar*> opnds = {op1Node, op2Node};
117  SelectStmt* select = new SelectStmt(dstNode, opnds, condNode);
118  addToStmt2TypeMap(select);
119  addEdge(op1Node, dstNode, select);
120  return select;
121  }
122 }
123 
127 CmpStmt* SVFIR::addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predicate)
128 {
129  SVFVar* op1Node = getGNode(op1);
130  SVFVar* op2Node = getGNode(op2);
131  SVFVar* dstNode = getGNode(dst);
132  if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Cmp, op2Node))
133  return nullptr;
134  else
135  {
136  std::vector<SVFVar*> opnds = {op1Node, op2Node};
137  CmpStmt* cmp = new CmpStmt(dstNode, opnds, predicate);
138  addToStmt2TypeMap(cmp);
139  addEdge(op1Node, dstNode, cmp);
140  return cmp;
141  }
142 }
143 
144 
149 {
150  SVFVar* op1Node = getGNode(op1);
151  SVFVar* op2Node = getGNode(op2);
152  SVFVar* dstNode = getGNode(dst);
153  if(hasLabeledEdge(op1Node, dstNode, SVFStmt::BinaryOp, op2Node))
154  return nullptr;
155  else
156  {
157  std::vector<SVFVar*> opnds = {op1Node, op2Node};
158  BinaryOPStmt* binaryOP = new BinaryOPStmt(dstNode, opnds, opcode);
159  addToStmt2TypeMap(binaryOP);
160  addEdge(op1Node,dstNode, binaryOP);
161  return binaryOP;
162  }
163 }
164 
169 {
170  SVFVar* srcNode = getGNode(src);
171  SVFVar* dstNode = getGNode(dst);
172  if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::UnaryOp))
173  return nullptr;
174  else
175  {
176  UnaryOPStmt* unaryOP = new UnaryOPStmt(srcNode, dstNode, opcode);
177  addToStmt2TypeMap(unaryOP);
178  addEdge(srcNode,dstNode, unaryOP);
179  return unaryOP;
180  }
181 }
182 
183 /*
184 * Add BranchStmt
185 */
187 {
188  SVFVar* brNode = getGNode(br);
189  SVFVar* condNode = getGNode(cond);
190  if(hasNonlabeledEdge(condNode,brNode, SVFStmt::Branch))
191  return nullptr;
192  else
193  {
194  BranchStmt* branch = new BranchStmt(brNode, condNode, succs);
195  addToStmt2TypeMap(branch);
196  addEdge(condNode,brNode, branch);
197  return branch;
198  }
199 }
200 
205 {
206  SVFVar* srcNode = getGNode(src);
207  SVFVar* dstNode = getGNode(dst);
208  if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Load))
209  return nullptr;
210  else
211  {
212  LoadStmt* loadPE = new LoadStmt(srcNode, dstNode);
213  addToStmt2TypeMap(loadPE);
214  addEdge(srcNode,dstNode, loadPE);
215  return loadPE;
216  }
217 }
218 
224 {
225  SVFVar* srcNode = getGNode(src);
226  SVFVar* dstNode = getGNode(dst);
227  if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Store, curVal))
228  return nullptr;
229  else
230  {
231  StoreStmt* storePE = new StoreStmt(srcNode, dstNode, curVal);
232  addToStmt2TypeMap(storePE);
233  addEdge(srcNode,dstNode, storePE);
234  return storePE;
235  }
236 }
237 
242 {
243  SVFVar* srcNode = getGNode(src);
244  SVFVar* dstNode = getGNode(dst);
245  if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Call, cs))
246  return nullptr;
247  else
248  {
249  CallPE* callPE = new CallPE(srcNode, dstNode, cs,entry);
250  addToStmt2TypeMap(callPE);
251  addEdge(srcNode,dstNode, callPE);
252  return callPE;
253  }
254 }
255 
259 RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit)
260 {
261  SVFVar* srcNode = getGNode(src);
262  SVFVar* dstNode = getGNode(dst);
263  if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Ret, cs))
264  return nullptr;
265  else
266  {
267  RetPE* retPE = new RetPE(srcNode, dstNode, cs, exit);
268  addToStmt2TypeMap(retPE);
269  addEdge(srcNode,dstNode, retPE);
270  return retPE;
271  }
272 }
273 
278 {
280  return pag->addAddrStmt(pag->getBlackHoleNode(), node);
281  else
282  return pag->addCopyStmt(pag->getNullPtr(), node, CopyStmt::COPYVAL);
283 }
284 
289 {
290  SVFVar* srcNode = getGNode(src);
291  SVFVar* dstNode = getGNode(dst);
292  if(hasLabeledEdge(srcNode,dstNode, SVFStmt::ThreadFork, cs))
293  return nullptr;
294  else
295  {
296  TDForkPE* forkPE = new TDForkPE(srcNode, dstNode, cs, entry);
297  addToStmt2TypeMap(forkPE);
298  addEdge(srcNode,dstNode, forkPE);
299  return forkPE;
300  }
301 }
302 
307 {
308  SVFVar* srcNode = getGNode(src);
309  SVFVar* dstNode = getGNode(dst);
310  if(hasLabeledEdge(srcNode,dstNode, SVFStmt::ThreadJoin, cs))
311  return nullptr;
312  else
313  {
314  TDJoinPE* joinPE = new TDJoinPE(srcNode, dstNode, cs, exit);
315  addToStmt2TypeMap(joinPE);
316  addEdge(srcNode,dstNode, joinPE);
317  return joinPE;
318  }
319 }
320 
321 
327 GepStmt* SVFIR::addGepStmt(NodeID src, NodeID dst, const AccessPath& ap, bool constGep)
328 {
329 
330  SVFVar* node = getGNode(src);
331  if (!constGep || node->hasIncomingVariantGepEdge())
332  {
335  return addVariantGepStmt(src, dst, ap);
336  }
337  else
338  {
339  return addNormalGepStmt(src, dst, ap);
340  }
341 }
342 
347 {
348  SVFVar* baseNode = getGNode(src);
349  SVFVar* dstNode = getGNode(dst);
350  if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep))
351  return nullptr;
352  else
353  {
354  GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap);
355  addToStmt2TypeMap(gepPE);
356  addEdge(baseNode, dstNode, gepPE);
357  return gepPE;
358  }
359 }
360 
366 {
367  SVFVar* baseNode = getGNode(src);
368  SVFVar* dstNode = getGNode(dst);
369  if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep))
370  return nullptr;
371  else
372  {
373  GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap, true);
374  addToStmt2TypeMap(gepPE);
375  addEdge(baseNode, dstNode, gepPE);
376  return gepPE;
377  }
378 }
379 
380 
381 
386 NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, const AccessPath& ap, NodeID i, const SVFType* type)
387 {
388  NodeID base = getValueNode(gepVal);
389  //assert(findPAGNode(i) == false && "this node should not be created before");
390  assert(0==GepValObjMap[curInst].count(std::make_pair(base, ap))
391  && "this node should not be created before");
392  GepValObjMap[curInst][std::make_pair(base, ap)] = i;
393  GepValVar *node = new GepValVar(gepVal, i, ap, type);
394  return addValNode(gepVal, node, i);
395 }
396 
401 {
402  SVFVar* node = pag->getGNode(id);
403  if (GepObjVar* gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
404  return getGepObjVar(gepNode->getMemObj(), gepNode->getConstantFieldIdx() + apOffset);
405  else if (FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
406  return getGepObjVar(baseNode->getMemObj(), apOffset);
407  else if (DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
408  return getGepObjVar(baseNode->getMemObj(), apOffset);
409  else
410  {
411  assert(false && "new gep obj node kind?");
412  return id;
413  }
414 }
415 
422 NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset)
423 {
424  NodeID base = obj->getId();
425 
427  if (obj->isFieldInsensitive())
428  return getFIObjVar(obj);
429 
430  APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj, apOffset);
431 
432  // Base and first field are the same memory location.
433  if (Options::FirstFieldEqBase() && newLS == 0) return base;
434 
435  NodeOffsetMap::iterator iter = GepObjVarMap.find(std::make_pair(base, newLS));
436  if (iter == GepObjVarMap.end())
437  {
439  return addGepObjNode(obj, newLS,gepId);
440  }
441  else
442  return iter->second;
443 
444 }
445 
449 NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId)
450 {
451  //assert(findPAGNode(i) == false && "this node should not be created before");
452  NodeID base = obj->getId();
453  assert(0==GepObjVarMap.count(std::make_pair(base, apOffset))
454  && "this node should not be created before");
455 
456  GepObjVarMap[std::make_pair(base, apOffset)] = gepId;
457  GepObjVar *node = new GepObjVar(obj, gepId, apOffset);
458  memToFieldsMap[base].set(gepId);
459  return addObjNode(obj->getValue(), node, gepId);
460 }
461 
466 {
467  //assert(findPAGNode(i) == false && "this node should not be created before");
468  NodeID base = obj->getId();
469  memToFieldsMap[base].set(obj->getId());
470  FIObjVar *node = new FIObjVar(obj->getValue(), obj->getId(), obj);
471  return addObjNode(obj->getValue(), node, obj->getId());
472 }
473 
478 {
479  NodeID base = obj->getId();
480  return memToFieldsMap[base];
481 }
482 
487 {
488  const SVFVar* node = pag->getGNode(id);
489  assert(SVFUtil::isa<ObjVar>(node) && "need an object node");
490  const ObjVar* obj = SVFUtil::cast<ObjVar>(node);
491  return getAllFieldsObjVars(obj->getMemObj());
492 }
493 
500 {
501  const SVFVar* node = pag->getGNode(id);
502  assert(SVFUtil::isa<ObjVar>(node) && "need an object node");
503  const MemObj* mem = SVFUtil::cast<ObjVar>(node)->getMemObj();
504  if(mem->isFieldInsensitive())
505  {
506  NodeBS bs;
507  bs.set(getFIObjVar(mem));
508  return bs;
509  }
510  else
511  return getAllFieldsObjVars(mem);
512 }
513 
517 NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const AccessPath& ap) const
518 {
519  GepValueVarMap::const_iterator iter = GepValObjMap.find(curInst);
520  if(iter==GepValObjMap.end())
521  {
522  return UINT_MAX;
523  }
524  else
525  {
526  NodeAccessPathMap::const_iterator lit =
527  iter->second.find(std::make_pair(base, ap));
528  if (lit == iter->second.end())
529  return UINT_MAX;
530  else
531  return lit->second;
532  }
533 }
534 
535 
540 {
541  delete icfg;
542  icfg = nullptr;
543  delete chgraph;
544  chgraph = nullptr;
546  svfModule = nullptr;
547  delete callGraph;
548  callGraph = nullptr;
549 }
550 
555 {
556 
557  outs() << "-------------------SVFIR------------------------------------\n";
558  SVFStmt::SVFStmtSetTy& addrs = pag->getSVFStmtSet(SVFStmt::Addr);
559  for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
560  addrs.end(); iter != eiter; ++iter)
561  {
562  outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID()
563  << "\n";
564  }
565 
566  SVFStmt::SVFStmtSetTy& copys = pag->getSVFStmtSet(SVFStmt::Copy);
567  for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
568  copys.end(); iter != eiter; ++iter)
569  {
570  outs() << (*iter)->getSrcID() << " -- Copy --> " << (*iter)->getDstID()
571  << "\n";
572  }
573 
574  SVFStmt::SVFStmtSetTy& calls = pag->getSVFStmtSet(SVFStmt::Call);
575  for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
576  calls.end(); iter != eiter; ++iter)
577  {
578  outs() << (*iter)->getSrcID() << " -- Call --> " << (*iter)->getDstID()
579  << "\n";
580  }
581 
582  SVFStmt::SVFStmtSetTy& rets = pag->getSVFStmtSet(SVFStmt::Ret);
583  for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter =
584  rets.end(); iter != eiter; ++iter)
585  {
586  outs() << (*iter)->getSrcID() << " -- Ret --> " << (*iter)->getDstID()
587  << "\n";
588  }
589 
590  SVFStmt::SVFStmtSetTy& tdfks = pag->getSVFStmtSet(SVFStmt::ThreadFork);
591  for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
592  tdfks.end(); iter != eiter; ++iter)
593  {
594  outs() << (*iter)->getSrcID() << " -- ThreadFork --> "
595  << (*iter)->getDstID() << "\n";
596  }
597 
598  SVFStmt::SVFStmtSetTy& tdjns = pag->getSVFStmtSet(SVFStmt::ThreadJoin);
599  for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter =
600  tdjns.end(); iter != eiter; ++iter)
601  {
602  outs() << (*iter)->getSrcID() << " -- ThreadJoin --> "
603  << (*iter)->getDstID() << "\n";
604  }
605 
606  SVFStmt::SVFStmtSetTy& ngeps = pag->getSVFStmtSet(SVFStmt::Gep);
607  for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
608  ngeps.end(); iter != eiter; ++iter)
609  {
610  GepStmt* gep = SVFUtil::cast<GepStmt>(*iter);
611  if(gep->isVariantFieldGep())
612  outs() << (*iter)->getSrcID() << " -- VariantGep --> "
613  << (*iter)->getDstID() << "\n";
614  else
615  outs() << gep->getRHSVarID() << " -- Gep (" << gep->getConstantStructFldIdx()
616  << ") --> " << gep->getLHSVarID() << "\n";
617  }
618 
619  SVFStmt::SVFStmtSetTy& loads = pag->getSVFStmtSet(SVFStmt::Load);
620  for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
621  loads.end(); iter != eiter; ++iter)
622  {
623  outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID()
624  << "\n";
625  }
626 
627  SVFStmt::SVFStmtSetTy& stores = pag->getSVFStmtSet(SVFStmt::Store);
628  for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
629  stores.end(); iter != eiter; ++iter)
630  {
631  outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID()
632  << "\n";
633  }
634  outs() << "----------------------------------------------------------\n";
635 
636 }
637 
640 {
641  // collect candidate pointers for demand-driven analysis
642  for (iterator nIter = begin(); nIter != end(); ++nIter)
643  {
644  NodeID nodeId = nIter->first;
645  // do not compute points-to for isolated node
646  if (isValidPointer(nodeId) == false)
647  continue;
648  candidatePointers.insert(nodeId);
649  }
650 }
651 /*
652  * If this is a dummy node or node does not have incoming edges and outgoing edges we assume it is not a pointer here.
653  * However, if it is a pointer and it is an argument of a function definition, we assume it is a pointer here.
654  */
655 bool SVFIR::isValidPointer(NodeID nodeId) const
656 {
657  SVFVar* node = pag->getGNode(nodeId);
658 
659  if (node->hasValue() && node->isPointer())
660  {
661  if(const SVFArgument* arg = SVFUtil::dyn_cast<SVFArgument>(node->getValue()))
662  {
663  if (!(arg->getParent()->isDeclaration()))
664  return true;
665  }
666  }
667 
668  if ((node->getInEdges().empty() && node->getOutEdges().empty()))
669  return false;
670  return node->isPointer();
671 }
672 
674 {
675  if (SVFUtil::isa<ValVar>(node))
676  {
677  if (isValidPointer(node->getId()) && node->hasValue())
678  {
680  }
681  }
682  return false;
683 }
684 
689 {
691 }
692 
693 
694 
newitem type
Definition: cJSON.cpp:2739
const cJSON *const b
Definition: cJSON.h:255
int count
Definition: cJSON.h:216
void setValue(T v)
Definition: CommandLine.h:351
NodeID getRHSVarID() const
NodeID getLHSVarID() const
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
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.
SVFStmt * hasLabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind, const ICFGNode *cs)
Definition: IRGraph.cpp:88
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
bool addEdge(SVFVar *src, SVFVar *dst, SVFStmt *edge)
Add an edge into the graph.
Definition: IRGraph.cpp:45
SVFStmt * hasNonlabeledEdge(SVFVar *src, SVFVar *dst, SVFStmt::PEDGEK kind)
Definition: IRGraph.cpp:60
const SVFValue * getValue() const
Get the reference value to this object.
SymID getId() const
Get the memory object id.
bool isFieldInsensitive() const
Return true if its field limit is 0.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateGepObjectId(NodeID base, u32_t offset, u32_t maxFieldLimit)
const MemObj * getMemObj() const
Return memory object.
Definition: SVFVariables.h:358
static const Option< bool > FirstFieldEqBase
Definition: Options.h:103
static Option< bool > HandBlackHole
Definition: Options.h:102
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition: Options.h:38
void addOpVar(SVFVar *op, const ICFGNode *inode)
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
NodeID addFIObjNode(const MemObj *obj)
Add a field-insensitive node, this method can only invoked by getFIGepObjNode.
Definition: SVFIR.cpp:465
GepStmt * addVariantGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Variant(Gep) edge.
Definition: SVFIR.cpp:365
NodeOffsetMap GepObjVarMap
Map a pair<base,off> to a gep obj node id.
Definition: SVFIR.h:84
CopyStmt * addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type)
Add Copy edge.
Definition: SVFIR.cpp:64
RetPE * addRetPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
Definition: SVFIR.cpp:259
GepStmt * addGepStmt(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
Definition: SVFIR.cpp:327
NodeID addObjNode(const SVFValue *val, NodeID i)
Add a memory obj node.
Definition: SVFIR.h:553
void print()
Print SVFIR.
Definition: SVFIR.cpp:554
static void handleBlackHole(bool b)
SVFIR build configurations.
Definition: SVFIR.cpp:688
NodeID getFIObjVar(const MemObj *obj) const
Get a field-insensitive obj SVFIR node according to a mem obj.
Definition: SVFIR.h:415
void addToStmt2TypeMap(SVFStmt *edge)
Map a SVFStatement type to a set of corresponding SVF statements.
Definition: SVFIR.h:495
CommonCHGraph * chgraph
Definition: SVFIR.h:99
SVFStmt * addBlackHoleAddrStmt(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr)
Definition: SVFIR.cpp:277
LoadStmt * addLoadStmt(NodeID src, NodeID dst)
Add Load edge.
Definition: SVFIR.cpp:204
GepStmt * addNormalGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Offset(Gep) edge.
Definition: SVFIR.cpp:346
MemObjToFieldsMap memToFieldsMap
Map a mem object id to all its fields.
Definition: SVFIR.h:85
PHINodeMap phiNodeMap
A set of phi copy edges.
Definition: SVFIR.h:87
NodeBS getFieldsAfterCollapse(NodeID id)
Definition: SVFIR.cpp:499
NodeID addGepValNode(const SVFValue *curInst, const SVFValue *val, const AccessPath &ap, NodeID i, const SVFType *type)
Add a temp field value node, this method can only invoked by getGepValVar.
Definition: SVFIR.cpp:386
CallPE * addCallPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
Definition: SVFIR.cpp:241
bool isValidTopLevelPtr(const SVFVar *node)
Definition: SVFIR.cpp:673
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Thread join edge for parameter passing.
Definition: SVFIR.cpp:306
void destroy()
Clean up memory.
Definition: SVFIR.cpp:539
NodeID addGepObjNode(const MemObj *obj, const APOffset &apOffset, const NodeID gepId)
Add a field obj node, this method can only invoked by getGepObjVar.
Definition: SVFIR.cpp:449
NodeBS & getAllFieldsObjVars(const MemObj *obj)
Get all fields of an object.
Definition: SVFIR.cpp:477
CmpStmt * addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
Definition: SVFIR.cpp:127
AddrStmt * addAddrStmt(NodeID src, NodeID dst)
Add an edge into SVFIR.
Definition: SVFIR.cpp:46
UnaryOPStmt * addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
Definition: SVFIR.cpp:168
SVFModule * svfModule
Definition: SVFIR.h:97
TDForkPE * addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
Definition: SVFIR.cpp:288
BinaryOPStmt * addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
Definition: SVFIR.cpp:148
NodeID addValNode(const SVFValue *val, NodeID i, const SVFBaseNode *gNode)
add node into SVFIR
Definition: SVFIR.h:547
static std::unique_ptr< SVFIR > pag
call graph
Definition: SVFIR.h:103
StoreStmt * addStoreStmt(NodeID src, NodeID dst, const ICFGNode *val)
Add Store edge.
Definition: SVFIR.cpp:223
PhiStmt * addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add phi node information.
Definition: SVFIR.cpp:82
OrderedNodeSet candidatePointers
Definition: SVFIR.h:96
ICFG * icfg
SVF Module.
Definition: SVFIR.h:98
SVFIR(bool buildFromFile)
Constructor.
Definition: SVFIR.cpp:39
SelectStmt * addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
Definition: SVFIR.cpp:106
PTACallGraph * callGraph
all the callsites of a program
Definition: SVFIR.h:101
NodeID getGepValVar(const SVFValue *curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
Definition: SVFIR.cpp:517
GepValueVarMap GepValObjMap
Map a pair<base,off> to a gep value node id.
Definition: SVFIR.h:82
bool isValidPointer(NodeID nodeId) const
Whether a node is a valid pointer.
Definition: SVFIR.cpp:655
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
Definition: SVFIR.cpp:422
BranchStmt * addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add BranchStmt.
Definition: SVFIR.cpp:186
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition: SVFIR.cpp:639
static void releaseSVFModule()
Definition: SVFModule.cpp:69
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
bool hasValue() const
Definition: SVFVariables.h:101
virtual bool isPointer() const
Whether it is a pointer.
Definition: SVFVariables.h:106
bool hasIncomingVariantGepEdge() const
Has incoming VariantGepEdges.
Definition: SVFVariables.h:230
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
void set(unsigned Idx)
bool isArgOfUncalledFunction(const SVFValue *svfval)
Return true if this argument belongs to an uncalled function.
Definition: SVFUtil.h:346
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
s64_t APOffset
Definition: GeneralType.h:60
unsigned u32_t
Definition: GeneralType.h:46