Static Value-Flow Analysis
PointerAnalysis.cpp
Go to the documentation of this file.
1 //===- PointerAnalysis.cpp -- Base class of pointer analyses------------------//
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  * PointerAnalysis.cpp
25  *
26  * Created on: May 14, 2013
27  * Author: Yulei Sui
28  */
29 
30 #include "Util/Options.h"
31 #include "SVFIR/SVFModule.h"
32 #include "Util/SVFUtil.h"
33 
36 #include "Util/PTAStat.h"
37 #include "Graphs/ThreadCallGraph.h"
38 #include "Graphs/ICFG.h"
39 #include "Util/CallGraphBuilder.h"
40 
41 #include <iomanip>
42 #include <iostream>
43 #include <fstream>
44 #include <sstream>
45 
46 using namespace SVF;
47 using namespace SVFUtil;
48 
49 
50 SVFIR* PointerAnalysis::pag = nullptr;
51 
57 const std::string PointerAnalysis::aliasTestPartialAliasMangled = "_Z12PARTIALALIASPvS_";
60 const std::string PointerAnalysis::aliasTestFailMayAlias = "EXPECTEDFAIL_MAYALIAS";
61 const std::string PointerAnalysis::aliasTestFailMayAliasMangled = "_Z21EXPECTEDFAIL_MAYALIASPvS_";
62 const std::string PointerAnalysis::aliasTestFailNoAlias = "EXPECTEDFAIL_NOALIAS";
63 const std::string PointerAnalysis::aliasTestFailNoAliasMangled = "_Z20EXPECTEDFAIL_NOALIASPvS_";
64 
68 PointerAnalysis::PointerAnalysis(SVFIR* p, PTATY ty, bool alias_check) :
69  svfMod(nullptr),ptaTy(ty),stat(nullptr),callgraph(nullptr),callGraphSCC(nullptr),icfg(nullptr),chgraph(nullptr)
70 {
71  pag = p;
75  alias_validation = (alias_check && Options::EnableAliasCheck());
76 }
77 
82 {
83  destroy();
84  // do not delete the SVFIR for now
85  //delete pag;
86 }
87 
88 
90 {
91  delete callgraph;
92  callgraph = nullptr;
93 
94  delete callGraphSCC;
95  callGraphSCC = nullptr;
96 
97  delete stat;
98  stat = nullptr;
99 }
100 
105 {
106  assert(pag && "SVFIR has not been built!");
107 
108  svfMod = pag->getModule();
109  chgraph = pag->getCHG();
110 
113  {
114  CallGraphBuilder bd;
116  }
117  else
118  {
119  PTACallGraph* cg = pag->getCallGraph();
120  callgraph = new PTACallGraph(*cg);
121  }
123 
124  // dump callgraph
126  getCallGraph()->dump("callgraph_initial");
127 }
128 
129 
134 {
135  const MemObj* obj = pag->getObject(id);
136  assert(obj && "object not found!!");
137  if(obj->isStack())
138  {
139  if(const SVFFunction* svffun = pag->getGNode(id)->getFunction())
140  {
141  return callGraphSCC->isInCycle(getCallGraph()->getCallGraphNode(svffun)->getId());
142  }
143  }
144  return false;
145 }
146 
151 {
152  for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
153  {
154  if(ObjVar* node = SVFUtil::dyn_cast<ObjVar>(nIter->second))
155  const_cast<MemObj*>(node->getMemObj())->setFieldSensitive();
156  }
157 }
158 
159 /*
160  * Dump statistics
161  */
162 
164 {
165 
166  if(print_stat && stat)
167  {
168  stat->performStat();
169  }
170 }
171 
177 {
178 
180  dumpStat();
181 
183  if (Options::PTSPrint())
184  {
186  //dumpAllPts();
187  //dumpCPts();
188  }
189 
190  if (Options::TypePrint())
191  dumpAllTypes();
192 
194  dumpAllPts();
195 
198 
200 
202  getCallGraph()->dump("callgraph_final");
203 
205  validateTests();
206 
209 }
210 
215 {
222 
229 }
230 
231 
233 {
234  for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin();
235  nIter != this->getAllValidPtrs().end(); ++nIter)
236  {
237  const PAGNode* node = getPAG()->getGNode(*nIter);
238  if (SVFUtil::isa<DummyObjVar, DummyValVar>(node))
239  continue;
240 
241  outs() << "##<" << node->getValue()->getName() << "> ";
242  outs() << "Source Loc: " << node->getValue()->getSourceLoc();
243  outs() << "\nNodeID " << node->getId() << "\n";
244 
245  const SVFType* type = node->getValue()->getType();
247  }
248 }
249 
254 {
255 
256  const PAGNode* node = pag->getGNode(ptr);
258  if (SVFUtil::isa<DummyObjVar> (node))
259  {
260  outs() << "##<Dummy Obj > id:" << node->getId();
261  }
262  else if (!SVFUtil::isa<DummyValVar>(node) && !SVFModule::pagReadFromTXT())
263  {
264  if (node->hasValue())
265  {
266  outs() << "##<" << node->getValue()->getName() << "> ";
267  outs() << "Source Loc: " << node->getValue()->getSourceLoc();
268  }
269  }
270  outs() << "\nPtr " << node->getId() << " ";
271 
272  if (pts.empty())
273  {
274  outs() << "\t\tPointsTo: {empty}\n\n";
275  }
276  else
277  {
278  outs() << "\t\tPointsTo: { ";
279  for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit;
280  ++it)
281  outs() << *it << " ";
282  outs() << "}\n\n";
283  }
284 
285  outs() << "";
286 
287  for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it)
288  {
289  const PAGNode* node = pag->getGNode(*it);
290  if(SVFUtil::isa<ObjVar>(node) == false)
291  continue;
292  NodeID ptd = node->getId();
293  outs() << "!!Target NodeID " << ptd << "\t [";
294  const PAGNode* pagNode = pag->getGNode(ptd);
295  if (SVFUtil::isa<DummyValVar>(node))
296  outs() << "DummyVal\n";
297  else if (SVFUtil::isa<DummyObjVar>(node))
298  outs() << "Dummy Obj id: " << node->getId() << "]\n";
299  else
300  {
302  {
303  if (node->hasValue())
304  {
305  outs() << "<" << pagNode->getValue()->getName() << "> ";
306  outs() << "Source Loc: "
307  << pagNode->getValue()->getSourceLoc() << "] \n";
308  }
309  }
310  }
311  }
312 }
313 
318 {
319  outs() << "\nNodeID: " << getFunPtr(cs);
320  outs() << "\nCallSite: ";
321  outs() << cs->toString();
322  outs() << "\tLocation: " << cs->getSourceLoc();
323  outs() << "\t with Targets: ";
324 
325  if (!targets.empty())
326  {
327  FunctionSet::const_iterator fit = targets.begin();
328  FunctionSet::const_iterator feit = targets.end();
329  for (; fit != feit; ++fit)
330  {
331  const SVFFunction* callee = *fit;
332  outs() << "\n\t" << callee->getName();
333  }
334  }
335  else
336  {
337  outs() << "\n\tNo Targets!";
338  }
339 
340  outs() << "\n";
341 }
342 
347 {
348  outs() << "==================Function Pointer Targets==================\n";
349  const CallEdgeMap& callEdges = getIndCallMap();
350  CallEdgeMap::const_iterator it = callEdges.begin();
351  CallEdgeMap::const_iterator eit = callEdges.end();
352  for (; it != eit; ++it)
353  {
354  const CallICFGNode* cs = it->first;
355  const FunctionSet& targets = it->second;
356  printIndCSTargets(cs, targets);
357  }
358 
359  const CallSiteToFunPtrMap& indCS = getIndirectCallsites();
360  CallSiteToFunPtrMap::const_iterator csIt = indCS.begin();
361  CallSiteToFunPtrMap::const_iterator csEit = indCS.end();
362  for (; csIt != csEit; ++csIt)
363  {
364  const CallICFGNode* cs = csIt->first;
365  if (hasIndCSCallees(cs) == false)
366  {
367  outs() << "\nNodeID: " << csIt->second;
368  outs() << "\nCallSite: ";
369  outs() << cs->toString();
370  outs() << "\tLocation: " << cs->getSourceLoc();
371  outs() << "\n\t!!!has no targets!!!\n";
372  }
373  }
374 }
375 
376 
377 
381 void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges)
382 {
383 
384  assert(pag->isIndirectCallSites(cs) && "not an indirect callsite?");
386  for (PointsTo::iterator ii = target.begin(), ie = target.end();
387  ii != ie; ii++)
388  {
389 
391  {
392  wrnMsg("Resolved Indirect Call Edges are Out-Of-Budget, please increase the limit");
393  return;
394  }
395 
396  if(ObjVar* objPN = SVFUtil::dyn_cast<ObjVar>(pag->getGNode(*ii)))
397  {
398  const MemObj* obj = pag->getObject(objPN);
399 
400  if(obj->isFunction())
401  {
402  const SVFFunction* calleefun = SVFUtil::cast<SVFFunction>(obj->getValue());
403  const SVFFunction* callee = calleefun->getDefFunForMultipleModule();
404 
405  if(SVFUtil::matchArgs(cs, callee) == false)
406  continue;
407 
408  if(0 == getIndCallMap()[cs].count(callee))
409  {
410  newEdges[cs].insert(callee);
411  getIndCallMap()[cs].insert(callee);
412 
413  callgraph->addIndirectCallGraphEdge(cs, cs->getCaller(), callee);
414  // FIXME: do we need to update llvm call graph here?
415  // The indirect call is maintained by ourself, We may update llvm's when we need to
416  //PTACallGraphNode* callgraphNode = callgraph->getOrInsertFunction(cs.getCaller());
417  //callgraphNode->addCalledFunction(cs,callgraph->getOrInsertFunction(callee));
418  }
419  }
420  }
421  }
422 }
423 
424 /*
425  * Get virtual functions "vfns" based on CHA
426  */
428 {
429  if (chgraph->csHasVFnsBasedonCHA(cs))
430  vfns = chgraph->getCSVFsBasedonCHA(cs);
431 }
432 
433 /*
434  * Get virtual functions "vfns" from PoninsTo set "target" for callsite "cs"
435  */
436 void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns)
437 {
438 
439  if (chgraph->csHasVtblsBasedonCHA(cs))
440  {
442  const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(cs);
443  for (PointsTo::iterator it = target.begin(), eit = target.end(); it != eit; ++it)
444  {
445  const PAGNode *ptdnode = pag->getGNode(*it);
446  if (ptdnode->hasValue())
447  {
448  if (const SVFGlobalValue *vtbl = SVFUtil::dyn_cast<SVFGlobalValue>(ptdnode->getValue()))
449  {
450  if (chaVtbls.find(vtbl) != chaVtbls.end())
451  vtbls.insert(vtbl);
452  }
453  }
454  }
455  chgraph->getVFnsFromVtbls(cs, vtbls, vfns);
456  }
457 }
458 
459 /*
460  * Connect callsite "cs" to virtual functions in "vfns"
461  */
463 {
465  for (VFunSet::const_iterator fit = vfns.begin(),
466  feit = vfns.end(); fit != feit; ++fit)
467  {
468  const SVFFunction* callee = *fit;
469  callee = callee->getDefFunForMultipleModule();
470  if (getIndCallMap()[cs].count(callee) > 0)
471  continue;
472  if(cs->arg_size() == callee->arg_size() ||
473  (cs->isVarArg() && callee->isVarArg()))
474  {
475  newEdges[cs].insert(callee);
476  getIndCallMap()[cs].insert(callee);
477  const CallICFGNode* callBlockNode = cs;
478  callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(),callee);
479  }
480  }
481 }
482 
484 void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges)
485 {
486  assert(cs->isVirtualCall() && "not cpp virtual call");
487 
488  VFunSet vfns;
490  getVFnsFromCHA(cs, vfns);
491  else
492  getVFnsFromPts(cs, target, vfns);
493  connectVCallToVFns(cs, vfns, newEdges);
494 }
495 
501 {
502  // check for must alias cases, whether our alias analysis produce the correct results
503  if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun))
504  {
505  if(!checkFun->isUncalledFunction())
506  outs() << "[" << this->PTAName() << "] Checking " << fun << "\n";
507 
508  for(const CallICFGNode* callNode : pag->getCallSiteSet())
509  {
510  if (callNode->getCalledFunction() == checkFun)
511  {
512  assert(callNode->getNumArgOperands() == 2
513  && "arguments should be two pointers!!");
514  const SVFVar* V1 = callNode->getArgument(0);
515  const SVFVar* V2 = callNode->getArgument(1);
516  AliasResult aliasRes = alias(V1->getId(), V2->getId());
517 
518  bool checkSuccessful = false;
519  if (fun == aliasTestMayAlias || fun == aliasTestMayAliasMangled)
520  {
521  if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias)
522  checkSuccessful = true;
523  }
524  else if (fun == aliasTestNoAlias || fun == aliasTestNoAliasMangled)
525  {
526  if (aliasRes == AliasResult::NoAlias)
527  checkSuccessful = true;
528  }
529  else if (fun == aliasTestMustAlias || fun == aliasTestMustAliasMangled)
530  {
531  // change to must alias when our analysis support it
532  if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias)
533  checkSuccessful = true;
534  }
535  else if (fun == aliasTestPartialAlias || fun == aliasTestPartialAliasMangled)
536  {
537  // change to partial alias when our analysis support it
538  if (aliasRes == AliasResult::MayAlias)
539  checkSuccessful = true;
540  }
541  else
542  assert(false && "not supported alias check!!");
543 
544  NodeID id1 = V1->getId();
545  NodeID id2 = V2->getId();
546 
547  if (checkSuccessful)
548  outs() << sucMsg("\t SUCCESS :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
549  << callNode->getSourceLoc() << ")\n";
550  else
551  {
552  SVFUtil::errs() << errMsg("\t FAILURE :") << fun
553  << " check <id:" << id1 << ", id:" << id2
554  << "> at (" << callNode->getSourceLoc() << ")\n";
555  assert(false && "test case failed!");
556  }
557  }
558  }
559  }
560 }
561 
566 {
567 
568  if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun))
569  {
570  if(!checkFun->isUncalledFunction())
571  outs() << "[" << this->PTAName() << "] Checking " << fun << "\n";
572 
573  for(const CallICFGNode* callNode : pag->getCallSiteSet())
574  {
575  if (callNode->getCalledFunction() == checkFun)
576  {
577  assert(callNode->arg_size() == 2
578  && "arguments should be two pointers!!");
579  const SVFVar* V1 = callNode->getArgument(0);
580  const SVFVar* V2 = callNode->getArgument(1);
581  AliasResult aliasRes = alias(V1->getId(), V2->getId());
582 
583  bool expectedFailure = false;
585  {
586  // change to must alias when our analysis support it
587  if (aliasRes == AliasResult::NoAlias)
588  expectedFailure = true;
589  }
590  else if (fun == aliasTestFailNoAlias || fun == aliasTestFailNoAliasMangled)
591  {
592  // change to partial alias when our analysis support it
593  if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::PartialAlias || aliasRes == AliasResult::MustAlias)
594  expectedFailure = true;
595  }
596  else
597  assert(false && "not supported alias check!!");
598 
599  NodeID id1 = V1->getId();
600  NodeID id2 = V2->getId();
601 
602  if (expectedFailure)
603  outs() << sucMsg("\t EXPECTED-FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
604  << callNode->getSourceLoc() << ")\n";
605  else
606  {
607  SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << fun << " check <id:" << id1 << ", id:" << id2 << "> at ("
608  << callNode->getSourceLoc() << ")\n";
609  assert(false && "test case failed!");
610  }
611  }
612  }
613  }
614 }
cJSON * p
Definition: cJSON.cpp:2559
newitem type
Definition: cJSON.cpp:2739
int count
Definition: cJSON.h:216
const char *const string
Definition: cJSON.h:172
ThreadCallGraph * buildThreadCallGraph()
Build thread-aware callgraph.
const std::string toString() const override
Definition: ICFG.cpp:131
const SVFFunction * getCaller() const
Return callsite.
Definition: ICFGNode.h:470
bool isVarArg() const
Definition: ICFGNode.h:523
const std::string getSourceLoc() const override
Definition: ICFGNode.h:588
bool isVirtualCall() const
Definition: ICFGNode.h:527
u32_t arg_size() const
Definition: ICFGNode.h:505
virtual bool csHasVFnsBasedonCHA(const CallICFGNode *cs)=0
virtual const VFunSet & getCSVFsBasedonCHA(const CallICFGNode *cs)=0
virtual const VTableSet & getCSVtblsBasedonCHA(const CallICFGNode *cs)=0
virtual void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions)=0
virtual bool csHasVtblsBasedonCHA(const CallICFGNode *cs)=0
iterator begin()
Iterators.
Definition: GenericGraph.h:627
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
bool isBuiltFromFile()
Whether this SVFIR built from a txt file.
Definition: IRGraph.h:119
SymbolTableInfo * getSymbolInfo() const
Definition: IRGraph.h:114
const SVFValue * getValue() const
Get the reference value to this object.
bool isFunction() const
object attributes methods
bool isStack() const
static const Option< bool > CallGraphDotGraph
Definition: Options.h:126
static const Option< bool > EnableThreadCallGraph
Definition: Options.h:132
static const Option< bool > PTSPrint
Definition: Options.h:116
static const Option< bool > EnableAliasCheck
Definition: Options.h:130
static const Option< bool > PTSAllPrint
Definition: Options.h:117
static const Option< bool > UsePreCompFieldSensitive
Definition: Options.h:129
static const Option< bool > TypePrint
Definition: Options.h:114
static const Option< u32_t > IndirectCallLimit
Definition: Options.h:128
static const Option< bool > FuncPointerPrint
Definition: Options.h:115
static const Option< bool > ConnectVCallOnCHA
Definition: Options.h:133
static const Option< bool > PStat
Definition: Options.h:119
static const Option< u32_t > StatBudget
Definition: Options.h:120
void addIndirectCallGraphEdge(const CallICFGNode *cs, const SVFFunction *callerFun, const SVFFunction *calleeFun)
void dump(const std::string &filename)
Dump the graph.
void verifyCallGraph()
Issue a warning if the function which has indirect call sites can not be reached from program entry.
void performStat() override
Definition: PTAStat.cpp:52
void getVFnsFromPts(const CallICFGNode *cs, const PointsTo &target, VFunSet &vfns)
void destroy()
Release the memory.
virtual void validateTests()
Alias check functions to verify correctness of pointer analysis.
PTATY
Pointer analysis type list.
CommonCHGraph * chgraph
CHGraph.
static const std::string aliasTestNoAliasMangled
bool isLocalVarInRecursiveFun(NodeID id) const
Whether a local variable is in function recursions.
virtual void finalize()
Finalization of a pointer analysis, including checking alias correctness.
static const std::string aliasTestMayAliasMangled
PointerAnalysis(SVFIR *pag, PTATY ty=Default_PTA, bool alias_check=true)
Constructor.
static const std::string aliasTestFailNoAlias
virtual void dumpPts(NodeID ptr, const PointsTo &pts)
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
SVFIR * getPAG() const
static const std::string aliasTestFailMayAlias
bool print_stat
User input flags.
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and SVFIR etc.
virtual ~PointerAnalysis()
Destructor.
Set< const SVFGlobalValue * > VTableSet
PTAImplTy ptaImplTy
PTA implementation type.
PTAStat * stat
Statistics.
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
virtual void dumpTopLevelPtsTo()
static const std::string aliasTestFailMayAliasMangled
void connectVCallToVFns(const CallICFGNode *cs, const VFunSet &vfns, CallEdgeMap &newEdges)
void resetObjFieldSensitive()
Reset all object node as field-sensitive.
static const std::string aliasTestMustAlias
static const std::string aliasTestMayAlias
PTACallGraph * getCallGraph() const
Return call graph.
virtual void validateSuccessTests(std::string fun)
SVFModule * svfMod
Module.
static const std::string aliasTestPartialAlias
virtual void dumpAllPts()
virtual void resolveIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve indirect call edges.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Return all indirect callsites.
Set< const SVFFunction * > VFunSet
bool alias_validation
Flag for validating points-to/alias results.
void callGraphSCCDetection()
PTACallGraph SCC related methods.
void dumpStat()
Dump the statistics.
virtual void validateExpectedFailureTests(std::string fun)
bool hasIndCSCallees(const CallICFGNode *cs) const
virtual void resolveCPPIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve cpp indirect call edges.
@ BaseImpl
Represents PointerAnalaysis.
Set< const SVFFunction * > FunctionSet
static const std::string aliasTestNoAlias
static const std::string aliasTestPartialAliasMangled
PTACallGraph * callgraph
Call graph used for pointer analysis.
u32_t getNumOfResolvedIndCallEdge() const
Return number of resolved indirect call edges.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
NodeID getFunPtr(const CallICFGNode *cs) const
Return function pointer PAGNode at a callsite cs.
static SVFIR * pag
SVFIR.
void getVFnsFromCHA(const CallICFGNode *cs, VFunSet &vfns)
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
CallGraphSCC * callGraphSCC
SCC for PTACallGraph.
static const std::string aliasTestMustAliasMangled
virtual const std::string PTAName() const
Return PTA name.
static const std::string aliasTestFailNoAliasMangled
u32_t OnTheFlyIterBudgetForStat
Flag for iteration budget for on-the-fly statistics.
bool empty() const
Returns true if set is empty.
Definition: PointsTo.cpp:98
const_iterator end() const
Definition: PointsTo.h:132
const_iterator begin() const
Definition: PointsTo.h:128
bool isInCycle(NodeID n) const
whether the node is in a cycle
Definition: SCC.h:149
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const SVFFunction * getDefFunForMultipleModule() const
Definition: SVFValue.h:393
u32_t arg_size() const
Definition: SVFValue.cpp:170
bool isVarArg() const
Definition: SVFValue.cpp:181
PTACallGraph * getCallGraph()
Definition: SVFIR.h:192
const MemObj * getObject(NodeID id) const
Definition: SVFIR.h:395
bool isIndirectCallSites(const CallICFGNode *cs) const
Definition: SVFIR.h:366
CommonCHGraph * getCHG()
Definition: SVFIR.h:181
const CallSiteSet & getCallSiteSet() const
Get all callsites.
Definition: SVFIR.h:254
SVFModule * getModule()
Definition: SVFIR.h:161
static bool pagReadFromTXT()
Definition: SVFModule.h:98
const SVFFunction * getSVFFunction(const std::string &name)
Definition: SVFModule.cpp:48
virtual const SVFType * getType() const
Definition: SVFValue.h:256
const std::string & getName() const
Definition: SVFValue.h:243
virtual const std::string getSourceLoc() const
Definition: SVFValue.h:280
bool hasValue() const
Definition: SVFVariables.h:101
virtual const SVFFunction * getFunction() const
Return the function that this SVFVar resides in. Return nullptr if it is a global or constantexpr nod...
Definition: SVFVariables.h:122
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
void printFlattenFields(const SVFType *type)
Debug method.
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:53
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition: SVFUtil.cpp:61
bool matchArgs(const CallICFGNode *cs, const SVFFunction *callee)
Definition: SVFUtil.cpp:320
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
AliasResult
Definition: SVFType.h:527
@ PartialAlias
Definition: SVFType.h:531
@ MustAlias
Definition: SVFType.h:530
@ MayAlias
Definition: SVFType.h:529
@ NoAlias
Definition: SVFType.h:528
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96