SVF
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions | Private Attributes | List of all members
SVF::TypeBasedHeapCloning Class Referenceabstract

#include <TypeBasedHeapCloning.h>

Inheritance diagram for SVF::TypeBasedHeapCloning:
SVF::FlowSensitiveTBHC

Public Member Functions

virtual ~TypeBasedHeapCloning ()
 

Static Public Member Functions

static const MDNodegetRawCTirMetadata (const Value *)
 Returns raw ctir metadata of a Value. Returns null if it doesn't exist. More...
 

Protected Member Functions

 TypeBasedHeapCloning (BVDataPTAImpl *pta)
 Constructor. pta is the pointer analysis using this object (i.e. that which is extending). More...
 
virtual void backPropagate (NodeID clone)=0
 
void setDCHG (DCHGraph *dchg)
 DCHG must be set by extending class once the DCHG is available. More...
 
void setPAG (PAG *pag)
 PAG must be set by extending class once the PAG is available. More...
 
bool isBlkObjOrConstantObj (NodeID o) const
 
bool isBase (const DIType *a, const DIType *b) const
 
bool isClone (NodeID o) const
 Returns true if o is a clone. More...
 
void setType (NodeID o, const DIType *t)
 Sets the type (in objToType) of o. More...
 
const DITypegetType (NodeID o) const
 Returns the type (from objToType) of o. Asserts existence. More...
 
void setAllocationSite (NodeID o, NodeID site)
 Sets the allocation site (in objToAllocation) of o. More...
 
NodeID getAllocationSite (NodeID o) const
 Returns the allocation site (from objToAllocation) of o. Asserts existence. More...
 
const NodeBS getObjsWithClones (void)
 Returns objects that have clones (any key in objToClones). More...
 
void addClone (NodeID o, NodeID c)
 Add a clone c to object o. More...
 
const NodeBSgetClones (NodeID o)
 Returns all the clones of o. More...
 
void setOriginalObj (NodeID c, NodeID o)
 
NodeID getOriginalObj (NodeID c) const
 Returns the original object c is cloned from. If c is not a clone, returns itself. More...
 
PointsTogetFilterSet (NodeID loc)
 Returns the filter set of a location. Not const; could create empty PointsTo. More...
 
void addGepToObj (NodeID gep, NodeID base, unsigned offset)
 Associates gep with base (through objToGeps and memObjToGeps). More...
 
const NodeBSgetGepObjsFromMemObj (const MemObj *memObj, unsigned offset)
 
const NodeBSgetGepObjs (NodeID base)
 
const NodeBS getGepObjClones (NodeID base, unsigned offset)
 
bool init (NodeID loc, NodeID p, const DIType *tildet, bool reuse, bool gep=false)
 
NodeID cloneObject (NodeID o, const DIType *type, bool reuse)
 
NodeID addCloneDummyObjNode (const MemObj *mem)
 Add clone dummy object node to PAG. More...
 
NodeID addCloneGepObjNode (const MemObj *mem, const LocationSet &l)
 Add clone GEP object node to PAG. More...
 
NodeID addCloneFIObjNode (const MemObj *mem)
 Add clone FI object node to PAG. More...
 
const DITypegetTypeFromCTirMetadata (const Value *)
 
void validateTBHCTests (SVFModule *svfMod)
 
void dumpStats (void)
 Dump some statistics we tracked. More...
 

Protected Attributes

DCHGraphdchg = nullptr
 

Static Protected Attributes

static const DITypeundefType = nullptr
 The undefined type (•); void. More...
 
static const std::string derefFnName = "deref"
 deref function for TBHC alias tests. More...
 
static const std::string mangledDerefFnName = "_Z5derefv"
 deref function (mangled) for TBHC alias tests. More...
 

Private Member Functions

bool isGep (const PAGNode *n) const
 Test whether object is a GEP object. For convenience. More...
 

Private Attributes

BVDataPTAImplpta
 PTA extending this class. More...
 
PAGppag = nullptr
 PAG the PTA uses. Just a shortcut for getPAG(). More...
 
Map< NodeID, const DIType * > objToType
 Object -> its type. More...
 
Map< NodeID, NodeIDobjToAllocation
 
Map< NodeID, NodeBSobjToClones
 (Original) object -> set of its clones. More...
 
Map< NodeID, NodeIDcloneToOriginalObj
 (Clone) object -> original object (opposite of objToclones). More...
 
Map< NodeID, PointsTolocToFilterSet
 Maps nodes (a location like a PAG node or SVFG node) to their filter set. More...
 
Map< NodeID, NodeBSobjToGeps
 Maps objects to the GEP nodes beneath them. More...
 
Map< const MemObj *, Map< unsigned, NodeBS > > memObjToGeps
 Maps memory objects to their GEP objects. (memobj -> (fieldidx -> geps)) More...
 
unsigned numInit = 0
 
unsigned numTBWU = 0
 
unsigned numTBSSU = 0
 
unsigned numTBSU = 0
 
unsigned numReuse = 0
 
unsigned numAgg = 0
 
unsigned numSGInit = 0
 
unsigned numSGTBWU = 0
 
unsigned numSGTBSSU = 0
 
unsigned numSGTBSU = 0
 
unsigned numSGReuse = 0
 
unsigned numSGAgg = 0
 

Detailed Description

Definition at line 21 of file TypeBasedHeapCloning.h.

Constructor & Destructor Documentation

◆ ~TypeBasedHeapCloning()

virtual SVF::TypeBasedHeapCloning::~TypeBasedHeapCloning ( )
inlinevirtual

Definition at line 27 of file TypeBasedHeapCloning.h.

27 { };

◆ TypeBasedHeapCloning()

TypeBasedHeapCloning::TypeBasedHeapCloning ( BVDataPTAImpl pta)
protected

Constructor. pta is the pointer analysis using this object (i.e. that which is extending).

Definition at line 21 of file TypeBasedHeapCloning.cpp.

22 {
23  this->pta = pta;
24 }
BVDataPTAImpl * pta
PTA extending this class.

Member Function Documentation

◆ addClone()

void TypeBasedHeapCloning::addClone ( NodeID  o,
NodeID  c 
)
protected

Add a clone c to object o.

Definition at line 86 of file TypeBasedHeapCloning.cpp.

87 {
88  objToClones[o].set(c);
89 }
Map< NodeID, NodeBS > objToClones
(Original) object -> set of its clones.

◆ addCloneDummyObjNode()

NodeID TypeBasedHeapCloning::addCloneDummyObjNode ( const MemObj mem)
inlineprotected

Add clone dummy object node to PAG.

Definition at line 501 of file TypeBasedHeapCloning.cpp.

502 {
504  return ppag->addObjNode(nullptr, new CloneDummyObjPN(id, mem), id);
505 }
u32_t NodeID
Definition: SVFBasicTypes.h:80
NodeID addObjNode(const Value *val, NodeID i)
Add a memory obj node.
Definition: PAG.h:707
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
static NodeIDAllocator * get(void)
Return (singleton) allocator.

◆ addCloneFIObjNode()

NodeID TypeBasedHeapCloning::addCloneFIObjNode ( const MemObj mem)
inlineprotected

Add clone FI object node to PAG.

Definition at line 513 of file TypeBasedHeapCloning.cpp.

514 {
516  return ppag->addObjNode(mem->getRefVal(), new CloneFIObjPN(mem->getRefVal(), id, mem), id);
517 }
u32_t NodeID
Definition: SVFBasicTypes.h:80
NodeID addObjNode(const Value *val, NodeID i)
Add a memory obj node.
Definition: PAG.h:707
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
const Value * getRefVal() const
Get the reference value to this object.
Definition: MemModel.h:325
static NodeIDAllocator * get(void)
Return (singleton) allocator.

◆ addCloneGepObjNode()

NodeID TypeBasedHeapCloning::addCloneGepObjNode ( const MemObj mem,
const LocationSet l 
)
inlineprotected

Add clone GEP object node to PAG.

Definition at line 507 of file TypeBasedHeapCloning.cpp.

508 {
510  return ppag->addObjNode(mem->getRefVal(), new CloneGepObjPN(mem, id, l), id);
511 }
u32_t NodeID
Definition: SVFBasicTypes.h:80
NodeID addObjNode(const Value *val, NodeID i)
Add a memory obj node.
Definition: PAG.h:707
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
const Value * getRefVal() const
Get the reference value to this object.
Definition: MemModel.h:325
static NodeIDAllocator * get(void)
Return (singleton) allocator.

◆ addGepToObj()

void TypeBasedHeapCloning::addGepToObj ( NodeID  gep,
NodeID  base,
unsigned  offset 
)
protected

Associates gep with base (through objToGeps and memObjToGeps).

Definition at line 118 of file TypeBasedHeapCloning.cpp.

119 {
120  objToGeps[base].set(gep);
121  const PAGNode *baseNode = ppag->getPAGNode(base);
122  assert(baseNode && "TBHC: given bad base node?");
123  const ObjPN *baseObj = SVFUtil::dyn_cast<ObjPN>(baseNode);
124  assert(baseObj && "TBHC: non-object given for base?");
125  // We can use the base or the gep mem. obj.; should be identical.
126  const MemObj *baseMemObj = baseObj->getMemObj();
127 
128  objToGeps[base].set(gep);
129  memObjToGeps[baseMemObj][offset].set(gep);
130 }
const MemObj * getMemObj() const
Return memory object.
Definition: PAGNode.h:359
#define assert(ex)
Definition: util.h:141
Map< NodeID, NodeBS > objToGeps
Maps objects to the GEP nodes beneath them.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
Map< const MemObj *, Map< unsigned, NodeBS > > memObjToGeps
Maps memory objects to their GEP objects. (memobj -> (fieldidx -> geps))

◆ backPropagate()

virtual void SVF::TypeBasedHeapCloning::backPropagate ( NodeID  clone)
protectedpure virtual

Required by user. Handles back-propagation of newly created clone after all metadata has been set. Used by cloneObject.

Implemented in SVF::FlowSensitiveTBHC.

◆ cloneObject()

NodeID TypeBasedHeapCloning::cloneObject ( NodeID  o,
const DIType type,
bool  reuse 
)
protected

Returns a clone of o with type type. reuse indicates whether we are cloning as a result of reuse.

Definition at line 411 of file TypeBasedHeapCloning.cpp.

412 {
413  NodeID clone;
414  const PAGNode *obj = ppag->getPAGNode(o);
415  if (const GepObjPN *gepObj = SVFUtil::dyn_cast<GepObjPN>(obj))
416  {
417  const NodeBS &clones = getGepObjClones(gepObj->getBaseNode(), gepObj->getLocationSet().getOffset());
418  // TODO: a bit of repetition.
419  for (NodeID clone : clones)
420  {
421  if (getType(clone) == type)
422  {
423  return clone;
424  }
425  }
426 
427  clone = addCloneGepObjNode(gepObj->getMemObj(), gepObj->getLocationSet());
428 
429  // The base needs to know about the new clone.
430  addGepToObj(clone, gepObj->getBaseNode(), gepObj->getLocationSet().getOffset());
431 
432  addClone(o, clone);
433  addClone(getOriginalObj(o), clone);
434  // The only instance of original object of a Gep object being retrieved is for
435  // IN sets and gepToSVFGRetriever in FSTBHC, so we don't care that clone comes
436  // from o (we can get that by checking the base and offset).
437  setOriginalObj(clone, getOriginalObj(o));
439  cloneGepObj->setBaseNode(gepObj->getBaseNode());
440  }
441  else if (SVFUtil::isa<FIObjPN>(obj) || SVFUtil::isa<DummyObjPN>(obj))
442  {
443  o = getOriginalObj(o);
444  // Check there isn't an appropriate clone already.
445  const NodeBS &clones = getClones(o);
446  for (NodeID clone : clones)
447  {
448  if (getType(clone) == type)
449  {
450  return clone;
451  }
452  }
453 
454  if (const FIObjPN *fiObj = SVFUtil::dyn_cast<FIObjPN>(obj))
455  {
456  clone = addCloneFIObjNode(fiObj->getMemObj());
457  }
458  else
459  {
460  const DummyObjPN *dummyObj = SVFUtil::dyn_cast<DummyObjPN>(obj);
461  clone = addCloneDummyObjNode(dummyObj->getMemObj());
462  }
463  // We checked above that it's an FIObj or a DummyObj.
464 
465  // Tracking object<->clone mappings.
466  addClone(o, clone);
467  setOriginalObj(clone, o);
468  }
469  else
470  {
471  assert(false && "FSTBHC: trying to clone unhandled object");
472  }
473 
474  // Clone's metadata. This can be shared between Geps/otherwise.
475  setType(clone, type);
477 
478  backPropagate(clone);
479 
480  return clone;
481 }
void setOriginalObj(NodeID c, NodeID o)
virtual void backPropagate(NodeID clone)=0
const MemObj * getMemObj() const
Return memory object.
Definition: PAGNode.h:359
u32_t NodeID
Definition: SVFBasicTypes.h:80
void setBaseNode(NodeID base)
Set the base object from which this GEP node came from.
Definition: PAGNode.h:497
#define assert(ex)
Definition: util.h:141
void setType(NodeID o, const DIType *t)
Sets the type (in objToType) of o.
NodeID addCloneFIObjNode(const MemObj *mem)
Add clone FI object node to PAG.
NodeID addCloneGepObjNode(const MemObj *mem, const LocationSet &l)
Add clone GEP object node to PAG.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
NodeID getAllocationSite(NodeID o) const
Returns the allocation site (from objToAllocation) of o. Asserts existence.
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
void setAllocationSite(NodeID o, NodeID site)
Sets the allocation site (in objToAllocation) of o.
llvm::SparseBitVector NodeBS
Definition: SVFBasicTypes.h:87
const NodeBS & getClones(NodeID o)
Returns all the clones of o.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
NodeID addCloneDummyObjNode(const MemObj *mem)
Add clone dummy object node to PAG.
const NodeBS getGepObjClones(NodeID base, unsigned offset)
void addClone(NodeID o, NodeID c)
Add a clone c to object o.
NodeID getOriginalObj(NodeID c) const
Returns the original object c is cloned from. If c is not a clone, returns itself.
void addGepToObj(NodeID gep, NodeID base, unsigned offset)
Associates gep with base (through objToGeps and memObjToGeps).

◆ dumpStats()

void TypeBasedHeapCloning::dumpStats ( void  )
protected

Dump some statistics we tracked.

Definition at line 731 of file TypeBasedHeapCloning.cpp.

732 {
733  std::string indent = "";
734  SVFUtil::outs() << "@@@@@@@@@ TBHC STATISTICS @@@@@@@@@\n";
735  indent = " ";
736 
737  // Print clones with their types.
738  SVFUtil::outs() << indent << "=== Original objects to clones ===\n";
739  indent = " ";
740  unsigned totalClones = 0;
741  const NodeBS objs = getObjsWithClones();
742  for (NodeID o : objs)
743  {
744  const NodeBS &clones = getClones(o);
745  if (clones.count() == 0) continue;
746 
747  totalClones += clones.count();
748  SVFUtil::outs() << indent
749  << " " << o << " : "
750  << "(" << clones.count() << ")"
751  << "[ ";
752  bool first = true;
753  for (NodeID c : clones)
754  {
755  if (!first)
756  {
757  SVFUtil::outs() << ", ";
758  }
759 
760  SVFUtil::outs() << c
761  << "{"
762  << dchg->diTypeToStr(getType(c))
763  << "}";
764  first = false;
765  }
766 
767  SVFUtil::outs() << " ]\n";
768  }
769 
770  indent = " ";
771  SVFUtil::outs() << indent
772  << "Total: " << ppag->getObjectNodeNum() + ppag->getFieldObjNodeNum() + totalClones
773  << " (" << totalClones << " clones)\n";
774  SVFUtil::outs() << indent << "==================================\n";
775 
776  SVFUtil::outs() << indent << "INITIALISE : " << numInit << "\n";
777  SVFUtil::outs() << indent << "TBWU : " << numTBWU << "\n";
778  SVFUtil::outs() << indent << "TBSSU : " << numTBSSU << "\n";
779  SVFUtil::outs() << indent << "TBSU : " << numTBSU << "\n";
780  SVFUtil::outs() << indent << "REUSE : " << numReuse << "\n";
781  SVFUtil::outs() << indent << "AGG CASE : " << numAgg << "\n";
782 
783  SVFUtil::outs() << "\n";
784  SVFUtil::outs() << indent << "STACK/GLOBAL OBJECTS\n";
785  indent = " ";
786  SVFUtil::outs() << indent << "INITIALISE : " << numSGInit << "\n";
787  SVFUtil::outs() << indent << "TBWU : " << numSGTBWU << "\n";
788  SVFUtil::outs() << indent << "TBSSU : " << numSGTBSSU << "\n";
789  SVFUtil::outs() << indent << "TBSU : " << numSGTBSU << "\n";
790  SVFUtil::outs() << indent << "REUSE : " << numSGReuse << "\n";
791  SVFUtil::outs() << indent << "AGG CASE : " << numSGAgg << "\n";
792 
793  SVFUtil::outs() << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n";
794 }
static std::string diTypeToStr(const DIType *)
Returns a human-readable version of the DIType.
Definition: DCHG.cpp:958
u32_t NodeID
Definition: SVFBasicTypes.h:80
Size_t getFieldObjNodeNum() const
Definition: PAG.h:434
static std::string indent(size_t n)
Definition: DCHG.cpp:1126
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
const NodeBS getObjsWithClones(void)
Returns objects that have clones (any key in objToClones).
Size_t getObjectNodeNum() const
Definition: PAG.h:426
raw_ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:47
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
llvm::SparseBitVector NodeBS
Definition: SVFBasicTypes.h:87
const NodeBS & getClones(NodeID o)
Returns all the clones of o.

◆ getAllocationSite()

NodeID TypeBasedHeapCloning::getAllocationSite ( NodeID  o) const
protected

Returns the allocation site (from objToAllocation) of o. Asserts existence.

Definition at line 69 of file TypeBasedHeapCloning.cpp.

70 {
71  assert(objToAllocation.find(o) != objToAllocation.end() && "TBHC: object has no allocation site?");
72  return objToAllocation.at(o);
73 }
#define assert(ex)
Definition: util.h:141
Map< NodeID, NodeID > objToAllocation

◆ getClones()

const NodeBS & TypeBasedHeapCloning::getClones ( NodeID  o)
protected

Returns all the clones of o.

Definition at line 91 of file TypeBasedHeapCloning.cpp.

92 {
93  return objToClones[o];
94 }
Map< NodeID, NodeBS > objToClones
(Original) object -> set of its clones.

◆ getFilterSet()

PointsTo & TypeBasedHeapCloning::getFilterSet ( NodeID  loc)
protected

Returns the filter set of a location. Not const; could create empty PointsTo.

Definition at line 113 of file TypeBasedHeapCloning.cpp.

114 {
115  return locToFilterSet[loc];
116 }
Map< NodeID, PointsTo > locToFilterSet
Maps nodes (a location like a PAG node or SVFG node) to their filter set.

◆ getGepObjClones()

const NodeBS TypeBasedHeapCloning::getGepObjClones ( NodeID  base,
unsigned  offset 
)
protected

Returns the GEP object node(s) of base for ls. This may include clones. If there are no GEP objects, then getGepObjNode is called on the PAG (through base's getGepObjNode) which will create one.

Definition at line 142 of file TypeBasedHeapCloning.cpp.

143 {
144  assert(dchg && "TBHC: DCHG not set!");
145  // Set of GEP objects we will return.
146  NodeBS geps;
147 
148  PAGNode *node = ppag->getPAGNode(base);
149  assert(node && "TBHC: base object node does not exist.");
150  ObjPN *baseNode = SVFUtil::dyn_cast<ObjPN>(node);
151  assert(baseNode && "TBHC: base \"object\" node is not an object.");
152 
153  // totalOffset is the offset from the real base (i.e. base of base),
154  // offset is the offset into base, whether it is a field itself or not.
155  unsigned totalOffset = offset;
156  if (const GepObjPN *baseGep = SVFUtil::dyn_cast<GepObjPN>(baseNode))
157  {
158  totalOffset += baseGep->getLocationSet().getOffset();
159  }
160 
161  const DIType *baseType = getType(base);
162 
163  // First field? Just return the whole object; same thing.
164  // For arrays, we want things to work as normal because an array *object* is more
165  // like a pointer than a struct object.
166  if (offset == 0 && baseType->getTag() != dwarf::DW_TAG_array_type)
167  {
168  // The base object is the 0 gep object.
169  addGepToObj(base, base, 0);
170  geps.set(base);
171  return geps;
172  }
173 
174  if (baseNode->getMemObj()->isFieldInsensitive())
175  {
176  // If it's field-insensitive, the base represents everything.
177  geps.set(base);
178  return geps;
179  }
180 
181  // Caching on offset would improve performance but it seems minimal.
182  const NodeBS &gepObjs = getGepObjs(base);
183  for (NodeID gep : gepObjs)
184  {
185  PAGNode *node = ppag->getPAGNode(gep);
186  assert(node && "TBHC: expected gep node doesn't exist.");
187  assert((SVFUtil::isa<GepObjPN>(node) || SVFUtil::isa<FIObjPN>(node))
188  && "TBHC: expected a GEP or FI object.");
189 
190  if (GepObjPN *gepNode = SVFUtil::dyn_cast<GepObjPN>(node))
191  {
192  if (gepNode->getLocationSet().getOffset() == totalOffset)
193  {
194  geps.set(gep);
195  }
196  }
197  else
198  {
199  // Definitely a FIObj (asserted), but we don't want to add it if
200  // the object is field-sensitive because in that case it actually
201  // represents the 0th field, not the whole object.
202  if (baseNode->getMemObj()->isFieldInsensitive())
203  {
204  geps.set(gep);
205  }
206  }
207  }
208 
209  if (geps.empty())
210  {
211  // No gep node has even be created, so create one.
212  NodeID newGep;
213  LocationSet newLS;
214  // fldIdx is what is returned by getOffset.
215  newLS.setFldIdx(totalOffset);
216 
217  if (isClone(base))
218  {
219  // Don't use ppag->getGepObjNode because base and it's original object
220  // have the same memory object which is the key PAG uses.
221  newGep = addCloneGepObjNode(baseNode->getMemObj(), newLS);
222  }
223  else
224  {
225  newGep = ppag->getGepObjNode(base, newLS);
226  }
227 
228  if (GepObjPN *gep = SVFUtil::dyn_cast<GepObjPN>(ppag->getPAGNode(newGep)))
229  {
230  gep->setBaseNode(base);
231  }
232 
233  addGepToObj(newGep, base, totalOffset);
234  const DIType *newGepType = nullptr;
235  if (baseType->getTag() == dwarf::DW_TAG_array_type || baseType->getTag() == dwarf::DW_TAG_pointer_type)
236  {
237  if (const DICompositeType *arrayType = SVFUtil::dyn_cast<DICompositeType>(baseType))
238  {
239  // Array access.
240  newGepType = arrayType->getBaseType();
241  }
242  else if (const DIDerivedType *ptrType = SVFUtil::dyn_cast<DIDerivedType>(baseType))
243  {
244  // Pointer access.
245  newGepType = ptrType->getBaseType();
246  }
247  assert(newGepType && "TBHC: newGepType is neither DIComposite nor DIDerived");
248 
249  // Get the canonical type because we got the type from the DIType infrastructure directly.
250  newGepType = dchg->getCanonicalType(newGepType);
251  }
252  else
253  {
254  // Must be a struct/class.
255  // Don't use totalOffset because we're operating on the Gep object which is our parent
256  // (i.e. field of some base, not the base itself).
257  newGepType = dchg->getFieldType(getType(base), offset);
258  }
259 
260  setType(newGep, newGepType);
261  // We call the object created in the non-TBHC analysis the original object.
262  setOriginalObj(newGep, ppag->getGepObjNode(baseNode->getMemObj(), offset));
263  setAllocationSite(newGep, 0);
264 
265  geps.set(newGep);
266  }
267 
268  return geps;
269 }
void setOriginalObj(NodeID c, NodeID o)
const MemObj * getMemObj() const
Return memory object.
Definition: PAGNode.h:359
u32_t NodeID
Definition: SVFBasicTypes.h:80
const NodeBS & getGepObjs(NodeID base)
#define assert(ex)
Definition: util.h:141
void setType(NodeID o, const DIType *t)
Sets the type (in objToType) of o.
void setFldIdx(Size_t idx)
Definition: LocationSet.h:202
bool isFieldInsensitive() const
Return true if its field limit is 0.
Definition: MemModel.h:337
NodeID addCloneGepObjNode(const MemObj *mem, const LocationSet &l)
Add clone GEP object node to PAG.
llvm::DICompositeType DICompositeType
Definition: BasicTypes.h:219
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
NodeID getGepObjNode(const MemObj *obj, const LocationSet &ls)
Get a field PAG Object node according to base mem obj and offset.
Definition: PAG.cpp:671
llvm::DIDerivedType DIDerivedType
Definition: BasicTypes.h:220
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
void setAllocationSite(NodeID o, NodeID site)
Sets the allocation site (in objToAllocation) of o.
const DIType * getFieldType(const DIType *base, unsigned idx)
Returns the type of field number idx (flattened) in base.
Definition: DCHG.h:291
const DIType * getCanonicalType(const DIType *t)
Definition: DCHG.cpp:713
bool isClone(NodeID o) const
Returns true if o is a clone.
llvm::SparseBitVector NodeBS
Definition: SVFBasicTypes.h:87
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
llvm::DIType DIType
Definition: BasicTypes.h:217
void addGepToObj(NodeID gep, NodeID base, unsigned offset)
Associates gep with base (through objToGeps and memObjToGeps).

◆ getGepObjs()

const NodeBS & TypeBasedHeapCloning::getGepObjs ( NodeID  base)
protected

Returns all gep objects under an object. Not const; could create empty set.

Definition at line 137 of file TypeBasedHeapCloning.cpp.

138 {
139  return objToGeps[base];
140 }
Map< NodeID, NodeBS > objToGeps
Maps objects to the GEP nodes beneath them.

◆ getGepObjsFromMemObj()

const NodeBS & TypeBasedHeapCloning::getGepObjsFromMemObj ( const MemObj memObj,
unsigned  offset 
)
protected

Returns all gep objects at a particular offset for memory object. Not const; could create empty set.

Definition at line 132 of file TypeBasedHeapCloning.cpp.

133 {
134  return memObjToGeps[memObj][offset];
135 }
Map< const MemObj *, Map< unsigned, NodeBS > > memObjToGeps
Maps memory objects to their GEP objects. (memobj -> (fieldidx -> geps))

◆ getObjsWithClones()

const NodeBS TypeBasedHeapCloning::getObjsWithClones ( void  )
protected

Returns objects that have clones (any key in objToClones).

Definition at line 75 of file TypeBasedHeapCloning.cpp.

76 {
77  NodeBS objs;
78  for (std::pair<NodeID, NodeBS> oc : objToClones)
79  {
80  objs.set(oc.first);
81  }
82 
83  return objs;
84 }
llvm::SparseBitVector NodeBS
Definition: SVFBasicTypes.h:87
Map< NodeID, NodeBS > objToClones
(Original) object -> set of its clones.

◆ getOriginalObj()

NodeID TypeBasedHeapCloning::getOriginalObj ( NodeID  c) const
protected

Returns the original object c is cloned from. If c is not a clone, returns itself.

Definition at line 101 of file TypeBasedHeapCloning.cpp.

102 {
103  if (isClone(c))
104  {
106  && "TBHC: original object not set for clone?");
107  return cloneToOriginalObj.at(c);
108  }
109 
110  return c;
111 }
#define assert(ex)
Definition: util.h:141
Map< NodeID, NodeID > cloneToOriginalObj
(Clone) object -> original object (opposite of objToclones).
bool isClone(NodeID o) const
Returns true if o is a clone.

◆ getRawCTirMetadata()

const MDNode * TypeBasedHeapCloning::getRawCTirMetadata ( const Value v)
static

Returns raw ctir metadata of a Value. Returns null if it doesn't exist.

Definition at line 483 of file TypeBasedHeapCloning.cpp.

484 {
485  assert(v != nullptr && "TBHC: trying to get metadata from nullptr!");
486 
487  const MDNode *mdNode = nullptr;
488  if (const Instruction *inst = SVFUtil::dyn_cast<Instruction>(v))
489  {
490  mdNode = inst->getMetadata(cppUtil::ctir::derefMDName);
491  }
492  else if (const GlobalObject *go = SVFUtil::dyn_cast<GlobalObject>(v))
493  {
494  mdNode = go->getMetadata(cppUtil::ctir::derefMDName);
495  }
496 
497  // Will be nullptr if metadata isn't there.
498  return mdNode;
499 }
#define assert(ex)
Definition: util.h:141
llvm::GlobalObject GlobalObject
Definition: BasicTypes.h:81
const std::string derefMDName
Definition: CPPUtil.h:113
llvm::Instruction Instruction
Definition: BasicTypes.h:79
llvm::MDNode MDNode
Definition: BasicTypes.h:138

◆ getType()

const DIType * TypeBasedHeapCloning::getType ( NodeID  o) const
protected

Returns the type (from objToType) of o. Asserts existence.

Definition at line 58 of file TypeBasedHeapCloning.cpp.

59 {
60  assert(objToType.find(o) != objToType.end() && "TBHC: object has no type?");
61  return objToType.at(o);
62 }
Map< NodeID, const DIType * > objToType
Object -> its type.
#define assert(ex)
Definition: util.h:141

◆ getTypeFromCTirMetadata()

const DIType * TypeBasedHeapCloning::getTypeFromCTirMetadata ( const Value v)
protected

Returns the ctir type attached to the value, nullptr if non-existant. Not static because it needs the DCHG to return the canonical type. Not static because we need dchg's getCanonicalType.

Definition at line 519 of file TypeBasedHeapCloning.cpp.

520 {
521  assert(v != nullptr && "TBHC: trying to get type from nullptr!");
522 
523  const MDNode *mdNode = getRawCTirMetadata(v);
524  if (mdNode == nullptr)
525  {
526  return nullptr;
527  }
528 
529  const DIType *type = SVFUtil::dyn_cast<DIType>(mdNode);
530  if (type == nullptr)
531  {
532  SVFUtil::errs() << "TBHC: bad ctir metadata type\n";
533  return nullptr;
534  }
535 
536  return dchg->getCanonicalType(type);
537 }
#define assert(ex)
Definition: util.h:141
raw_ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:53
static const MDNode * getRawCTirMetadata(const Value *)
Returns raw ctir metadata of a Value. Returns null if it doesn&#39;t exist.
const DIType * getCanonicalType(const DIType *t)
Definition: DCHG.cpp:713
llvm::MDNode MDNode
Definition: BasicTypes.h:138
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
llvm::DIType DIType
Definition: BasicTypes.h:217

◆ init()

bool TypeBasedHeapCloning::init ( NodeID  loc,
NodeID  p,
const DIType tildet,
bool  reuse,
bool  gep = false 
)
protected

Initialise the pointees of p at loc (which is type tildet *). reuse indicates whether reuse is a possibility for this initialisation. Returns whether p changed.

Definition at line 271 of file TypeBasedHeapCloning.cpp.

272 {
273  assert(dchg && "TBHC: DCHG not set!");
274  bool changed = false;
275 
276  const PointsTo &pPt = pta->getPts(p);
277  // The points-to set we will populate in the loop to fill pPt.
278  PointsTo pNewPt;
279 
280  PointsTo &filterSet = getFilterSet(loc);
281  for (NodeID o : pPt)
282  {
283  // If it's been filtered before, it'll be filtered again.
284  if (filterSet.test(o)) continue;
285 
286  PAGNode *obj = ppag->getPAGNode(o);
287  assert(obj && "TBHC: pointee object does not exist in PAG?");
288  const DIType *tp = getType(o); // tp is t'
289 
290  // When an object is field-insensitive, we can't filter on any of the fields' types.
291  // i.e. a pointer of the field type can safely access an object of the base/struct
292  // type if that object is field-insensitive.
293  bool fieldInsensitive = false;
294  std::vector<const DIType *> fieldTypes;
295  if (ObjPN *obj = SVFUtil::dyn_cast<ObjPN>(ppag->getPAGNode(o)))
296  {
297  fieldInsensitive = obj->getMemObj()->isFieldInsensitive();
298  if (tp != nullptr && (tp->getTag() == dwarf::DW_TAG_structure_type
299  || tp->getTag() == dwarf::DW_TAG_class_type))
300  {
301  fieldTypes = dchg->getFieldTypes(tp);
302  }
303  }
304 
305  const Set<const DIType *> &aggs = dchg->isAgg(tp)
306  ? dchg->getAggs(tp) : Set<const DIType *>();
307 
308  NodeID prop;
309  bool filter = false;
310  if (tp == undefType)
311  {
312  // o is uninitialised.
313  // GEP objects should never be uninitialised; type assigned at creation.
314  assert(!isGep(obj) && "TBHC: GEP object is untyped!");
315  prop = cloneObject(o, tildet, false);
316  ++numInit;
317  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGInit;
318  }
319  else if (fieldInsensitive && tp && dchg->isFieldOf(tildet, tp))
320  {
321  // Field-insensitive object but the instruction is operating on a field.
322  prop = o;
323  ++numTBWU;
324  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGTBWU;
325  }
326  else if (gep && aggs.find(tildet) != aggs.end())
327  {
328  // SVF treats two consecutive GEPs as children to the same load/store.
329  // Special case for aggregates.
330  // SVF will transform (for example)
331  // `1: s = get struct element X from array a; 2: f = get field of struct Y from s;`
332  // to `1: s = get struct element X from array a; 2: f = get field of struct Y from a;`
333  // so we want the second instruction to be operating on an object of type
334  // 'Struct S', not 'Array of S'.
335  prop = cloneObject(o, tildet, false);
336  ++numAgg;
337  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGAgg;
338  }
339  else if (isBase(tp, tildet) && tp != tildet
340  && (reuse || dchg->isFirstField(tp, tildet) || (!reuse && pta->isHeapMemObj(o))))
341  {
342  // Downcast.
343  // One of three conditions:
344  // - !reuse && heap: because downcasts should not happen to stack/globals.
345  // - isFirstField because ^ can happen because when we take the field of a
346  // struct that is a struct, we get its first field, then it may downcast
347  // back to the struct at another GEP.
348  // TODO: this can probably be solved more cleanly.
349  // - reuse: because it can happen to stack/heap objects.
350  prop = cloneObject(o, tildet, reuse);
351  ++numTBSSU;
352  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGTBSSU;
353  }
354  else if (isBase(tildet, tp))
355  {
356  // Upcast.
357  prop = o;
358  ++numTBWU;
359  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGTBWU;
360  }
361  else if (tildet != tp && reuse)
362  {
363  // Reuse.
364  prop = cloneObject(o, tildet, true);
365  ++numReuse;
366  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGReuse;
367  }
368  else
369  {
370  // Some spurious objects will be filtered.
371  filter = true;
372  prop = o;
373  ++numTBSU;
374  if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjPN>(obj)) ++numSGTBSU;
375  }
376 
377  if (prop != o)
378  {
379  // If we cloned, we want to keep o in p's PTS but filter it (ignore it later).
380  pNewPt.set(o);
381  filterSet.set(o);
382  // TODO: hack, sound but imprecise and unclean.
383  // In the aggs case there is a difference between it being good for
384  // arrays and structs. For now, just propagate both the clone and the original
385  // object till a cleaner solution is found.
386  if (gep && aggs.find(tildet) != aggs.end())
387  {
388  filterSet.reset(o);
389  }
390  }
391 
392  pNewPt.set(prop);
393 
394  if (filter)
395  {
396  filterSet.set(o);
397  }
398  }
399 
400  if (pPt != pNewPt)
401  {
402  // Seems fast enough to perform in the naive way.
403  pta->clearFullPts(p);
404  pta->unionPts(p, pNewPt);
405  changed = true;
406  }
407 
408  return changed;
409 }
const std::vector< const DIType * > & getFieldTypes(const DIType *base)
Returns a vector of the types of all fields in base.
Definition: DCHG.h:327
virtual void clearFullPts(NodeID id)
Clear points-to set of id.
u32_t NodeID
Definition: SVFBasicTypes.h:80
#define assert(ex)
Definition: util.h:141
virtual bool unionPts(NodeID id, const PointsTo &target)
const Set< const DIType * > & getAggs(const DIType *base)
Returns all the aggregates contained (transitively) in base.
Definition: DCHG.h:343
static const DIType * undefType
The undefined type (•); void.
BVDataPTAImpl * pta
PTA extending this class.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
static bool isAgg(const DIType *t)
Definition: DCHG.cpp:342
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: SVFBasicTypes.h:93
virtual const PointsTo & getPts(NodeID id)
virtual bool isFieldOf(const DIType *f, const DIType *b)
Returns true if f is a field of b (fields from getFieldTypes).
Definition: DCHG.cpp:677
NodeID cloneObject(NodeID o, const DIType *type, bool reuse)
bool isBase(const DIType *a, const DIType *b) const
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
bool isHeapMemObj(NodeID id) const
Whether this object is heap or array.
PointsTo & getFilterSet(NodeID loc)
Returns the filter set of a location. Not const; could create empty PointsTo.
bool isGep(const PAGNode *n) const
Test whether object is a GEP object. For convenience.
bool isFirstField(const DIType *f, const DIType *b)
Definition: DCHG.cpp:931
NodeBS PointsTo
Definition: SVFBasicTypes.h:88
llvm::DIType DIType
Definition: BasicTypes.h:217

◆ isBase()

bool TypeBasedHeapCloning::isBase ( const DIType a,
const DIType b 
) const
protected

Wrapper around DCHGraph::isBase. Purpose is to keep our conditions clean by only passing two parameters like the rules.

Definition at line 42 of file TypeBasedHeapCloning.cpp.

43 {
44  assert(dchg && "TBHC: DCHG not set!");
45  return dchg->isBase(a, b, true);
46 }
#define assert(ex)
Definition: util.h:141
virtual bool isBase(const DIType *a, const DIType *b, bool firstField)
Definition: DCHG.cpp:666

◆ isBlkObjOrConstantObj()

bool TypeBasedHeapCloning::isBlkObjOrConstantObj ( NodeID  o) const
protected

Check if an object is a black hole obj or a constant object. Required since other implementations obviously do not account for clones.

Definition at line 36 of file TypeBasedHeapCloning.cpp.

37 {
38  if (isClone(o)) o = cloneToOriginalObj.at(o);
39  return SVFUtil::isa<ObjPN>(ppag->getPAGNode(o)) && ppag->isBlkObjOrConstantObj(o);
40 }
bool isBlkObjOrConstantObj(NodeID id) const
Definition: PAG.h:613
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
Map< NodeID, NodeID > cloneToOriginalObj
(Clone) object -> original object (opposite of objToclones).
bool isClone(NodeID o) const
Returns true if o is a clone.

◆ isClone()

bool TypeBasedHeapCloning::isClone ( NodeID  o) const
protected

Returns true if o is a clone.

Definition at line 48 of file TypeBasedHeapCloning.cpp.

49 {
50  return cloneToOriginalObj.find(o) != cloneToOriginalObj.end();
51 }
Map< NodeID, NodeID > cloneToOriginalObj
(Clone) object -> original object (opposite of objToclones).

◆ isGep()

bool TypeBasedHeapCloning::isGep ( const PAGNode n) const
private

Test whether object is a GEP object. For convenience.

Definition at line 539 of file TypeBasedHeapCloning.cpp.

540 {
541  assert(n != nullptr && "TBHC: testing if null is a GEP object!");
542  return SVFUtil::isa<GepObjPN>(n);
543 }
#define assert(ex)
Definition: util.h:141

◆ setAllocationSite()

void TypeBasedHeapCloning::setAllocationSite ( NodeID  o,
NodeID  site 
)
protected

Sets the allocation site (in objToAllocation) of o.

Definition at line 64 of file TypeBasedHeapCloning.cpp.

65 {
66  objToAllocation.insert({o, site});
67 }
Map< NodeID, NodeID > objToAllocation

◆ setDCHG()

void TypeBasedHeapCloning::setDCHG ( DCHGraph dchg)
protected

DCHG must be set by extending class once the DCHG is available.

Definition at line 26 of file TypeBasedHeapCloning.cpp.

27 {
28  this->dchg = dchg;
29 }

◆ setOriginalObj()

void TypeBasedHeapCloning::setOriginalObj ( NodeID  c,
NodeID  o 
)
protected

Definition at line 96 of file TypeBasedHeapCloning.cpp.

97 {
98  cloneToOriginalObj.insert({c, o});
99 }
Map< NodeID, NodeID > cloneToOriginalObj
(Clone) object -> original object (opposite of objToclones).

◆ setPAG()

void TypeBasedHeapCloning::setPAG ( PAG pag)
protected

PAG must be set by extending class once the PAG is available.

Definition at line 31 of file TypeBasedHeapCloning.cpp.

32 {
33  ppag = pag;
34 }
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().

◆ setType()

void TypeBasedHeapCloning::setType ( NodeID  o,
const DIType t 
)
protected

Sets the type (in objToType) of o.

Definition at line 53 of file TypeBasedHeapCloning.cpp.

54 {
55  objToType.insert({o, t});
56 }
Map< NodeID, const DIType * > objToType
Object -> its type.

◆ validateTBHCTests()

void TypeBasedHeapCloning::validateTBHCTests ( SVFModule svfMod)
protected

Runs tests on MAYALIAS, NOALIAS, etc. built from TBHC_MAYALIAS, TBHC_NOALIAS, etc. macros. TBHC_XALIAS macros produce: call XALIAS(...) %1 = load ... ... n = load p store ... n-1, ...* n !ctir !t1 call deref() n+1 = load ... ... n+n = load q store ... n+n-1, ...* n+n !ctir !t2 call deref() We want to test the points-to sets of n and n+n after filtering with !t1 and !t2 respectively.

Definition at line 562 of file TypeBasedHeapCloning.cpp.

563 {
564  const LLVMModuleSet *llvmModuleSet = LLVMModuleSet::getLLVMModuleSet();
565  for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
566  {
567  const PAG::CallSiteSet &callSites = ppag->getCallSiteSet();
568  for (const CallBlockNode *cbn : callSites)
569  {
570  const CallSite &cs = SVFUtil::getLLVMCallSite(cbn->getCallSite());
571  const Function *fn = cs.getCalledFunction();
572  if (fn == nullptr || !isAliasTestFunction(fn->getName().str()))
573  {
574  continue;
575  }
576 
577  // We have a test call,
578  // We want the store which stores to the pointer in question (i.e. operand of the
579  // store is the pointer, and the store itself is the dereference).
580  const StoreInst *ps = nullptr, *qs = nullptr;
581  // Check: currInst is a deref call, so p/q is prevInst.
582 
583  // Find p.
584  const Instruction *prevInst = nullptr;
585  const Instruction *currInst = cs.getInstruction();
586  do
587  {
588  if (const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
589  {
590  std::string calledFnName = ci->getCalledFunction()->getName().str();
591  if (calledFnName == derefFnName || calledFnName == mangledDerefFnName)
592  {
593  const StoreInst *si = SVFUtil::dyn_cast<StoreInst>(prevInst);
594  assert(si && "TBHC: validation macro not producing stores?");
595  ps = si;
596  break;
597  }
598  }
599 
600  prevInst = currInst;
601  currInst = currInst->getNextNonDebugInstruction();
602  }
603  while (currInst != nullptr);
604 
605  // Repeat for q.
606  while (currInst != nullptr)
607  {
608  // while loop, not do-while, because we need to the next instruction (current
609  // instruction is the first deref()).
610  prevInst = currInst;
611  currInst = currInst->getNextNonDebugInstruction();
612 
613  if (const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
614  {
615  std::string calledFnName = ci->getCalledFunction()->getName().str();
616  if (calledFnName == derefFnName || calledFnName == mangledDerefFnName)
617  {
618  const StoreInst *si = SVFUtil::dyn_cast<StoreInst>(prevInst);
619  assert(si && "TBHC: validation macro not producing stores?");
620  qs = si;
621  break;
622  }
623  }
624  }
625 
626  assert(ps != nullptr && qs != nullptr && "TBHC: malformed alias test?");
627  NodeID p = ppag->getValueNode(ps->getPointerOperand()),
628  q = ppag->getValueNode(qs->getPointerOperand());
629  const DIType *pt = getTypeFromCTirMetadata(ps), *qt = getTypeFromCTirMetadata(qs);
630 
631  // Now filter both points-to sets according to the type of the value.
632  const PointsTo &pPts = pta->getPts(p), &qPts = pta->getPts(q);
633  PointsTo pPtsFiltered, qPtsFiltered;
634  for (NodeID o : pPts)
635  {
636  if (getType(o) != undefType && isBase(pt, getType(o)))
637  {
638  pPtsFiltered.set(o);
639  }
640  }
641 
642  for (NodeID o : qPts)
643  {
644  if (getType(o) != undefType && isBase(qt, getType(o)))
645  {
646  qPtsFiltered.set(o);
647  }
648  }
649 
651  assert(bvpta && "TBHC: need a BVDataPTAImpl for TBHC alias testing.");
652  AliasResult res = bvpta->alias(pPtsFiltered, qPtsFiltered);
653 
654  bool passed = false;
655  std::string testName = "";
656  if (fn->getName() == PointerAnalysis::aliasTestMayAlias
657  || fn->getName() == PointerAnalysis::aliasTestMayAliasMangled)
658  {
659  passed = res == llvm::MayAlias || res == llvm::MustAlias;
661  }
662  else if (fn->getName() == PointerAnalysis::aliasTestNoAlias
663  || fn->getName() == PointerAnalysis::aliasTestNoAliasMangled)
664  {
665  passed = res == llvm::NoAlias;
667  }
668  else if (fn->getName() == PointerAnalysis::aliasTestMustAlias
669  || fn->getName() == PointerAnalysis::aliasTestMustAliasMangled)
670  {
671  passed = res == llvm::MustAlias || res == llvm::MayAlias;
673  }
674  else if (fn->getName() == PointerAnalysis::aliasTestPartialAlias
676  {
677  passed = res == llvm::MayAlias || res == llvm::PartialAlias;
679  }
680  else if (fn->getName() == PointerAnalysis::aliasTestFailMayAlias
682  {
683  passed = res != llvm::MayAlias && res != llvm::MustAlias && res != llvm::PartialAlias;
685  }
686  else if (fn->getName() == PointerAnalysis::aliasTestFailNoAlias
688  {
689  passed = res != llvm::NoAlias;
691  }
692 
693  SVFUtil::outs() << "[" << pta->PTAName() << "] Checking " << testName << "\n";
694  raw_ostream &msgStream = passed ? SVFUtil::outs() : SVFUtil::errs();
695  msgStream << (passed ? SVFUtil::sucMsg("\t SUCCESS") : SVFUtil::errMsg("\t FAILURE"))
696  << " : " << testName
697  << " check <id:" << p << ", id:" << q << "> "
698  << "at (" << SVFUtil::getSourceLoc(cs.getInstruction()) << ")\n";
699  if (!passed)
700  assert(false && "test case failed!");
701 
702  if (pPtsFiltered.empty())
703  {
704  msgStream << SVFUtil::wrnMsg("\t WARNING")
705  << " : pts(" << p << ") is empty\n";
706  }
707 
708  if (qPtsFiltered.empty())
709  {
710  msgStream << SVFUtil::wrnMsg("\t WARNING")
711  << " : pts(" << q << ") is empty\n";
712  }
713 
714  if (testName == PointerAnalysis::aliasTestMustAlias)
715  {
716  msgStream << SVFUtil::wrnMsg("\t WARNING")
717  << " : MUSTALIAS tests are actually MAYALIAS tests\n";
718  }
719 
721  {
722  msgStream << SVFUtil::wrnMsg("\t WARNING")
723  << " : PARTIALALIAS tests are actually MAYALIAS tests\n";
724  }
725 
726  msgStream.flush();
727  }
728  }
729 }
static bool isAliasTestFunction(std::string name)
Returns true if the function name matches MAYALIAS, NOALIAS, etc.
llvm::StoreInst StoreInst
Definition: BasicTypes.h:146
NodeID getValueNode(const Value *V)
Get PAG Node according to LLVM value.
Definition: PAG.h:521
static const std::string derefFnName
deref function for TBHC alias tests.
llvm::raw_ostream raw_ostream
LLVM outputs.
Definition: BasicTypes.h:99
u32_t NodeID
Definition: SVFBasicTypes.h:80
static const std::string aliasTestFailMayAliasMangled
static const std::string aliasTestNoAlias
#define assert(ex)
Definition: util.h:141
raw_ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:53
llvm::CallInst CallInst
Definition: BasicTypes.h:143
CallBase * getInstruction() const
Definition: BasicTypes.h:316
std::string getSourceLoc(const Value *val)
Return source code including line number and file name from debug information.
Definition: SVFUtil.cpp:259
std::string sucMsg(std::string msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:54
u32_t getModuleNum() const
Definition: LLVMModule.h:91
unsigned u32_t
Definition: SVFBasicTypes.h:75
static const DIType * undefType
The undefined type (•); void.
BVDataPTAImpl * pta
PTA extending this class.
PAG * ppag
PAG the PTA uses. Just a shortcut for getPAG().
static const std::string aliasTestMayAliasMangled
static const std::string aliasTestFailNoAlias
llvm::Function Function
Definition: BasicTypes.h:76
virtual const PointsTo & getPts(NodeID id)
llvm::Instruction Instruction
Definition: BasicTypes.h:79
static const std::string mangledDerefFnName
deref function (mangled) for TBHC alias tests.
static const std::string aliasTestMustAliasMangled
static const std::string aliasTestNoAliasMangled
Set< const CallBlockNode * > CallSiteSet
Definition: PAG.h:51
static const std::string aliasTestMayAlias
static const std::string aliasTestMustAlias
raw_ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:47
static const std::string aliasTestPartialAlias
bool isBase(const DIType *a, const DIType *b) const
const DIType * getType(NodeID o) const
Returns the type (from objToType) of o. Asserts existence.
Function * getCalledFunction() const
Definition: BasicTypes.h:326
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:69
CallSite getLLVMCallSite(const Instruction *inst)
Return LLVM callsite given a instruction.
Definition: SVFUtil.h:183
static const std::string aliasTestFailNoAliasMangled
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
const DIType * getTypeFromCTirMetadata(const Value *)
static const std::string aliasTestPartialAliasMangled
std::string wrnMsg(std::string msg)
Returns warning message by converting a string into yellow string output.
Definition: SVFUtil.cpp:62
std::string errMsg(std::string msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
virtual const std::string PTAName() const
Return PTA name.
const CallSiteSet & getCallSiteSet() const
Definition: PAG.h:201
static const std::string aliasTestFailMayAlias
NodeBS PointsTo
Definition: SVFBasicTypes.h:88
virtual AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
Interface expose to users of our pointer analysis, given Location infos.
llvm::DIType DIType
Definition: BasicTypes.h:217
llvm::AliasResult AliasResult
Definition: BasicTypes.h:130

Member Data Documentation

◆ cloneToOriginalObj

Map<NodeID, NodeID> SVF::TypeBasedHeapCloning::cloneToOriginalObj
private

(Clone) object -> original object (opposite of objToclones).

Definition at line 160 of file TypeBasedHeapCloning.h.

◆ dchg

DCHGraph* SVF::TypeBasedHeapCloning::dchg = nullptr
protected

Class hierarchy graph built from debug information. Required, CHG from IR is insufficient.

Definition at line 47 of file TypeBasedHeapCloning.h.

◆ derefFnName

const std::string TypeBasedHeapCloning::derefFnName = "deref"
staticprotected

deref function for TBHC alias tests.

Definition at line 34 of file TypeBasedHeapCloning.h.

◆ locToFilterSet

Map<NodeID, PointsTo> SVF::TypeBasedHeapCloning::locToFilterSet
private

Maps nodes (a location like a PAG node or SVFG node) to their filter set.

Definition at line 162 of file TypeBasedHeapCloning.h.

◆ mangledDerefFnName

const std::string TypeBasedHeapCloning::mangledDerefFnName = "_Z5derefv"
staticprotected

deref function (mangled) for TBHC alias tests.

Definition at line 36 of file TypeBasedHeapCloning.h.

◆ memObjToGeps

Map<const MemObj *, Map<unsigned, NodeBS> > SVF::TypeBasedHeapCloning::memObjToGeps
private

Maps memory objects to their GEP objects. (memobj -> (fieldidx -> geps))

Definition at line 166 of file TypeBasedHeapCloning.h.

◆ numAgg

unsigned SVF::TypeBasedHeapCloning::numAgg = 0
private

Definition at line 177 of file TypeBasedHeapCloning.h.

◆ numInit

unsigned SVF::TypeBasedHeapCloning::numInit = 0
private

Definition at line 172 of file TypeBasedHeapCloning.h.

◆ numReuse

unsigned SVF::TypeBasedHeapCloning::numReuse = 0
private

Definition at line 176 of file TypeBasedHeapCloning.h.

◆ numSGAgg

unsigned SVF::TypeBasedHeapCloning::numSGAgg = 0
private

Definition at line 185 of file TypeBasedHeapCloning.h.

◆ numSGInit

unsigned SVF::TypeBasedHeapCloning::numSGInit = 0
private

Definition at line 180 of file TypeBasedHeapCloning.h.

◆ numSGReuse

unsigned SVF::TypeBasedHeapCloning::numSGReuse = 0
private

Definition at line 184 of file TypeBasedHeapCloning.h.

◆ numSGTBSSU

unsigned SVF::TypeBasedHeapCloning::numSGTBSSU = 0
private

Definition at line 182 of file TypeBasedHeapCloning.h.

◆ numSGTBSU

unsigned SVF::TypeBasedHeapCloning::numSGTBSU = 0
private

Definition at line 183 of file TypeBasedHeapCloning.h.

◆ numSGTBWU

unsigned SVF::TypeBasedHeapCloning::numSGTBWU = 0
private

Definition at line 181 of file TypeBasedHeapCloning.h.

◆ numTBSSU

unsigned SVF::TypeBasedHeapCloning::numTBSSU = 0
private

Definition at line 174 of file TypeBasedHeapCloning.h.

◆ numTBSU

unsigned SVF::TypeBasedHeapCloning::numTBSU = 0
private

Definition at line 175 of file TypeBasedHeapCloning.h.

◆ numTBWU

unsigned SVF::TypeBasedHeapCloning::numTBWU = 0
private

Definition at line 173 of file TypeBasedHeapCloning.h.

◆ objToAllocation

Map<NodeID, NodeID> SVF::TypeBasedHeapCloning::objToAllocation
private

Object -> allocation site. The value NodeID depends on the pointer analysis (could be an SVFG node or PAG node for example).

Definition at line 156 of file TypeBasedHeapCloning.h.

◆ objToClones

Map<NodeID, NodeBS> SVF::TypeBasedHeapCloning::objToClones
private

(Original) object -> set of its clones.

Definition at line 158 of file TypeBasedHeapCloning.h.

◆ objToGeps

Map<NodeID, NodeBS> SVF::TypeBasedHeapCloning::objToGeps
private

Maps objects to the GEP nodes beneath them.

Definition at line 164 of file TypeBasedHeapCloning.h.

◆ objToType

Map<NodeID, const DIType *> SVF::TypeBasedHeapCloning::objToType
private

Object -> its type.

Definition at line 152 of file TypeBasedHeapCloning.h.

◆ ppag

PAG* SVF::TypeBasedHeapCloning::ppag = nullptr
private

PAG the PTA uses. Just a shortcut for getPAG().

Definition at line 149 of file TypeBasedHeapCloning.h.

◆ pta

BVDataPTAImpl* SVF::TypeBasedHeapCloning::pta
private

PTA extending this class.

Definition at line 147 of file TypeBasedHeapCloning.h.

◆ undefType

const DIType * TypeBasedHeapCloning::undefType = nullptr
staticprotected

The undefined type (•); void.

Definition at line 27 of file TypeBasedHeapCloning.h.


The documentation for this class was generated from the following files: