Static Value-Flow Analysis
PointerAnalysisImpl.cpp
Go to the documentation of this file.
1 //===- PointerAnalysisImpl.cpp -- Pointer analysis implementation--------------------//
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 /*
25  * PointerAnalysisImpl.cpp
26  *
27  * Created on: 28Mar.,2020
28  * Author: yulei
29  */
30 
31 
33 #include "Util/Options.h"
34 #include <fstream>
35 #include <sstream>
36 
37 using namespace SVF;
38 using namespace SVFUtil;
39 using namespace std;
40 
45  PointerAnalysis(p, type, alias_check), ptCache()
46 {
48  || type == TypeCPP_WPA || type == FlowS_DDA
50  {
51  // Only maintain reverse points-to when the analysis is field-sensitive, as objects turning
52  // field-insensitive is all it is used for.
53  bool maintainRevPts = Options::MaxFieldLimit() != 0;
54  if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique<MutDiffPTDataTy>(maintainRevPts);
55  else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique<PersDiffPTDataTy>(getPtCache(), maintainRevPts);
56  else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
57  }
58  else if (type == Steensgaard_WPA)
59  {
60  // Steensgaard is only field-insensitive (for now?), so no reverse points-to.
61  if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique<MutDiffPTDataTy>(false);
62  else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique<PersDiffPTDataTy>(getPtCache(), false);
63  else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
64  }
65  else if (type == FSSPARSE_WPA)
66  {
68  {
69  if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique<MutIncDFPTDataTy>(false);
70  else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique<PersIncDFPTDataTy>(getPtCache(), false);
71  else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
72  }
73  else
74  {
75  if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique<MutDFPTDataTy>(false);
76  else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique<PersDFPTDataTy>(getPtCache(), false);
77  else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
78  }
79  }
80  else if (type == VFS_WPA)
81  {
82  if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique<MutVersionedPTDataTy>(false);
83  else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique<PersVersionedPTDataTy>(getPtCache(), false);
84  else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!");
85  }
86  else assert(false && "no points-to data available");
87 
89 }
90 
92 {
95 
96  if (Options::ptDataBacking() == PTBackingType::Persistent && print_stat)
97  {
98  std::string moduleName(pag->getModule()->getModuleIdentifier());
99  std::vector<std::string> names = SVFUtil::split(moduleName,'/');
100  if (names.size() > 1)
101  moduleName = names[names.size() - 1];
102 
103  std::string subtitle;
104 
106  subtitle = "Andersen's analysis bitvector";
107  else if(ptaTy >=FSDATAFLOW_WPA && ptaTy <=FSCS_WPA)
108  subtitle = "flow-sensitive analysis bitvector";
109  else if(ptaTy >=CFLFICI_WPA && ptaTy <=CFLFSCS_WPA)
110  subtitle = "CFL analysis bitvector";
111  else if(ptaTy == TypeCPP_WPA)
112  subtitle = "Type analysis bitvector";
113  else if(ptaTy >=FieldS_DDA && ptaTy <=Cxt_DDA)
114  subtitle = "DDA bitvector";
115  else
116  subtitle = "bitvector";
117 
118  SVFUtil::outs() << "\n****Persistent Points-To Cache Statistics: " << subtitle << "****\n";
119  SVFUtil::outs() << "################ (program : " << moduleName << ")###############\n";
120  SVFUtil::outs().flags(std::ios::left);
121  ptCache.printStats("bitvector");
122  SVFUtil::outs() << "#######################################################" << std::endl;
123  SVFUtil::outs().flush();
124  }
125 
126 }
127 
131 void BVDataPTAImpl::expandFIObjs(const PointsTo& pts, PointsTo& expandedPts)
132 {
133  expandedPts = pts;;
134  for(PointsTo::iterator pit = pts.begin(), epit = pts.end(); pit!=epit; ++pit)
135  {
136  if (pag->getBaseObjVar(*pit) == *pit || isFieldInsensitive(*pit))
137  {
138  expandedPts |= pag->getAllFieldsObjVars(*pit);
139  }
140  }
141 }
142 
143 void BVDataPTAImpl::expandFIObjs(const NodeBS& pts, NodeBS& expandedPts)
144 {
145  expandedPts = pts;
146  for (const NodeID o : pts)
147  {
148  if (pag->getBaseObjVar(o) == o || isFieldInsensitive(o))
149  {
150  expandedPts |= pag->getAllFieldsObjVars(o);
151  }
152  }
153 }
154 
156 {
158 }
159 
160 void BVDataPTAImpl::writeObjVarToFile(const string& filename)
161 {
162  outs() << "Storing ObjVar to '" << filename << "'...";
163  error_code err;
164  std::fstream f(filename.c_str(), std::ios_base::out);
165  if (!f.good())
166  {
167  outs() << " error opening file for writing!\n";
168  return;
169  }
170 
171  // Write BaseNodes insensitivity to file
172  NodeBS NodeIDs;
173  for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it)
174  {
175  PAGNode* pagNode = it->second;
176  if (!isa<ObjVar>(pagNode)) continue;
177  NodeID n = pag->getBaseObjVar(it->first);
178  if (NodeIDs.test(n)) continue;
179  f << n << " ";
180  f << isFieldInsensitive(n) << "\n";
181  NodeIDs.set(n);
182  }
183 
184  f << "------\n";
185 
186  f.close();
187  if (f.good())
188  {
189  outs() << "\n";
190  return;
191  }
192 
193 
194 }
195 
197 {
198  // Write analysis results to file
199  for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it)
200  {
201  NodeID var = it->first;
202  const PointsTo &pts = getPts(var);
203 
204  stringstream ss;
205  f << var << " -> { ";
206  if (pts.empty())
207  {
208  f << " ";
209  }
210  else
211  {
212  for (NodeID n: pts)
213  {
214  f << n << " ";
215  }
216  }
217  f << "}\n";
218  }
219 
220 }
221 
223 {
224  //write gepObjVarMap to file(in form of: baseID offset gepObjNodeId)
225  SVFIR::NodeOffsetMap &gepObjVarMap = pag->getGepObjNodeMap();
226  for(SVFIR::NodeOffsetMap::const_iterator it = gepObjVarMap.begin(), eit = gepObjVarMap.end(); it != eit; it++)
227  {
228  const SVFIR::NodeOffset offsetPair = it -> first;
229  //write the base id to file
230  f << offsetPair.first << " ";
231  //write the offset to file
232  f << offsetPair.second << " ";
233  //write the gepObjNodeId to file
234  f << it->second << "\n";
235  }
236 
237 }
238 
244 void BVDataPTAImpl::writeToFile(const string& filename)
245 {
246 
247  outs() << "Storing pointer analysis results to '" << filename << "'...";
248 
249  error_code err;
250  std::fstream f(filename.c_str(), std::ios_base::app);
251  if (!f.good())
252  {
253  outs() << " error opening file for writing!\n";
254  return;
255  }
256 
258 
259  f << "------\n";
260 
262 
263  f << "------\n";
264 
265  // Write BaseNodes insensitivity to file
266  NodeBS NodeIDs;
267  for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it)
268  {
269  PAGNode* pagNode = it->second;
270  if (!isa<ObjVar>(pagNode)) continue;
271  NodeID n = pag->getBaseObjVar(it->first);
272  if (NodeIDs.test(n)) continue;
273  f << n << " ";
274  f << isFieldInsensitive(n) << "\n";
275  NodeIDs.set(n);
276  }
277 
278  // Job finish and close file
279  f.close();
280  if (f.good())
281  {
282  outs() << "\n";
283  return;
284  }
285 }
286 
288 {
289  string line;
290  // Read analysis results from file
291  PTDataTy *ptD = getPTDataTy();
292 
293  // Read points-to sets
294  string delimiter1 = " -> { ";
295  string delimiter2 = " }";
296  map<NodeID, string> nodePtsMap;
297  map<string, PointsTo> strPtsMap;
298 
299  while (F.good())
300  {
301  // Parse a single line in the form of "var -> { obj1 obj2 obj3 }"
302  getline(F, line);
303  if (line.at(0) == '[' || line == "---VERSIONED---") continue;
304  if (line == "------") break;
305  size_t pos = line.find(delimiter1);
306  if (pos == string::npos) break;
307  if (line.back() != '}') break;
308 
309  // var
310  NodeID var = atoi(line.substr(0, pos).c_str());
311 
312  // objs
313  pos = pos + delimiter1.length();
314  size_t len = line.length() - pos - delimiter2.length();
315  string objs = line.substr(pos, len);
316  PointsTo dstPts;
317 
318  if (!objs.empty())
319  {
320  // map the variable ID to its unique string pointer set
321  nodePtsMap[var] = objs;
322  if (strPtsMap.count(objs)) continue;
323 
324  istringstream ss(objs);
325  NodeID obj;
326  while (ss.good())
327  {
328  ss >> obj;
329  dstPts.set(obj);
330  }
331  // map the string pointer set to the parsed PointsTo set
332  strPtsMap[objs] = dstPts;
333  }
334  }
335 
336  // map the variable ID to its pointer set
337  for (auto t: nodePtsMap)
338  ptD->unionPts(t.first, strPtsMap[t.second]);
339 }
340 
342 {
343  string line;
344  //read GepObjVarMap from file
345  SVFIR::NodeOffsetMap gepObjVarMap = pag->getGepObjNodeMap();
346  while (F.good())
347  {
348  getline(F, line);
349  if (line == "------") break;
350  // Parse a single line in the form of "ID baseNodeID offset"
351  istringstream ss(line);
352  NodeID base;
353  size_t offset;
354  NodeID id;
355  ss >> base >> offset >>id;
356  SVFIR::NodeOffsetMap::const_iterator iter = gepObjVarMap.find(std::make_pair(base, offset));
357  if (iter == gepObjVarMap.end())
358  {
359  SVFVar* node = pag->getGNode(base);
360  const MemObj* obj = nullptr;
361  if (GepObjVar* gepObjVar = SVFUtil::dyn_cast<GepObjVar>(node))
362  obj = gepObjVar->getMemObj();
363  else if (FIObjVar* baseNode = SVFUtil::dyn_cast<FIObjVar>(node))
364  obj = baseNode->getMemObj();
365  else if (DummyObjVar* baseNode = SVFUtil::dyn_cast<DummyObjVar>(node))
366  obj = baseNode->getMemObj();
367  else
368  assert(false && "new gep obj node kind?");
369  pag->addGepObjNode(obj, offset, id);
371  }
372 
373 
374  }
375 }
376 
377 void BVDataPTAImpl::readAndSetObjFieldSensitivity(std::ifstream& F, const std::string& delimiterStr)
378 {
379  string line;
380  // //update ObjVar status
381  while (F.good())
382  {
383  getline(F, line);
384  if (line.empty() || line == delimiterStr)
385  break;
386  // Parse a single line in the form of "baseNodeID insensitive"
387  istringstream ss(line);
388  NodeID base;
389  bool insensitive;
390  ss >> base >> insensitive;
391 
392  if (insensitive)
394  }
395 
396 }
397 
403 bool BVDataPTAImpl::readFromFile(const string& filename)
404 {
405 
406  outs() << "Loading pointer analysis results from '" << filename << "'...";
407 
408  ifstream F(filename.c_str());
409  if (!F.is_open())
410  {
411  outs() << " error opening file for reading!\n";
412  return false;
413  }
414 
416 
418 
420 
422 
423  // Update callgraph
425 
426  F.close();
427  outs() << "\n";
428 
429  return true;
430 }
431 
432 
437 {
438  for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin();
439  nIter != this->getAllValidPtrs().end(); ++nIter)
440  {
441  const PAGNode* node = getPAG()->getGNode(*nIter);
442  if (getPAG()->isValidTopLevelPtr(node))
443  {
444  const PointsTo& pts = this->getPts(node->getId());
445  outs() << "\nNodeID " << node->getId() << " ";
446 
447  if (pts.empty())
448  {
449  outs() << "\t\tPointsTo: {empty}\n\n";
450  }
451  else
452  {
453  outs() << "\t\tPointsTo: { ";
454  for (PointsTo::iterator it = pts.begin(), eit = pts.end();
455  it != eit; ++it)
456  outs() << *it << " ";
457  outs() << "}\n\n";
458  }
459  }
460  }
461 
462  outs().flush();
463 }
464 
465 
470 {
471  OrderedNodeSet pagNodes;
472  for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; it++)
473  {
474  pagNodes.insert(it->first);
475  }
476 
477  for (NodeID n : pagNodes)
478  {
479  outs() << "----------------------------------------------\n";
480  dumpPts(n, this->getPts(n));
481  }
482 
483  outs() << "----------------------------------------------\n";
484 }
485 
486 
493 {
494  for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter)
495  {
496  const CallICFGNode* cs = iter->first;
497 
498  if (cs->isVirtualCall())
499  {
500  const SVFVar* vtbl = cs->getVtablePtr();
501  assert(vtbl != nullptr);
502  NodeID vtblId = vtbl->getId();
503  resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
504  }
505  else
506  resolveIndCalls(iter->first,getPts(iter->second),newEdges);
507  }
508 }
509 
516  CallEdgeMap& newForkEdges)
517 {
518  // add indirect fork edges
519  if(ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast<ThreadCallGraph>(callgraph))
520  {
521  for(CallSiteSet::const_iterator it = tdCallGraph->forksitesBegin(),
522  eit = tdCallGraph->forksitesEnd(); it != eit; ++it)
523  {
524  const SVFValue* forkedVal =tdCallGraph->getThreadAPI()->getForkedFun(*it)->getValue();
525  if(SVFUtil::dyn_cast<SVFFunction>(forkedVal) == nullptr)
526  {
527  SVFIR *pag = this->getPAG();
528  const NodeBS targets = this->getPts(pag->getValueNode(forkedVal)).toNodeBS();
529  for(NodeBS::iterator ii = targets.begin(), ie = targets.end(); ii != ie; ++ii)
530  {
531  if(ObjVar *objPN = SVFUtil::dyn_cast<ObjVar>(pag->getGNode(*ii)))
532  {
533  const MemObj *obj = pag->getObject(objPN);
534  if(obj->isFunction())
535  {
536  const SVFFunction *svfForkedFun = SVFUtil::cast<SVFFunction>(obj->getValue());
537  if(tdCallGraph->addIndirectForkEdge(*it, svfForkedFun))
538  newForkEdges[*it].insert(svfForkedFun);
539  }
540  }
541  }
542  }
543  }
544  }
545 }
546 
551 {
552  SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap();
553  SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap();
554 
555  // collect each gep node whose base node has been set as field-insensitive
556  NodeBS dropNodes;
557  for (auto t: memToFieldsMap)
558  {
559  NodeID base = t.first;
560  const MemObj* memObj = pag->getObject(base);
561  assert(memObj && "Invalid memobj in memToFieldsMap");
562  if (memObj->isFieldInsensitive())
563  {
564  for (NodeID id : t.second)
565  {
566  if (SVFUtil::isa<GepObjVar>(pag->getGNode(id)))
567  {
568  dropNodes.set(id);
569  }
570  else
571  assert(id == base && "Not a GepObj Node or a baseObj Node?");
572  }
573  }
574  }
575 
576  // remove the collected redundant gep nodes in each pointers's pts
577  for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
578  {
579  NodeID n = nIter->first;
580 
581  const PointsTo &tmpPts = getPts(n);
582  for (NodeID obj : tmpPts)
583  {
584  if (!dropNodes.test(obj))
585  continue;
586  NodeID baseObj = pag->getBaseObjVar(obj);
587  clearPts(n, obj);
588  addPts(n, baseObj);
589  }
590  }
591 
592  // clear GepObjVarMap and memToFieldsMap for redundant gepnodes
593  // and remove those nodes from pag
594  for (NodeID n: dropNodes)
595  {
596  NodeID base = pag->getBaseObjVar(n);
597  GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(pag->getGNode(n));
598  const APOffset apOffset = gepNode->getConstantFieldIdx();
599  GepObjVarMap.erase(std::make_pair(base, apOffset));
600  memToFieldsMap[base].reset(n);
601 
602  pag->removeGNode(gepNode);
603  }
604 }
605 
610  const SVFValue* V2)
611 {
612  return alias(pag->getValueNode(V1),pag->getValueNode(V2));
613 }
614 
619 {
620  return alias(getPts(node1),getPts(node2));
621 }
622 
627 {
628 
629  PointsTo pts1;
630  expandFIObjs(p1,pts1);
631  PointsTo pts2;
632  expandFIObjs(p2,pts2);
633 
634  if (containBlackHoleNode(pts1) || containBlackHoleNode(pts2) || pts1.intersects(pts2))
635  return AliasResult::MayAlias;
636  else
637  return AliasResult::NoAlias;
638 }
#define F(f)
cJSON * p
Definition: cJSON.cpp:2559
newitem type
Definition: cJSON.cpp:2739
buffer offset
Definition: cJSON.cpp:1113
cJSON * n
Definition: cJSON.cpp:2558
const char *const string
Definition: cJSON.h:172
virtual void normalizePointsTo()
AliasResult alias(const SVFValue *V1, const SVFValue *V2) override
Interface expose to users of our pointer analysis, given Value infos.
virtual void writeToFile(const std::string &filename)
Interface for analysis result storage on filesystem.
virtual bool readFromFile(const std::string &filename)
virtual void writeObjVarToFile(const std::string &filename)
virtual void clearPts(NodeID id, NodeID element)
Remove element from the points-to set of id.
virtual void readAndSetObjFieldSensitivity(std::ifstream &f, const std::string &delimiterStr)
virtual void writeGepObjVarMapToFile(std::fstream &f)
void finalize() override
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
virtual void writePtsResultToFile(std::fstream &f)
virtual void expandFIObjs(const PointsTo &pts, PointsTo &expandedPts)
Expand FI objects.
void dumpAllPts() override
void remapPointsToSets(void)
Remap all points-to sets to use the current mapping.
virtual void onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newForkEdges)
On the fly thread call graph construction respecting forksite.
PersistentPointsToCache< PointsTo > ptCache
virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
On the fly call graph construction.
virtual bool updateCallGraph(const CallSiteToFunPtrMap &)
Update callgraph. This should be implemented by its subclass.
BVDataPTAImpl(SVFIR *pag, PointerAnalysis::PTATY type, bool alias_check=true)
Constructor.
std::unique_ptr< PTDataTy > ptD
Points-to data.
const PointsTo & getPts(NodeID id) override
void dumpTopLevelPtsTo() override
PTDataTy * getPTDataTy() const
Get points-to data structure.
virtual void readPtsResultFromFile(std::ifstream &f)
virtual bool addPts(NodeID id, NodeID ptd)
PersistentPointsToCache< PointsTo > & getPtCache()
virtual void readGepObjVarMapFromFile(std::ifstream &f)
const SVFVar * getVtablePtr() const
Definition: ICFGNode.h:537
bool isVirtualCall() const
Definition: ICFGNode.h:527
iterator begin()
Iterators.
Definition: GenericGraph.h:627
void removeGNode(NodeType *node)
Delete a node.
Definition: GenericGraph.h:668
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
APOffset getConstantFieldIdx() const
offset of the mem object
Definition: SVFVariables.h:500
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
const SVFValue * getValue() const
Get the reference value to this object.
bool isFieldInsensitive() const
Return true if its field limit is 0.
bool isFunction() const
object attributes methods
static NodeIDAllocator * get(void)
Return (singleton) allocator.
static const Option< bool > INCDFPTData
Definition: Options.h:136
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition: Options.h:38
static const OptionMap< BVDataPTAImpl::PTBackingType > ptDataBacking
PTData type.
Definition: Options.h:69
virtual void remapAllPts(void)=0
Remaps all points-to sets to use the current mapping.
PTATY
Pointer analysis type list.
@ Cxt_DDA
context sensitive DDA
@ CFLFICI_WPA
Flow-, context-, insensitive CFL-reachability-based analysis.
@ VFS_WPA
Versioned sparse flow-sensitive WPA.
@ FSCS_WPA
Flow-, context- sensitive WPA.
@ FSDATAFLOW_WPA
Traditional Dataflow-based flow sensitive WPA.
@ AndersenSCD_WPA
Selective cycle detection andersen-style WPA.
@ Andersen_BASE
Base Andersen PTA.
@ FlowS_DDA
Flow sensitive DDA.
@ Andersen_WPA
Andersen PTA.
@ CFLFSCS_WPA
Flow-, context-, CFL-reachability-based analysis.
@ FieldS_DDA
Field sensitive DDA.
@ AndersenWaveDiff_WPA
Diff wave propagation andersen-style WPA.
@ TypeCPP_WPA
Type-based analysis for C++.
@ AndersenSFR_WPA
Stride-based field representation.
@ Steensgaard_WPA
Steensgaard PTA.
@ FSSPARSE_WPA
Sparse flow sensitive WPA.
bool isFieldInsensitive(NodeID id) const
virtual void finalize()
Finalization of a pointer analysis, including checking alias correctness.
virtual void dumpPts(NodeID ptr, const PointsTo &pts)
SVFIR * getPAG() const
bool print_stat
User input flags.
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
bool containBlackHoleNode(const PointsTo &pts)
Determine whether a points-to contains a black hole or constant node.
PTAImplTy ptaImplTy
PTA implementation type.
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
virtual void resolveIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve indirect call edges.
virtual void resolveCPPIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve cpp indirect call edges.
@ BVDataImpl
Represents BVDataPTAImpl.
void setObjFieldInsensitive(NodeID id)
PTACallGraph * callgraph
Call graph used for pointer analysis.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
static SVFIR * pag
SVFIR.
PTATY ptaTy
Pointer analysis Type.
bool empty() const
Returns true if set is empty.
Definition: PointsTo.cpp:98
const_iterator end() const
Definition: PointsTo.h:132
void set(u32_t n)
Inserts n in the set.
Definition: PointsTo.cpp:157
NodeBS toNodeBS() const
Returns this points-to set as a NodeBS.
Definition: PointsTo.cpp:313
const_iterator begin() const
Definition: PointsTo.h:128
bool intersects(const PointsTo &rhs) const
Returns true if this set and rhs share any elements.
Definition: PointsTo.cpp:189
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
Definition: SVFIR.h:350
const MemObj * getObject(NodeID id) const
Definition: SVFIR.h:395
std::pair< NodeID, APOffset > NodeOffset
Definition: SVFIR.h:68
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
MemObjToFieldsMap & getMemToFieldsMap()
Return memToFieldsMap.
Definition: SVFIR.h:129
NodeBS & getAllFieldsObjVars(const MemObj *obj)
Get all fields of an object.
Definition: SVFIR.cpp:477
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Definition: SVFIR.h:455
Map< NodeID, NodeBS > MemObjToFieldsMap
Definition: SVFIR.h:57
NodeOffsetMap & getGepObjNodeMap()
Return GepObjVarMap.
Definition: SVFIR.h:134
SVFModule * getModule()
Definition: SVFIR.h:161
Map< NodeOffset, NodeID > NodeOffsetMap
Definition: SVFIR.h:70
const std::string & getModuleIdentifier() const
Definition: SVFModule.h:185
bool test(unsigned Idx) const
iterator end() const
void set(unsigned Idx)
iterator begin() const
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
Definition: SVFUtil.h:203
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
OrderedSet< NodeID > OrderedNodeSet
Definition: GeneralType.h:112
u32_t NodeID
Definition: GeneralType.h:55
s64_t APOffset
Definition: GeneralType.h:60
AliasResult
Definition: SVFType.h:527
@ MayAlias
Definition: SVFType.h:529
@ NoAlias
Definition: SVFType.h:528