Static Value-Flow Analysis
ConsG.cpp
Go to the documentation of this file.
1 //===- ConsG.cpp -- Constraint graph representation-----------------------------//
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  * ConstraintGraph.cpp
25  *
26  * Created on: Oct 14, 2013
27  * Author: Yulei Sui
28  */
29 
30 #include "Graphs/ConsG.h"
31 #include "Util/Options.h"
32 
33 using namespace SVF;
34 using namespace SVFUtil;
35 
36 
41 {
42 
43  // initialize nodes
44  for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; ++it)
45  {
46  addConstraintNode(new ConstraintNode(it->first), it->first);
47  }
48 
49  // initialize edges
50  SVFStmt::SVFStmtSetTy& addrs = getPAGEdgeSet(SVFStmt::Addr);
51  for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
52  addrs.end(); iter != eiter; ++iter)
53  {
54  const AddrStmt* edge = SVFUtil::cast<AddrStmt>(*iter);
55  addAddrCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
56  }
57 
58  SVFStmt::SVFStmtSetTy& copys = getPAGEdgeSet(SVFStmt::Copy);
59  for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
60  copys.end(); iter != eiter; ++iter)
61  {
62  const CopyStmt* edge = SVFUtil::cast<CopyStmt>(*iter);
63  if(edge->isBitCast() || edge->isValueCopy())
64  addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
65  }
66 
67  SVFStmt::SVFStmtSetTy& phis = getPAGEdgeSet(SVFStmt::Phi);
68  for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter =
69  phis.end(); iter != eiter; ++iter)
70  {
71  const PhiStmt* edge = SVFUtil::cast<PhiStmt>(*iter);
72  for(const auto opVar : edge->getOpndVars())
73  addCopyCGEdge(opVar->getId(),edge->getResID());
74  }
75 
76  SVFStmt::SVFStmtSetTy& selects = getPAGEdgeSet(SVFStmt::Select);
77  for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
78  selects.end(); iter != eiter; ++iter)
79  {
80  const SelectStmt* edge = SVFUtil::cast<SelectStmt>(*iter);
81  for(const auto opVar : edge->getOpndVars())
82  addCopyCGEdge(opVar->getId(),edge->getResID());
83  }
84 
85  SVFStmt::SVFStmtSetTy& calls = getPAGEdgeSet(SVFStmt::Call);
86  for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter =
87  calls.end(); iter != eiter; ++iter)
88  {
89  const CallPE* edge = SVFUtil::cast<CallPE>(*iter);
90  addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
91  }
92 
93  SVFStmt::SVFStmtSetTy& rets = getPAGEdgeSet(SVFStmt::Ret);
94  for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter =
95  rets.end(); iter != eiter; ++iter)
96  {
97  const RetPE* edge = SVFUtil::cast<RetPE>(*iter);
98  addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
99  }
100 
101  SVFStmt::SVFStmtSetTy& tdfks = getPAGEdgeSet(SVFStmt::ThreadFork);
102  for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter =
103  tdfks.end(); iter != eiter; ++iter)
104  {
105  const TDForkPE* edge = SVFUtil::cast<TDForkPE>(*iter);
106  addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
107  }
108 
109  SVFStmt::SVFStmtSetTy& tdjns = getPAGEdgeSet(SVFStmt::ThreadJoin);
110  for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter =
111  tdjns.end(); iter != eiter; ++iter)
112  {
113  const TDJoinPE* edge = SVFUtil::cast<TDJoinPE>(*iter);
114  addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
115  }
116 
117  SVFStmt::SVFStmtSetTy& ngeps = getPAGEdgeSet(SVFStmt::Gep);
118  for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
119  ngeps.end(); iter != eiter; ++iter)
120  {
121  GepStmt* edge = SVFUtil::cast<GepStmt>(*iter);
122  if(edge->isVariantFieldGep())
123  addVariantGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
124  else
125  addNormalGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID(),edge->getAccessPath());
126  }
127 
128  SVFStmt::SVFStmtSetTy& loads = getPAGEdgeSet(SVFStmt::Load);
129  for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
130  loads.end(); iter != eiter; ++iter)
131  {
132  LoadStmt* edge = SVFUtil::cast<LoadStmt>(*iter);
133  addLoadCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
134  }
135 
136  SVFStmt::SVFStmtSetTy& stores = getPAGEdgeSet(SVFStmt::Store);
137  for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
138  stores.end(); iter != eiter; ++iter)
139  {
140  StoreStmt* edge = SVFUtil::cast<StoreStmt>(*iter);
141  addStoreCGEdge(edge->getRHSVarID(),edge->getLHSVarID());
142  }
143 
144  clearSolitaries();
145 }
146 
151 {
153  NodeSet retFromIndCalls;
154  for(auto cs_pair : pag->getIndirectCallsites())
155  {
156  const RetICFGNode* retBlockNode = cs_pair.first->getRetICFGNode();
157  if(pag->callsiteHasRet(retBlockNode))
158  retFromIndCalls.insert(pag->getCallSiteRet(retBlockNode)->getId());
159  }
160 
161  Set<ConstraintNode*> nodesToRemove;
162  for (auto it = this->begin(); it != this->end(); ++it)
163  {
164  if (it->second->hasIncomingEdge() || it->second->hasOutgoingEdge())
165  continue;
166  if (pag->getGNode(it->first)->isPointer())
167  continue;
168  if (retFromIndCalls.find(it->first)!=retFromIndCalls.end())
169  continue;
170  nodesToRemove.insert(it->second);
171  }
172 
173  for (auto node : nodesToRemove)
174  removeConstraintNode(node);
175 }
176 
181 {
182 }
183 
188  : ConstraintEdge(s,d,Addr,id)
189 {
190  // Retarget addr edges may lead s to be a dummy node
191  PAGNode* node = SVFIR::getPAG()->getGNode(s->getId());
192  (void)node; // Suppress warning of unused variable under release build
194  {
195  assert(!SVFUtil::isa<DummyValVar>(node) && "a dummy node??");
196  }
197 }
198 
203 {
204  ConstraintNode* srcNode = getConstraintNode(src);
205  ConstraintNode* dstNode = getConstraintNode(dst);
206  if (hasEdge(srcNode, dstNode, ConstraintEdge::Addr))
207  return nullptr;
208  AddrCGEdge* edge = new AddrCGEdge(srcNode, dstNode, edgeIndex++);
209 
210  bool inserted = AddrCGEdgeSet.insert(edge).second;
211  (void)inserted; // Suppress warning of unused variable under release build
212  assert(inserted && "new AddrCGEdge not added??");
213 
214  srcNode->addOutgoingAddrEdge(edge);
215  dstNode->addIncomingAddrEdge(edge);
216  return edge;
217 }
218 
223 {
224 
225  ConstraintNode* srcNode = getConstraintNode(src);
226  ConstraintNode* dstNode = getConstraintNode(dst);
227  if (hasEdge(srcNode, dstNode, ConstraintEdge::Copy) || srcNode == dstNode)
228  return nullptr;
229 
230  CopyCGEdge* edge = new CopyCGEdge(srcNode, dstNode, edgeIndex++);
231 
232  bool inserted = directEdgeSet.insert(edge).second;
233  (void)inserted; // Suppress warning of unused variable under release build
234  assert(inserted && "new CopyCGEdge not added??");
235 
236  srcNode->addOutgoingCopyEdge(edge);
237  dstNode->addIncomingCopyEdge(edge);
238  return edge;
239 }
240 
241 
246 {
247  ConstraintNode* srcNode = getConstraintNode(src);
248  ConstraintNode* dstNode = getConstraintNode(dst);
249  if (hasEdge(srcNode, dstNode, ConstraintEdge::NormalGep))
250  return nullptr;
251 
252  NormalGepCGEdge* edge =
253  new NormalGepCGEdge(srcNode, dstNode, ap, edgeIndex++);
254 
255  bool inserted = directEdgeSet.insert(edge).second;
256  (void)inserted; // Suppress warning of unused variable under release build
257  assert(inserted && "new NormalGepCGEdge not added??");
258 
259  srcNode->addOutgoingGepEdge(edge);
260  dstNode->addIncomingGepEdge(edge);
261  return edge;
262 }
263 
268 {
269  ConstraintNode* srcNode = getConstraintNode(src);
270  ConstraintNode* dstNode = getConstraintNode(dst);
271  if (hasEdge(srcNode, dstNode, ConstraintEdge::VariantGep))
272  return nullptr;
273 
274  VariantGepCGEdge* edge = new VariantGepCGEdge(srcNode, dstNode, edgeIndex++);
275 
276  bool inserted = directEdgeSet.insert(edge).second;
277  (void)inserted; // Suppress warning of unused variable under release build
278  assert(inserted && "new VariantGepCGEdge not added??");
279 
280  srcNode->addOutgoingGepEdge(edge);
281  dstNode->addIncomingGepEdge(edge);
282  return edge;
283 }
284 
289 {
290  ConstraintNode* srcNode = getConstraintNode(src);
291  ConstraintNode* dstNode = getConstraintNode(dst);
292  if (hasEdge(srcNode, dstNode, ConstraintEdge::Load))
293  return nullptr;
294 
295  LoadCGEdge* edge = new LoadCGEdge(srcNode, dstNode, edgeIndex++);
296 
297  bool inserted = LoadCGEdgeSet.insert(edge).second;
298  (void)inserted; // Suppress warning of unused variable under release build
299  assert(inserted && "new LoadCGEdge not added??");
300 
301  srcNode->addOutgoingLoadEdge(edge);
302  dstNode->addIncomingLoadEdge(edge);
303  return edge;
304 }
305 
310 {
311  ConstraintNode* srcNode = getConstraintNode(src);
312  ConstraintNode* dstNode = getConstraintNode(dst);
313  if (hasEdge(srcNode, dstNode, ConstraintEdge::Store))
314  return nullptr;
315 
316  StoreCGEdge* edge = new StoreCGEdge(srcNode, dstNode, edgeIndex++);
317 
318  bool inserted = StoreCGEdgeSet.insert(edge).second;
319  (void)inserted; // Suppress warning of unused variable under release build
320  assert(inserted && "new StoreCGEdge not added??");
321 
322  srcNode->addOutgoingStoreEdge(edge);
323  dstNode->addIncomingStoreEdge(edge);
324  return edge;
325 }
326 
327 
336 {
337  NodeID newDstNodeID = newDstNode->getId();
338  NodeID srcId = edge->getSrcID();
339  if(LoadCGEdge* load = SVFUtil::dyn_cast<LoadCGEdge>(edge))
340  {
341  removeLoadEdge(load);
342  addLoadCGEdge(srcId,newDstNodeID);
343  }
344  else if(StoreCGEdge* store = SVFUtil::dyn_cast<StoreCGEdge>(edge))
345  {
346  removeStoreEdge(store);
347  addStoreCGEdge(srcId,newDstNodeID);
348  }
349  else if(CopyCGEdge* copy = SVFUtil::dyn_cast<CopyCGEdge>(edge))
350  {
352  addCopyCGEdge(srcId,newDstNodeID);
353  }
354  else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
355  {
356  const AccessPath ap = gep->getAccessPath();
357  removeDirectEdge(gep);
358  addNormalGepCGEdge(srcId,newDstNodeID, ap);
359  }
360  else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast<VariantGepCGEdge>(edge))
361  {
362  removeDirectEdge(gep);
363  addVariantGepCGEdge(srcId,newDstNodeID);
364  }
365  else if(AddrCGEdge* addr = SVFUtil::dyn_cast<AddrCGEdge>(edge))
366  {
367  removeAddrEdge(addr);
368  }
369  else
370  assert(false && "no other edge type!!");
371 }
372 
380 {
381  NodeID newSrcNodeID = newSrcNode->getId();
382  NodeID dstId = edge->getDstID();
383  if(LoadCGEdge* load = SVFUtil::dyn_cast<LoadCGEdge>(edge))
384  {
385  removeLoadEdge(load);
386  addLoadCGEdge(newSrcNodeID,dstId);
387  }
388  else if(StoreCGEdge* store = SVFUtil::dyn_cast<StoreCGEdge>(edge))
389  {
390  removeStoreEdge(store);
391  addStoreCGEdge(newSrcNodeID,dstId);
392  }
393  else if(CopyCGEdge* copy = SVFUtil::dyn_cast<CopyCGEdge>(edge))
394  {
396  addCopyCGEdge(newSrcNodeID,dstId);
397  }
398  else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
399  {
400  const AccessPath ap = gep->getAccessPath();
401  removeDirectEdge(gep);
402  addNormalGepCGEdge(newSrcNodeID, dstId, ap);
403  }
404  else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast<VariantGepCGEdge>(edge))
405  {
406  removeDirectEdge(gep);
407  addVariantGepCGEdge(newSrcNodeID,dstId);
408  }
409  else if(AddrCGEdge* addr = SVFUtil::dyn_cast<AddrCGEdge>(edge))
410  {
411  removeAddrEdge(addr);
412  }
413  else
414  assert(false && "no other edge type!!");
415 }
416 
421 {
424  u32_t num = AddrCGEdgeSet.erase(edge);
425  (void)num; // Suppress warning of unused variable under release build
426  assert(num && "edge not in the set, can not remove!!!");
427  delete edge;
428 }
429 
434 {
437  u32_t num = LoadCGEdgeSet.erase(edge);
438  (void)num; // Suppress warning of unused variable under release build
439  assert(num && "edge not in the set, can not remove!!!");
440  delete edge;
441 }
442 
447 {
450  u32_t num = StoreCGEdgeSet.erase(edge);
451  (void)num; // Suppress warning of unused variable under release build
452  assert(num && "edge not in the set, can not remove!!!");
453  delete edge;
454 }
455 
460 {
461 
464  u32_t num = directEdgeSet.erase(edge);
465  (void)num; // Suppress warning of unused variable under release build
466  assert(num && "edge not in the set, can not remove!!!");
467  delete edge;
468 }
469 
475 {
476  std::vector<ConstraintEdge*> sccEdges;
477  std::vector<ConstraintEdge*> nonSccEdges;
478  for (ConstraintNode::const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit;
479  ++it)
480  {
481  ConstraintEdge* subInEdge = *it;
482  if(sccRepNode(subInEdge->getSrcID()) != rep->getId())
483  nonSccEdges.push_back(subInEdge);
484  else
485  {
486  sccEdges.push_back(subInEdge);
487  }
488  }
489  // if this edge is outside scc, then re-target edge dst to rep
490  while(!nonSccEdges.empty())
491  {
492  ConstraintEdge* edge = nonSccEdges.back();
493  nonSccEdges.pop_back();
494  reTargetDstOfEdge(edge,rep);
495  }
496 
497  bool criticalGepInsideSCC = false;
498  // if this edge is inside scc, then remove this edge and two end nodes
499  while(!sccEdges.empty())
500  {
501  ConstraintEdge* edge = sccEdges.back();
502  sccEdges.pop_back();
504  if(SVFUtil::isa<CopyCGEdge>(edge))
505  removeDirectEdge(edge);
506  else if (SVFUtil::isa<GepCGEdge>(edge))
507  {
508  // If the GEP is critical (i.e. may have a non-zero offset),
509  // then it brings impact on field-sensitivity.
510  if (!isZeroOffsettedGepCGEdge(edge))
511  {
512  criticalGepInsideSCC = true;
513  }
514  removeDirectEdge(edge);
515  }
516  else if(SVFUtil::isa<LoadCGEdge, StoreCGEdge>(edge))
517  reTargetDstOfEdge(edge,rep);
518  else if(AddrCGEdge* addr = SVFUtil::dyn_cast<AddrCGEdge>(edge))
519  {
520  removeAddrEdge(addr);
521  }
522  else
523  assert(false && "no such edge");
524  }
525  return criticalGepInsideSCC;
526 }
527 
533 {
534 
535  std::vector<ConstraintEdge*> sccEdges;
536  std::vector<ConstraintEdge*> nonSccEdges;
537 
538  for (ConstraintNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it != eit;
539  ++it)
540  {
541  ConstraintEdge* subOutEdge = *it;
542  if(sccRepNode(subOutEdge->getDstID()) != rep->getId())
543  nonSccEdges.push_back(subOutEdge);
544  else
545  {
546  sccEdges.push_back(subOutEdge);
547  }
548  }
549  // if this edge is outside scc, then re-target edge src to rep
550  while(!nonSccEdges.empty())
551  {
552  ConstraintEdge* edge = nonSccEdges.back();
553  nonSccEdges.pop_back();
554  reTargetSrcOfEdge(edge,rep);
555  }
556  bool criticalGepInsideSCC = false;
557  // if this edge is inside scc, then remove this edge and two end nodes
558  while(!sccEdges.empty())
559  {
560  ConstraintEdge* edge = sccEdges.back();
561  sccEdges.pop_back();
563  if(SVFUtil::isa<CopyCGEdge>(edge))
564  removeDirectEdge(edge);
565  else if (SVFUtil::isa<GepCGEdge>(edge))
566  {
567  // If the GEP is critical (i.e. may have a non-zero offset),
568  // then it brings impact on field-sensitivity.
569  if (!isZeroOffsettedGepCGEdge(edge))
570  {
571  criticalGepInsideSCC = true;
572  }
573  removeDirectEdge(edge);
574  }
575  else if(SVFUtil::isa<LoadCGEdge, StoreCGEdge>(edge))
576  reTargetSrcOfEdge(edge,rep);
577  else if(AddrCGEdge* addr = SVFUtil::dyn_cast<AddrCGEdge>(edge))
578  {
579  removeAddrEdge(addr);
580  }
581  else
582  assert(false && "no such edge");
583  }
584  return criticalGepInsideSCC;
585 }
586 
587 
592 {
594 }
595 
600 {
601 
602  outs() << "-----------------ConstraintGraph--------------------------------------\n";
603 
605  for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = addrs.begin(),
606  eiter = addrs.end(); iter != eiter; ++iter)
607  {
608  outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID()
609  << "\n";
610  }
611 
613  for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = directs.begin(),
614  eiter = directs.end(); iter != eiter; ++iter)
615  {
616  if (CopyCGEdge* copy = SVFUtil::dyn_cast<CopyCGEdge>(*iter))
617  {
618  outs() << copy->getSrcID() << " -- Copy --> " << copy->getDstID()
619  << "\n";
620  }
621  else if (NormalGepCGEdge* ngep = SVFUtil::dyn_cast<NormalGepCGEdge>(*iter))
622  {
623  outs() << ngep->getSrcID() << " -- NormalGep (" << ngep->getConstantFieldIdx()
624  << ") --> " << ngep->getDstID() << "\n";
625  }
626  else if (VariantGepCGEdge* vgep = SVFUtil::dyn_cast<VariantGepCGEdge>(*iter))
627  {
628  outs() << vgep->getSrcID() << " -- VarintGep --> "
629  << vgep->getDstID() << "\n";
630  }
631  else
632  assert(false && "wrong constraint edge kind!");
633  }
634 
636  for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = loads.begin(),
637  eiter = loads.end(); iter != eiter; ++iter)
638  {
639  outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID()
640  << "\n";
641  }
642 
644  for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = stores.begin(),
645  eiter = stores.end(); iter != eiter; ++iter)
646  {
647  outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID()
648  << "\n";
649  }
650 
651  outs()
652  << "--------------------------------------------------------------\n";
653 
654 }
655 
660 {
661  SVF::ViewGraph(this, "Constraint Graph");
662 }
663 
665 
667 {
668  if (Options::DetectPWC())
669  return directOutEdges.begin();
670  else
671  return copyOutEdges.begin();
672 }
673 
675 {
676  if (Options::DetectPWC())
677  return directOutEdges.end();
678  else
679  return copyOutEdges.end();
680 }
681 
683 {
684  if (Options::DetectPWC())
685  return directInEdges.begin();
686  else
687  return copyInEdges.begin();
688 }
689 
691 {
692  if (Options::DetectPWC())
693  return directInEdges.end();
694  else
695  return copyInEdges.end();
696 }
697 
699 {
700  if (Options::DetectPWC())
701  return directOutEdges.begin();
702  else
703  return copyOutEdges.begin();
704 }
705 
707 {
708  if (Options::DetectPWC())
709  return directOutEdges.end();
710  else
711  return copyOutEdges.end();
712 }
713 
715 {
716  if (Options::DetectPWC())
717  return directInEdges.begin();
718  else
719  return copyInEdges.begin();
720 }
721 
723 {
724  if (Options::DetectPWC())
725  return directInEdges.end();
726  else
727  return copyInEdges.end();
728 }
730 
732 {
733  return SVFIR::getPAG()->getGNode(getId())->toString();
734 }
735 
739 namespace SVF
740 {
741 template<>
743 {
744 
746  DOTGraphTraits(bool isSimple = false) :
747  DOTGraphTraits<SVFIR*>(isSimple)
748  {
749  }
750 
753  {
754  return "ConstraintG";
755  }
756 
758  {
759  if (Options::ShowHiddenNode()) return false;
760  else return (n->getInEdges().empty() && n->getOutEdges().empty());
761  }
762 
766  {
767  PAGNode* node = SVFIR::getPAG()->getGNode(n->getId());
768  bool briefDisplay = Options::BriefConsCGDotGraph();
769  bool nameDisplay = true;
770  std::string str;
771  std::stringstream rawstr(str);
772 
773  if (briefDisplay)
774  {
775  if (SVFUtil::isa<ValVar>(node))
776  {
777  if (nameDisplay)
778  rawstr << node->getId() << ":" << node->getValueName();
779  else
780  rawstr << node->getId();
781  }
782  else
783  rawstr << node->getId();
784  }
785  else
786  {
787  // print the whole value
788  if (!SVFUtil::isa<DummyValVar>(node) && !SVFUtil::isa<DummyObjVar>(node))
789  rawstr << node->getId() << ":" << node->getValue()->toString();
790  else
791  rawstr << node->getId() << ":";
792 
793  }
794 
795  return rawstr.str();
796  }
797 
799  {
800  PAGNode* node = SVFIR::getPAG()->getGNode(n->getId());
801  if (SVFUtil::isa<ValVar>(node))
802  {
803  if(SVFUtil::isa<GepValVar>(node))
804  return "shape=hexagon";
805  else if (SVFUtil::isa<DummyValVar>(node))
806  return "shape=diamond";
807  else
808  return "shape=box";
809  }
810  else if (SVFUtil::isa<ObjVar>(node))
811  {
812  if(SVFUtil::isa<GepObjVar>(node))
813  return "shape=doubleoctagon";
814  else if(SVFUtil::isa<FIObjVar>(node))
815  return "shape=box3d";
816  else if (SVFUtil::isa<DummyObjVar>(node))
817  return "shape=tab";
818  else
819  return "shape=component";
820  }
821  else if (SVFUtil::isa<RetPN>(node))
822  {
823  return "shape=Mrecord";
824  }
825  else if (SVFUtil::isa<VarArgPN>(node))
826  {
827  return "shape=octagon";
828  }
829  else
830  {
831  assert(0 && "no such kind!!");
832  }
833  return "";
834  }
835 
836  template<class EdgeIter>
838  {
839  ConstraintEdge* edge = *(EI.getCurrent());
840  assert(edge && "No edge found!!");
841  if (edge->getEdgeKind() == ConstraintEdge::Addr)
842  {
843  return "color=green";
844  }
845  else if (edge->getEdgeKind() == ConstraintEdge::Copy)
846  {
847  return "color=black";
848  }
849  else if (edge->getEdgeKind() == ConstraintEdge::NormalGep
851  {
852  return "color=purple";
853  }
854  else if (edge->getEdgeKind() == ConstraintEdge::Store)
855  {
856  return "color=blue";
857  }
858  else if (edge->getEdgeKind() == ConstraintEdge::Load)
859  {
860  return "color=red";
861  }
862  else
863  {
864  assert(0 && "No such kind edge!!");
865  }
866  return "";
867  }
868 
869  template<class EdgeIter>
871  {
872  return "";
873  }
874 };
875 } // End namespace llvm
copy vgep
Definition: PAGGrammar.txt:9
copy
Definition: cJSON.cpp:414
cJSON * n
Definition: cJSON.cpp:2558
const char *const name
Definition: cJSON.h:264
const char *const string
Definition: cJSON.h:172
AddrCGEdge()
place holder
NodeID getRHSVarID() const
NodeID getLHSVarID() const
GenericNode< ConstraintNode, ConstraintEdge >::GEdgeSetTy ConstraintEdgeSetTy
Constraint edge type.
Definition: ConsGEdge.h:85
bool moveInEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition: ConsG.cpp:474
ConstraintEdge::ConstraintEdgeSetTy StoreCGEdgeSet
Definition: ConsG.h:64
ConstraintEdge::ConstraintEdgeSetTy directEdgeSet
Definition: ConsG.h:62
ConstraintEdge::ConstraintEdgeSetTy LoadCGEdgeSet
Definition: ConsG.h:63
LoadCGEdge * addLoadCGEdge(NodeID src, NodeID dst)
Add Load edge.
Definition: ConsG.cpp:288
ConstraintNode * getConstraintNode(NodeID id) const
Get/add/remove constraint node.
Definition: ConsG.h:109
void view()
View graph from the debugger.
Definition: ConsG.cpp:659
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition: ConsG.h:235
void reTargetDstOfEdge(ConstraintEdge *edge, ConstraintNode *newDstNode)
Used for cycle elimination.
Definition: ConsG.cpp:335
AddrCGEdge * addAddrCGEdge(NodeID src, NodeID dst)
Add a SVFIR edge into Edge map.
Definition: ConsG.cpp:202
ConstraintEdge::ConstraintEdgeSetTy AddrCGEdgeSet
Definition: ConsG.h:61
bool hasEdge(ConstraintNode *src, ConstraintNode *dst, ConstraintEdge::ConstraintEdgeK kind)
Definition: ConsG.h:130
CopyCGEdge * addCopyCGEdge(NodeID src, NodeID dst)
Add Copy edge.
Definition: ConsG.cpp:222
ConstraintEdge::ConstraintEdgeSetTy & getStoreCGEdges()
Get Store edges.
Definition: ConsG.h:211
StoreCGEdge * addStoreCGEdge(NodeID src, NodeID dst)
Add Store edge.
Definition: ConsG.cpp:309
void clearSolitaries()
Definition: ConsG.cpp:150
VariantGepCGEdge * addVariantGepCGEdge(NodeID src, NodeID dst)
Definition: ConsG.cpp:267
void removeDirectEdge(ConstraintEdge *edge)
Remove direct edge from their src and dst edge sets.
Definition: ConsG.cpp:459
bool moveOutEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition: ConsG.cpp:532
void removeLoadEdge(LoadCGEdge *edge)
Remove load edge from their src and dst edge sets.
Definition: ConsG.cpp:433
void print()
Print CG into terminal.
Definition: ConsG.cpp:599
void reTargetSrcOfEdge(ConstraintEdge *edge, ConstraintNode *newSrcNode)
Remove edge from old src target, change edge dst id and add modified edge into new src.
Definition: ConsG.cpp:379
void removeStoreEdge(StoreCGEdge *edge)
Remove store edge from their src and dst edge sets.
Definition: ConsG.cpp:446
NormalGepCGEdge * addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath &ap)
Add Gep edge.
Definition: ConsG.cpp:245
EdgeID edgeIndex
Definition: ConsG.h:59
void removeAddrEdge(AddrCGEdge *edge)
Remove addr edge from their src and dst edge sets.
Definition: ConsG.cpp:420
ConstraintEdge::ConstraintEdgeSetTy & getDirectCGEdges()
Get Copy/call/ret/gep edges.
Definition: ConsG.h:201
ConstraintEdge::ConstraintEdgeSetTy & getAddrCGEdges()
Get SVFIR edge.
Definition: ConsG.h:196
bool isZeroOffsettedGepCGEdge(ConstraintEdge *edge) const
Check if a given edge is a NormalGepCGEdge with 0 offset.
Definition: ConsG.h:294
void dump(std::string name)
Dump graph into dot file.
Definition: ConsG.cpp:591
ConstraintEdge::ConstraintEdgeSetTy & getLoadCGEdges()
Get Load edges.
Definition: ConsG.h:206
ConstraintEdge::ConstraintEdgeSetTy copyOutEdges
Definition: ConsGNode.h:61
bool addOutgoingStoreEdge(StoreCGEdge *outEdge)
Definition: ConsGNode.h:284
ConstraintEdge::ConstraintEdgeSetTy::iterator iterator
Definition: ConsGNode.h:44
iterator directInEdgeEnd()
Definition: ConsG.cpp:690
void addIncomingStoreEdge(StoreCGEdge *inEdge)
Definition: ConsGNode.h:257
void addOutgoingCopyEdge(CopyCGEdge *outEdge)
Definition: ConsGNode.h:237
bool removeOutgoingStoreEdge(StoreCGEdge *outEdge)
Definition: ConsGNode.h:367
bool removeIncomingStoreEdge(StoreCGEdge *inEdge)
Definition: ConsGNode.h:376
ConstraintEdge::ConstraintEdgeSetTy copyInEdges
Definition: ConsGNode.h:60
ConstraintEdge::ConstraintEdgeSetTy directInEdges
Definition: ConsGNode.h:57
bool removeIncomingAddrEdge(AddrCGEdge *inEdge)
Definition: ConsGNode.h:314
virtual const std::string toString() const
Definition: ConsG.cpp:731
bool removeOutgoingDirectEdge(ConstraintEdge *outEdge)
Definition: ConsGNode.h:323
bool removeIncomingDirectEdge(ConstraintEdge *inEdge)
Definition: ConsGNode.h:336
bool removeOutgoingLoadEdge(LoadCGEdge *outEdge)
Definition: ConsGNode.h:349
iterator directInEdgeBegin()
Definition: ConsG.cpp:682
void addIncomingLoadEdge(LoadCGEdge *inEdge)
Definition: ConsGNode.h:252
bool removeIncomingLoadEdge(LoadCGEdge *inEdge)
Definition: ConsGNode.h:358
iterator directOutEdgeEnd()
Definition: ConsG.cpp:674
bool addOutgoingLoadEdge(LoadCGEdge *outEdge)
Definition: ConsGNode.h:276
void addIncomingGepEdge(GepCGEdge *inEdge)
Definition: ConsGNode.h:232
ConstraintEdge::ConstraintEdgeSetTy::const_iterator const_iterator
Definition: ConsGNode.h:45
bool removeOutgoingAddrEdge(AddrCGEdge *outEdge)
Remove constraint graph edges.
Definition: ConsGNode.h:305
void addOutgoingGepEdge(GepCGEdge *outEdge)
Definition: ConsGNode.h:242
void addIncomingCopyEdge(CopyCGEdge *inEdge)
Add constraint graph edges.
Definition: ConsGNode.h:227
iterator directOutEdgeBegin()
Iterators.
Definition: ConsG.cpp:666
void addIncomingAddrEdge(AddrCGEdge *inEdge)
Definition: ConsGNode.h:247
void addOutgoingAddrEdge(AddrCGEdge *outEdge)
Definition: ConsGNode.h:271
ConstraintEdge::ConstraintEdgeSetTy directOutEdges
Definition: ConsGNode.h:58
bool isBitCast() const
bool isValueCopy() const
GEdgeKind getEdgeKind() const
Definition: GenericGraph.h:89
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
iterator OutEdgeEnd()
Definition: GenericGraph.h:458
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:454
iterator InEdgeBegin()
Definition: GenericGraph.h:462
iterator InEdgeEnd()
Definition: GenericGraph.h:466
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
const AccessPath & getAccessPath() const
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56
const OPVars & getOpndVars() const
NodeID getResID() const
static const Option< bool > BriefConsCGDotGraph
Definition: Options.h:209
static Option< bool > DetectPWC
Definition: Options.h:216
static const Option< bool > ShowHiddenNode
Definition: Options.h:228
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
static bool pagReadFromTXT()
Definition: SVFModule.h:98
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
std::string toString() const
Needs to be implemented by a SVF front end.
Definition: LLVMUtil.cpp:663
virtual const std::string getValueName() const =0
Get name of the LLVM value.
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
Set< NodeID > NodeSet
Definition: GeneralType.h:113
u32_t NodeID
Definition: GeneralType.h:55
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
Definition: GraphWriter.h:371
unsigned u32_t
Definition: GeneralType.h:46
u32_t EdgeID
Definition: GeneralType.h:56
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96
static std::string getNodeAttributes(NodeType *n, ConstraintGraph *)
Definition: ConsG.cpp:798
static std::string getEdgeSourceLabel(NodeType *, EdgeIter)
Definition: ConsG.cpp:870
static std::string getGraphName(ConstraintGraph *)
Return name of the graph.
Definition: ConsG.cpp:752
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, ConstraintGraph *)
Definition: ConsG.cpp:837
static std::string getNodeLabel(NodeType *n, ConstraintGraph *)
Definition: ConsG.cpp:765
static bool isNodeHidden(NodeType *n, ConstraintGraph *)
Definition: ConsG.cpp:757
DOTGraphTraits(bool isSimple=false)
Definition: ConsG.cpp:746