Static Value-Flow Analysis
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Attributes | List of all members
SVF::SVFIR2AbsState Class Reference

#include <SVFIR2AbsState.h>

Public Member Functions

 SVFIR2AbsState (SVFIR *ir)
 
void setRelEs (const RelExeState &relEs)
 
RelExeStategetRelEs ()
 
void widenAddrs (AbstractState &es, AbstractState &lhs, const AbstractState &rhs)
 
void narrowAddrs (AbstractState &es, AbstractState &lhs, const AbstractState &rhs)
 
AddressValue getGepObjAddress (AbstractState &es, u32_t pointer, APOffset offset)
 Return the field address given a pointer points to a struct object and an offset. More...
 
IntervalValue getRangeLimitFromType (const SVFType *type)
 Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128, 127]. More...
 
IntervalValue getZExtValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getSExtValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getFPToSIntValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getFPToUIntValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getSIntToFPValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getUIntToFPValue (const AbstractState &es, const SVFVar *var)
 
IntervalValue getTruncValue (const AbstractState &es, const SVFVar *var, const SVFType *dstType)
 
IntervalValue getFPTruncValue (const AbstractState &es, const SVFVar *var, const SVFType *dstType)
 
IntervalValue getByteOffset (const AbstractState &es, const GepStmt *gep)
 
IntervalValue getElementIndex (const AbstractState &es, const GepStmt *gep)
 Return the offset expression of a GepStmt. More...
 
void applySummary (AbstractState &es)
 
void initObjVar (AbstractState &as, const ObjVar *var)
 Init ObjVar. More...
 
AbstractValuegetAddrs (AbstractState &es, u32_t id)
 
bool inVarTable (const AbstractState &es, u32_t id) const
 
bool inAddrTable (const AbstractState &es, u32_t id) const
 
bool inVarToValTable (const AbstractState &es, u32_t id) const
 whether the variable is in varToVal table More...
 
bool inVarToAddrsTable (const AbstractState &es, u32_t id) const
 whether the variable is in varToAddrs table More...
 
bool inLocToValTable (const AbstractState &es, u32_t id) const
 whether the memory address stores a interval value More...
 
bool inLocToAddrsTable (const AbstractState &es, u32_t id) const
 whether the memory address stores memory addresses More...
 
void handleAddr (AbstractState &es, const AddrStmt *addr)
 
void handleBinary (AbstractState &es, const BinaryOPStmt *binary)
 
void handleCmp (AbstractState &es, const CmpStmt *cmp)
 
void handleLoad (AbstractState &es, const LoadStmt *load)
 
void handleStore (AbstractState &es, const StoreStmt *store)
 
void handleCopy (AbstractState &es, const CopyStmt *copy)
 
void handleCall (AbstractState &es, const CallPE *callPE)
 
void handleRet (AbstractState &es, const RetPE *retPE)
 
void handleGep (AbstractState &es, const GepStmt *gep)
 
void handleSelect (AbstractState &es, const SelectStmt *select)
 
void handlePhi (AbstractState &es, const PhiStmt *phi)
 

Static Public Member Functions

static z3::context & getContext ()
 
static u32_t getInternalID (u32_t idx)
 Return the internal index if idx is an address otherwise return the value of idx. More...
 
static u32_t getVirtualMemAddress (u32_t idx)
 The physical address starts with 0x7f...... + idx. More...
 
static bool isVirtualMemAddress (u32_t val)
 Check bit value of val start with 0x7F000000, filter by 0xFF000000. More...
 

Static Public Attributes

static AbstractValue globalNulladdrs = AddressValue()
 

Private Attributes

SVFIR_svfir
 
RelExeState _relEs
 

Detailed Description

Definition at line 42 of file SVFIR2AbsState.h.

Constructor & Destructor Documentation

◆ SVFIR2AbsState()

SVF::SVFIR2AbsState::SVFIR2AbsState ( SVFIR ir)
inline

Definition at line 47 of file SVFIR2AbsState.h.

47 : _svfir(ir) {}

Member Function Documentation

◆ applySummary()

void SVF::SVFIR2AbsState::applySummary ( AbstractState es)

◆ getAddrs()

AbstractValue& SVF::SVFIR2AbsState::getAddrs ( AbstractState es,
u32_t  id 
)
inline

Definition at line 102 of file SVFIR2AbsState.h.

103  {
104  if (inVarToAddrsTable(es, id))
105  return es[id];
106  else
107  return globalNulladdrs;
108  }
bool inVarToAddrsTable(const AbstractState &es, u32_t id) const
whether the variable is in varToAddrs table
static AbstractValue globalNulladdrs

◆ getByteOffset()

IntervalValue SVFIR2AbsState::getByteOffset ( const AbstractState as,
const GepStmt gep 
)

Return the byte offset expression of a GepStmt elemBytesize is the element byte size of an static alloc or heap alloc array e.g. GepStmt* gep = [i32*10], x, and x is [0,3] std::pair<s32_t, s32_t> byteOffset = getByteOffset(gep); byteOffset should be [0, 12] since i32 is 4 bytes.

This function, getByteOffset, calculates the byte offset for a given GepStmt.

Parameters
gepThe GepStmt representing the GetElementPtr instruction.
Returns
The calculated byte offset as an IntervalValue.

It is byte offset rather than flatten index. e.g. var2 = getelementptr inbounds struct.OuterStruct, struct.OuterStruct* var0, i64 0, i32 2, i32 0, i64 var1 struct.OuterStruct = type { i32, i32, struct.InnerStruct } struct.InnerStruct = type { [2 x i32] } there are 4 GepTypePairs (<0, struct.OuterStruct*>, <2, struct.OuterStruct>, <0, struct.InnerStruct>, <var1, [2xi32]>) this function process arr/ptr subtype by calculating elemByteSize * indexOperand and process struct subtype by calculating the byte offset from beginning to the field of struct e.g. for 0th pair <0, struct.OuterStruct*>, it is 0* ptrSize(struct.OuterStruct*) = 0 bytes for 1st pair <2, struct.OuterStruct>, it is 2nd field in struct.OuterStruct = 8 bytes for 2nd pair <0, struct.InnerStruct>, it is 0th field in struct.InnerStruct = 0 bytes

for 3rd pair <%var1, [2xi32]>, it is %var1'th element in array [2xi32] = 4bytes * %var1

Therefore the final byteoffset is [8+4*var1.lb(), 8+4*var1.ub()]

Definition at line 365 of file SVFIR2AbsState.cpp.

366 {
367  IntervalValue byte_res = IntervalValue(0);
368  for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
369  {
370  AccessPath::IdxOperandPair IdxVarAndType =
372  const SVFValue *value =
373  gep->getOffsetVarAndGepTypePairVec()[i].first->getValue();
374  const SVFType *type = IdxVarAndType.second;
375  s64_t idxLb = 0;
376  s64_t idxUb = 0;
377  s64_t byteLb = 0;
378  s64_t byteUb = 0;
379  // get lb and ub of the index value
380  if (const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
381  idxLb = idxUb = constInt->getSExtValue();
382  else
383  {
384  IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval();
385  if (idxItv.isBottom())
386  idxLb = idxUb = 0;
387  else
388  {
389  idxLb = idxItv.lb().getIntNumeral();
390  idxUb = idxItv.ub().getIntNumeral();
391  }
392  }
393  // for pointer type, elemByteSize * indexOperand
394  if (SVFUtil::isa<SVFPointerType>(type))
395  {
396  u32_t elemByte = gep->getAccessPath().gepSrcPointeeType()->getByteSize();
397  byteLb = (double)Options::MaxFieldLimit() / elemByte < idxLb? Options::MaxFieldLimit(): idxLb * elemByte;
398  byteUb = (double)Options::MaxFieldLimit() / elemByte < idxUb? Options::MaxFieldLimit(): idxUb * elemByte;
399 
400  }
401  // for array or struct, get flattened index from SymbolTable Info
402  // and then calculate the byte offset from beginning to the field of struct
403  else
404  {
406  {
407  const std::vector<u32_t>& so = SymbolTableInfo::SymbolInfo()
408  ->getTypeInfo(type)
410  if (so.empty() || idxUb >= (APOffset)so.size() || idxLb < 0)
411  {
412  byteLb = byteUb = 0;
413  }
414  else
415  {
417  type, idxLb);
419  type, idxUb);
420  for (u32_t idx = 0; idx < idxLb; ++idx)
421  {
423  byteLb += byte;
424  }
425  byteUb = byteLb;
426  for (u32_t idx = idxLb; idx < idxUb; ++idx)
427  {
429  byteUb += byte;
430  }
431  }
432  }
433  else
434  {
435  byteLb = byteUb = 0;
436  }
437 
438  }
439  byte_res = byte_res + IntervalValue(byteLb, byteUb);
440  }
441 
442  if (byte_res.isBottom())
443  {
444  byte_res = IntervalValue(0);
445  }
446  return byte_res;
447 }
unsigned u32_t
Definition: CommandLine.h:18
newitem type
Definition: cJSON.cpp:2739
std::pair< const SVFVar *, const SVFType * > IdxOperandPair
Definition: AccessPath.h:64
const SVFType * gepSrcPointeeType() const
Definition: AccessPath.h:112
s64_t getIntNumeral() const
Definition: NumericValue.h:703
const AccessPath::IdxOperandPairs getOffsetVarAndGepTypePairVec() const
const AccessPath & getAccessPath() const
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
const BoundedInt & lb() const
Return the lower bound.
bool isBottom() const
Definition: IntervalValue.h:71
const BoundedInt & ub() const
Return the upper bound.
static const Option< bool > ModelArrays
Definition: Options.h:207
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition: Options.h:38
u32_t getByteSize() const
Definition: SVFType.h:244
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition: SVFType.h:98
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
s64_t APOffset
Definition: GeneralType.h:60
signed long long s64_t
Definition: GeneralType.h:49

◆ getContext()

static z3::context& SVF::SVFIR2AbsState::getContext ( )
inlinestatic

Definition at line 90 of file SVFIR2AbsState.h.

91  {
92  return Z3Expr::getContext();
93  }
static z3::context & getContext()
Get z3 context, singleton design here to make sure we only have one context.
Definition: Z3Expr.cpp:66

◆ getElementIndex()

IntervalValue SVFIR2AbsState::getElementIndex ( const AbstractState as,
const GepStmt gep 
)

Return the offset expression of a GepStmt.

This function, getElementIndex, calculates the offset range as a pair of APOffset values for a given GepStmt.

Parameters
gepThe GepStmt representing the GetElementPtr instruction.
Returns
A pair of APOffset values representing the offset range.

Definition at line 457 of file SVFIR2AbsState.cpp.

458 {
459  if (gep->isConstantOffset())
461  IntervalValue res = IntervalValue(0);
462  for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
463  {
464  AccessPath::IdxOperandPair IdxVarAndType =
466  const SVFValue *value =
467  gep->getOffsetVarAndGepTypePairVec()[i].first->getValue();
468  const SVFType *type = IdxVarAndType.second;
469  // idxLb/Ub is the flattened offset generated by the current OffsetVarAndGepTypePair
470  s64_t idxLb;
471  s64_t idxUb;
472  // get lb and ub of the index value
473  if (const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
474  idxLb = idxUb = constInt->getSExtValue();
475  else
476  {
477  IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval();
478  if (idxItv.isBottom())
479  idxLb = idxUb = 0;
480  else
481  {
482  idxLb = idxItv.lb().getIntNumeral();
483  idxUb = idxItv.ub().getIntNumeral();
484  }
485  }
486  // for pointer type, flattened index = elemNum * idx
487  if (SVFUtil::isa<SVFPointerType>(type))
488  {
490  idxLb = (double)Options::MaxFieldLimit() / elemNum < idxLb? Options::MaxFieldLimit(): idxLb * elemNum;
491  idxUb = (double)Options::MaxFieldLimit() / elemNum < idxUb? Options::MaxFieldLimit(): idxUb * elemNum;
492  }
493  // for array or struct, get flattened index from SymbolTable Info
494  else
495  {
497  {
498  const std::vector<u32_t>& so = SymbolTableInfo::SymbolInfo()
499  ->getTypeInfo(type)
501  if (so.empty() || idxUb >= (APOffset)so.size() || idxLb < 0)
502  {
503  idxLb = idxUb = 0;
504  }
505  else
506  {
508  type, idxLb);
510  type, idxUb);
511  }
512  }
513  else
514  idxLb = idxUb = 0;
515  }
516  res = res + IntervalValue(idxLb, idxUb);
517  }
519  if (res.isBottom())
520  {
521  res = IntervalValue(0);
522  }
523  return res;
524 }
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
Definition: AccessPath.cpp:63
APOffset accumulateConstantOffset() const
Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
bool isConstantOffset() const
Return TRUE if this is a constant location set.
void meet_with(const IntervalValue &other)
Return a intersected IntervalValue.

◆ getFPToSIntValue()

IntervalValue SVFIR2AbsState::getFPToSIntValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 161 of file SVFIR2AbsState.cpp.

162 {
163  // IntervalValue are BoundedInt, so we can directly return the value
164  return getSExtValue(as, var);
165 }
IntervalValue getSExtValue(const AbstractState &es, const SVFVar *var)

◆ getFPToUIntValue()

IntervalValue SVFIR2AbsState::getFPToUIntValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 167 of file SVFIR2AbsState.cpp.

168 {
169  // IntervalValue are BoundedInt, so we can directly return the value
170  return getZExtValue(as, var);
171 }
IntervalValue getZExtValue(const AbstractState &es, const SVFVar *var)

◆ getFPTruncValue()

IntervalValue SVFIR2AbsState::getFPTruncValue ( const AbstractState es,
const SVFVar var,
const SVFType dstType 
)

Definition at line 236 of file SVFIR2AbsState.cpp.

237 {
238  // TODO: now we do not really handle fptrunc
239  return as[var->getId()].getInterval();
240 }
NodeID getId() const
Get ID.
Definition: GenericGraph.h:180

◆ getGepObjAddress()

AddressValue SVFIR2AbsState::getGepObjAddress ( AbstractState es,
u32_t  pointer,
APOffset  offset 
)

Return the field address given a pointer points to a struct object and an offset.

Definition at line 328 of file SVFIR2AbsState.cpp.

329 {
330  AbstractValue addrs = getAddrs(as, pointer);
331  AddressValue ret = AddressValue();
332  for (const auto &addr: addrs.getAddrs())
333  {
334  s64_t baseObj = getInternalID(addr);
335  assert(SVFUtil::isa<ObjVar>(_svfir->getGNode(baseObj)) && "Fail to get the base object address!");
336  NodeID gepObj = _svfir->getGepObjVar(baseObj, offset);
339  }
340  return ret;
341 }
buffer offset
Definition: cJSON.cpp:1113
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
Definition: AbstractState.h:84
AddressValue & getAddrs()
std::pair< AddressValue::AddrSet::iterator, bool > insert(u32_t id)
Definition: AddressValue.h:112
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:406
AbstractValue & getAddrs(AbstractState &es, u32_t id)
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
Definition: SVFIR.cpp:422
unsigned NodeID

◆ getInternalID()

static u32_t SVF::SVFIR2AbsState::getInternalID ( u32_t  idx)
inlinestatic

Return the internal index if idx is an address otherwise return the value of idx.

Definition at line 168 of file SVFIR2AbsState.h.

169  {
170  return AbstractState::getInternalID(idx);
171  }
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
Definition: AbstractState.h:96

◆ getRangeLimitFromType()

IntervalValue SVFIR2AbsState::getRangeLimitFromType ( const SVFType type)

Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128, 127].

This function, getRangeLimitFromType, calculates the lower and upper bounds of a numeric range for a given SVFType. It is used to determine the possible value range of integer types. If the type is an SVFIntegerType, it calculates the bounds based on the size and signedness of the type. The calculated bounds are returned as an IntervalValue representing the lower (lb) and upper (ub) limits of the range.

Parameters
typeThe SVFType for which to calculate the value range.
Returns
An IntervalValue representing the lower and upper bounds of the range.

Definition at line 49 of file SVFIR2AbsState.cpp.

50 {
51  if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
52  {
53  u32_t bits = type->getByteSize() * 8;
54  s64_t ub = 0;
55  s64_t lb = 0;
56  if (bits >= 32)
57  {
58  if (intType->isSigned())
59  {
60  ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
61  lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
62  }
63  else
64  {
65  ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
66  lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
67  }
68  }
69  else if (bits == 16)
70  {
71  if (intType->isSigned())
72  {
73  ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
74  lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
75  }
76  else
77  {
78  ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
79  lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
80  }
81  }
82  else if (bits == 8)
83  {
84  if (intType->isSigned())
85  {
86  ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
87  lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
88  }
89  else
90  {
91  ub = static_cast<s64_t>(std::numeric_limits<u_int8_t>::max());
92  lb = static_cast<s64_t>(std::numeric_limits<u_int8_t>::min());
93  }
94  }
95  return IntervalValue(lb, ub);
96  }
97  else if (SVFUtil::isa<SVFOtherType>(type))
98  {
99  // handle other type like float double, set s32_t as the range
100  s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
101  s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
102  return IntervalValue(lb, ub);
103  }
104  else
105  {
106  return IntervalValue::top();
107  // other types, return top interval
108  }
109 }
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
Definition: IntervalValue.h:94

◆ getRelEs()

RelExeState& SVF::SVFIR2AbsState::getRelEs ( )
inline

Definition at line 55 of file SVFIR2AbsState.h.

56  {
57  return _relEs;
58  }

◆ getSExtValue()

IntervalValue SVFIR2AbsState::getSExtValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 156 of file SVFIR2AbsState.cpp.

157 {
158  return as[var->getId()].getInterval();
159 }

◆ getSIntToFPValue()

IntervalValue SVFIR2AbsState::getSIntToFPValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 173 of file SVFIR2AbsState.cpp.

174 {
175  // IntervalValue are BoundedInt, so we can directly return the value
176  return getSExtValue(as, var);
177 }

◆ getTruncValue()

IntervalValue SVFIR2AbsState::getTruncValue ( const AbstractState es,
const SVFVar var,
const SVFType dstType 
)

Definition at line 185 of file SVFIR2AbsState.cpp.

186 {
187  const IntervalValue& itv = as[var->getId()].getInterval();
188  if(itv.isBottom()) return itv;
189  // get the value of ub and lb
190  s64_t int_lb = itv.lb().getIntNumeral();
191  s64_t int_ub = itv.ub().getIntNumeral();
192  // get dst type
193  u32_t dst_bits = dstType->getByteSize() * 8;
194  if (dst_bits == 8)
195  {
196  // get the signed value of ub and lb
197  int8_t s8_lb = static_cast<int8_t>(int_lb);
198  int8_t s8_ub = static_cast<int8_t>(int_ub);
199  if (s8_lb > s8_ub)
200  {
201  // return range of s8
202  return IntervalValue::top();
203  }
204  return IntervalValue(s8_lb, s8_ub);
205  }
206  else if (dst_bits == 16)
207  {
208  // get the signed value of ub and lb
209  s16_t s16_lb = static_cast<s16_t>(int_lb);
210  s16_t s16_ub = static_cast<s16_t>(int_ub);
211  if (s16_lb > s16_ub)
212  {
213  // return range of s16
214  return IntervalValue::top();
215  }
216  return IntervalValue(s16_lb, s16_ub);
217  }
218  else if (dst_bits == 32)
219  {
220  // get the signed value of ub and lb
221  s32_t s32_lb = static_cast<s32_t>(int_lb);
222  s32_t s32_ub = static_cast<s32_t>(int_ub);
223  if (s32_lb > s32_ub)
224  {
225  // return range of s32
226  return IntervalValue::top();
227  }
228  return IntervalValue(s32_lb, s32_ub);
229  }
230  else
231  {
232  assert(false && "cannot support dst int type other than u8/16/32");
233  }
234 }
signed short s16_t
Definition: GeneralType.h:53
signed s32_t
Definition: GeneralType.h:47

◆ getUIntToFPValue()

IntervalValue SVFIR2AbsState::getUIntToFPValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 179 of file SVFIR2AbsState.cpp.

180 {
181  // IntervalValue are BoundedInt, so we can directly return the value
182  return getZExtValue(as, var);
183 }

◆ getVirtualMemAddress()

static u32_t SVF::SVFIR2AbsState::getVirtualMemAddress ( u32_t  idx)
inlinestatic

The physical address starts with 0x7f...... + idx.

Definition at line 174 of file SVFIR2AbsState.h.

175  {
177  }

◆ getZExtValue()

IntervalValue SVFIR2AbsState::getZExtValue ( const AbstractState es,
const SVFVar var 
)

Definition at line 111 of file SVFIR2AbsState.cpp.

112 {
113  const SVFType* type = var->getType();
114  if (SVFUtil::isa<SVFIntegerType>(type))
115  {
116  u32_t bits = type->getByteSize() * 8;
117  if (as[var->getId()].getInterval().is_numeral())
118  {
119  if (bits == 8)
120  {
121  int8_t signed_i8_value = as[var->getId()].getInterval().getIntNumeral();
122  u32_t unsigned_value = static_cast<uint8_t>(signed_i8_value);
123  return IntervalValue(unsigned_value, unsigned_value);
124  }
125  else if (bits == 16)
126  {
127  s16_t signed_i16_value = as[var->getId()].getInterval().getIntNumeral();
128  u32_t unsigned_value = static_cast<u16_t>(signed_i16_value);
129  return IntervalValue(unsigned_value, unsigned_value);
130  }
131  else if (bits == 32)
132  {
133  s32_t signed_i32_value = as[var->getId()].getInterval().getIntNumeral();
134  u32_t unsigned_value = static_cast<u32_t>(signed_i32_value);
135  return IntervalValue(unsigned_value, unsigned_value);
136  }
137  else if (bits == 64)
138  {
139  s64_t signed_i64_value = as[var->getId()].getInterval().getIntNumeral();
140  return IntervalValue((s64_t)signed_i64_value, (s64_t)signed_i64_value);
141  // we only support i64 at most
142  }
143  else
144  {
145  assert(false && "cannot support int type other than u8/16/32/64");
146  }
147  }
148  else
149  {
150  return IntervalValue::top(); // TODO: may have better solution
151  }
152  }
153  return IntervalValue::top(); // TODO: may have better solution
154 }
virtual const SVFType * getType() const
Return type of the value.
Definition: SVFVariables.h:107
unsigned short u16_t
Definition: GeneralType.h:52

◆ handleAddr()

void SVFIR2AbsState::handleAddr ( AbstractState es,
const AddrStmt addr 
)

Definition at line 563 of file SVFIR2AbsState.cpp.

564 {
565  initObjVar(as, SVFUtil::cast<ObjVar>(addr->getRHSVar()));
566  if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy)
567  as[addr->getRHSVarID()].getInterval().meet_with(getRangeLimitFromType(addr->getRHSVar()->getType()));
568  as[addr->getLHSVarID()] = as[addr->getRHSVarID()];
569 }
NodeID getRHSVarID() const
NodeID getLHSVarID() const
SVFVar * getRHSVar() const
IntervalValue getRangeLimitFromType(const SVFType *type)
Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128,...
void initObjVar(AbstractState &as, const ObjVar *var)
Init ObjVar.
@ SVFIntegerTy
Definition: SVFType.h:169
GNodeK getKind() const
Definition: SVFType.h:213

◆ handleBinary()

void SVFIR2AbsState::handleBinary ( AbstractState es,
const BinaryOPStmt binary 
)

Definition at line 572 of file SVFIR2AbsState.cpp.

573 {
574  u32_t op0 = binary->getOpVarID(0);
575  u32_t op1 = binary->getOpVarID(1);
576  u32_t res = binary->getResID();
577  if (!inVarToValTable(as, op0)) as[op0] = IntervalValue::top();
578  if (!inVarToValTable(as, op1)) as[op1] = IntervalValue::top();
579  IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
580  IntervalValue resVal;
581  switch (binary->getOpcode())
582  {
583  case BinaryOPStmt::Add:
584  case BinaryOPStmt::FAdd:
585  resVal = (lhs + rhs);
586  break;
587  case BinaryOPStmt::Sub:
588  case BinaryOPStmt::FSub:
589  resVal = (lhs - rhs);
590  break;
591  case BinaryOPStmt::Mul:
592  case BinaryOPStmt::FMul:
593  resVal = (lhs * rhs);
594  break;
595  case BinaryOPStmt::SDiv:
596  case BinaryOPStmt::FDiv:
597  case BinaryOPStmt::UDiv:
598  resVal = (lhs / rhs);
599  break;
600  case BinaryOPStmt::SRem:
601  case BinaryOPStmt::FRem:
602  case BinaryOPStmt::URem:
603  resVal = (lhs % rhs);
604  break;
605  case BinaryOPStmt::Xor:
606  resVal = (lhs ^ rhs);
607  break;
608  case BinaryOPStmt::And:
609  resVal = (lhs & rhs);
610  break;
611  case BinaryOPStmt::Or:
612  resVal = (lhs | rhs);
613  break;
614  case BinaryOPStmt::AShr:
615  resVal = (lhs >> rhs);
616  break;
617  case BinaryOPStmt::Shl:
618  resVal = (lhs << rhs);
619  break;
620  case BinaryOPStmt::LShr:
621  resVal = (lhs >> rhs);
622  break;
623  default:
624  assert(false && "undefined binary: ");
625  }
626  as[res] = resVal;
627 }
u32_t getOpcode() const
NodeID getOpVarID(u32_t pos) const
NodeID getResID() const
bool inVarToValTable(const AbstractState &es, u32_t id) const
whether the variable is in varToVal table

◆ handleCall()

void SVFIR2AbsState::handleCall ( AbstractState es,
const CallPE callPE 
)

Definition at line 945 of file SVFIR2AbsState.cpp.

946 {
947  NodeID lhs = callPE->getLHSVarID();
948  NodeID rhs = callPE->getRHSVarID();
949  as[lhs] = as[rhs];
950 }

◆ handleCmp()

void SVFIR2AbsState::handleCmp ( AbstractState es,
const CmpStmt cmp 
)

Definition at line 629 of file SVFIR2AbsState.cpp.

630 {
631  u32_t op0 = cmp->getOpVarID(0);
632  u32_t op1 = cmp->getOpVarID(1);
633  if (!inVarToValTable(as, op0)) as[op0] = IntervalValue::top();
634  if (!inVarToValTable(as, op1)) as[op1] = IntervalValue::top();
635  u32_t res = cmp->getResID();
636  if (inVarToValTable(as, op0) && inVarToValTable(as, op1))
637  {
638  IntervalValue resVal;
639  IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
640  //AbstractValue
641  auto predicate = cmp->getPredicate();
642  switch (predicate)
643  {
644  case CmpStmt::ICMP_EQ:
645  case CmpStmt::FCMP_OEQ:
646  case CmpStmt::FCMP_UEQ:
647  resVal = (lhs == rhs);
648  // resVal = (lhs.getInterval() == rhs.getInterval());
649  break;
650  case CmpStmt::ICMP_NE:
651  case CmpStmt::FCMP_ONE:
652  case CmpStmt::FCMP_UNE:
653  resVal = (lhs != rhs);
654  break;
655  case CmpStmt::ICMP_UGT:
656  case CmpStmt::ICMP_SGT:
657  case CmpStmt::FCMP_OGT:
658  case CmpStmt::FCMP_UGT:
659  resVal = (lhs > rhs);
660  break;
661  case CmpStmt::ICMP_UGE:
662  case CmpStmt::ICMP_SGE:
663  case CmpStmt::FCMP_OGE:
664  case CmpStmt::FCMP_UGE:
665  resVal = (lhs >= rhs);
666  break;
667  case CmpStmt::ICMP_ULT:
668  case CmpStmt::ICMP_SLT:
669  case CmpStmt::FCMP_OLT:
670  case CmpStmt::FCMP_ULT:
671  resVal = (lhs < rhs);
672  break;
673  case CmpStmt::ICMP_ULE:
674  case CmpStmt::ICMP_SLE:
675  case CmpStmt::FCMP_OLE:
676  case CmpStmt::FCMP_ULE:
677  resVal = (lhs <= rhs);
678  break;
679  case CmpStmt::FCMP_FALSE:
680  resVal = IntervalValue(0, 0);
681  break;
682  case CmpStmt::FCMP_TRUE:
683  resVal = IntervalValue(1, 1);
684  break;
685  default:
686  {
687  assert(false && "undefined compare: ");
688  }
689  }
690  as[res] = resVal;
691  }
692  else if (inVarToAddrsTable(as, op0) && inVarToAddrsTable(as, op1))
693  {
694  IntervalValue resVal;
695  AbstractValue &lhs = getAddrs(as, op0), &rhs = getAddrs(as, op1);
696  auto predicate = cmp->getPredicate();
697  switch (predicate)
698  {
699  case CmpStmt::ICMP_EQ:
700  case CmpStmt::FCMP_OEQ:
701  case CmpStmt::FCMP_UEQ:
702  {
703  if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
704  {
705  resVal = IntervalValue(0, 1);
706  }
707  else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
708  {
709  resVal = IntervalValue(1, 1);
710  }
711  else
712  {
713  resVal = IntervalValue(0, 0);
714  }
715  break;
716  }
717  case CmpStmt::ICMP_NE:
718  case CmpStmt::FCMP_ONE:
719  case CmpStmt::FCMP_UNE:
720  {
721  if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
722  {
723  resVal = IntervalValue(0, 1);
724  }
725  else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
726  {
727  resVal = IntervalValue(0, 0);
728  }
729  else
730  {
731  resVal = IntervalValue(1, 1);
732  }
733  break;
734  }
735  case CmpStmt::ICMP_UGT:
736  case CmpStmt::ICMP_SGT:
737  case CmpStmt::FCMP_OGT:
738  case CmpStmt::FCMP_UGT:
739  {
740  if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1)
741  {
742  resVal = IntervalValue(*lhs.getAddrs().begin() > *rhs.getAddrs().begin());
743  }
744  else
745  {
746  resVal = IntervalValue(0, 1);
747  }
748  break;
749  }
750  case CmpStmt::ICMP_UGE:
751  case CmpStmt::ICMP_SGE:
752  case CmpStmt::FCMP_OGE:
753  case CmpStmt::FCMP_UGE:
754  {
755  if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1)
756  {
757  resVal = IntervalValue(*lhs.getAddrs().begin() >= *rhs.getAddrs().begin());
758  }
759  else
760  {
761  resVal = IntervalValue(0, 1);
762  }
763  break;
764  }
765  case CmpStmt::ICMP_ULT:
766  case CmpStmt::ICMP_SLT:
767  case CmpStmt::FCMP_OLT:
768  case CmpStmt::FCMP_ULT:
769  {
770  if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1)
771  {
772  resVal = IntervalValue(*lhs.getAddrs().begin() < *rhs.getAddrs().begin());
773  }
774  else
775  {
776  resVal = IntervalValue(0, 1);
777  }
778  break;
779  }
780  case CmpStmt::ICMP_ULE:
781  case CmpStmt::ICMP_SLE:
782  case CmpStmt::FCMP_OLE:
783  case CmpStmt::FCMP_ULE:
784  {
785  if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1)
786  {
787  resVal = IntervalValue(*lhs.getAddrs().begin() <= *rhs.getAddrs().begin());
788  }
789  else
790  {
791  resVal = IntervalValue(0, 1);
792  }
793  break;
794  }
795  case CmpStmt::FCMP_FALSE:
796  resVal = IntervalValue(0, 0);
797  break;
798  case CmpStmt::FCMP_TRUE:
799  resVal = IntervalValue(1, 1);
800  break;
801  default:
802  {
803  assert(false && "undefined compare: ");
804  }
805  }
806  as[res] = resVal;
807  }
808 }
bool hasIntersect(const AddressValue &other)
Definition: AddressValue.h:164
bool empty() const
Definition: AddressValue.h:102
u32_t size() const
Definition: AddressValue.h:107
AddrSet::const_iterator begin() const
Definition: AddressValue.h:92
u32_t getPredicate() const
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ ICMP_NE
not equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_ULT
unsigned less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal

◆ handleCopy()

void SVFIR2AbsState::handleCopy ( AbstractState es,
const CopyStmt copy 
)

Definition at line 833 of file SVFIR2AbsState.cpp.

834 {
835  u32_t lhs = copy->getLHSVarID();
836  u32_t rhs = copy->getRHSVarID();
837 
838  if (copy->getCopyKind() == CopyStmt::COPYVAL)
839  {
840  as[lhs] = as[rhs];
841  }
842  else if (copy->getCopyKind() == CopyStmt::ZEXT)
843  {
844  as[lhs] = getZExtValue(as, copy->getRHSVar());
845  }
846  else if (copy->getCopyKind() == CopyStmt::SEXT)
847  {
848  as[lhs] = getSExtValue(as, copy->getRHSVar());
849  }
850  else if (copy->getCopyKind() == CopyStmt::FPTOSI)
851  {
852  as[lhs] = getFPToSIntValue(as, copy->getRHSVar());
853  }
854  else if (copy->getCopyKind() == CopyStmt::FPTOUI)
855  {
856  as[lhs] = getFPToUIntValue(as, copy->getRHSVar());
857  }
858  else if (copy->getCopyKind() == CopyStmt::SITOFP)
859  {
860  as[lhs] = getSIntToFPValue(as, copy->getRHSVar());
861  }
862  else if (copy->getCopyKind() == CopyStmt::UITOFP)
863  {
864  as[lhs] = getUIntToFPValue(as, copy->getRHSVar());
865  }
866  else if (copy->getCopyKind() == CopyStmt::TRUNC)
867  {
868  as[lhs] = getTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType());
869  }
870  else if (copy->getCopyKind() == CopyStmt::FPTRUNC)
871  {
872  as[lhs] = getFPTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType());
873  }
874  else if (copy->getCopyKind() == CopyStmt::INTTOPTR)
875  {
876  //insert nullptr
877  }
878  else if (copy->getCopyKind() == CopyStmt::PTRTOINT)
879  {
880  as[lhs] = IntervalValue::top();
881  }
882  else if (copy->getCopyKind() == CopyStmt::BITCAST)
883  {
884  if (as[rhs].isAddr())
885  {
886  as[lhs] = as[rhs];
887  }
888  else
889  {
890  // do nothing
891  }
892  }
893  else
894  {
895  assert(false && "undefined copy kind");
896  abort();
897  }
898 }
copy
Definition: cJSON.cpp:414
IntervalValue getFPTruncValue(const AbstractState &es, const SVFVar *var, const SVFType *dstType)
IntervalValue getFPToUIntValue(const AbstractState &es, const SVFVar *var)
IntervalValue getUIntToFPValue(const AbstractState &es, const SVFVar *var)
IntervalValue getFPToSIntValue(const AbstractState &es, const SVFVar *var)
IntervalValue getSIntToFPValue(const AbstractState &es, const SVFVar *var)
IntervalValue getTruncValue(const AbstractState &es, const SVFVar *var, const SVFType *dstType)

◆ handleGep()

void SVFIR2AbsState::handleGep ( AbstractState es,
const GepStmt gep 
)

Definition at line 900 of file SVFIR2AbsState.cpp.

901 {
902  u32_t rhs = gep->getRHSVarID();
903  u32_t lhs = gep->getLHSVarID();
904  IntervalValue offsetPair = getElementIndex(as, gep);
905  AbstractValue gepAddrs;
906  APOffset lb = offsetPair.lb().getIntNumeral() < Options::MaxFieldLimit()?
907  offsetPair.lb().getIntNumeral(): Options::MaxFieldLimit();
908  APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit()?
909  offsetPair.ub().getIntNumeral(): Options::MaxFieldLimit();
910  for (APOffset i = lb; i <= ub; i++)
911  gepAddrs.join_with(getGepObjAddress(as, rhs, i));
912  as[lhs] = gepAddrs;
913 }
void join_with(const AbstractValue &other)
AddressValue getGepObjAddress(AbstractState &es, u32_t pointer, APOffset offset)
Return the field address given a pointer points to a struct object and an offset.
IntervalValue getElementIndex(const AbstractState &es, const GepStmt *gep)
Return the offset expression of a GepStmt.

◆ handleLoad()

void SVFIR2AbsState::handleLoad ( AbstractState es,
const LoadStmt load 
)

Definition at line 810 of file SVFIR2AbsState.cpp.

811 {
812  u32_t rhs = load->getRHSVarID();
813  u32_t lhs = load->getLHSVarID();
814  AbstractValue &addrs = as[rhs];
815  AbstractValue rhsVal; // interval::bottom Address::bottom
816  // AbstractValue absRhs
817  for (const auto &addr: addrs.getAddrs())
818  rhsVal.join_with(as.load(addr));
819  as[lhs] = rhsVal;
820 }

◆ handlePhi()

void SVFIR2AbsState::handlePhi ( AbstractState es,
const PhiStmt phi 
)

Definition at line 932 of file SVFIR2AbsState.cpp.

933 {
934  u32_t res = phi->getResID();
935  AbstractValue rhs;
936  for (u32_t i = 0; i < phi->getOpVarNum(); i++)
937  {
938  NodeID curId = phi->getOpVarID(i);
939  rhs.join_with(as[curId]);
940  }
941  as[res] = rhs;
942 }
u32_t getOpVarNum() const

◆ handleRet()

void SVFIR2AbsState::handleRet ( AbstractState es,
const RetPE retPE 
)

Definition at line 952 of file SVFIR2AbsState.cpp.

953 {
954  NodeID lhs = retPE->getLHSVarID();
955  NodeID rhs = retPE->getRHSVarID();
956  as[lhs] = as[rhs];
957 }

◆ handleSelect()

void SVFIR2AbsState::handleSelect ( AbstractState es,
const SelectStmt select 
)

Definition at line 915 of file SVFIR2AbsState.cpp.

916 {
917  u32_t res = select->getResID();
918  u32_t tval = select->getTrueValue()->getId();
919  u32_t fval = select->getFalseValue()->getId();
920  u32_t cond = select->getCondition()->getId();
921  if (as[cond].getInterval().is_numeral())
922  {
923  as[res] = as[cond].getInterval().is_zero() ? as[fval] : as[tval];
924  }
925  else
926  {
927  as[res] = as[tval];
928  as[res].join_with(as[fval]);
929  }
930 }
const SVFVar * getTrueValue() const
const SVFVar * getCondition() const
const SVFVar * getFalseValue() const

◆ handleStore()

void SVFIR2AbsState::handleStore ( AbstractState es,
const StoreStmt store 
)

Definition at line 822 of file SVFIR2AbsState.cpp.

823 {
824  u32_t rhs = store->getRHSVarID();
825  u32_t lhs = store->getLHSVarID();
826 
827  for (const auto &addr: as[lhs].getAddrs())
828  {
829  as.store(addr, as[rhs]);
830  }
831 }

◆ inAddrTable()

bool SVF::SVFIR2AbsState::inAddrTable ( const AbstractState es,
u32_t  id 
) const
inline

Definition at line 115 of file SVFIR2AbsState.h.

116  {
117  return es.inAddrToValTable(id) || es.inAddrToAddrsTable(id);
118  }

◆ initObjVar()

void SVFIR2AbsState::initObjVar ( AbstractState as,
const ObjVar var 
)

Init ObjVar.

constant data

Definition at line 527 of file SVFIR2AbsState.cpp.

528 {
529  NodeID varId = var->getId();
530  if (var->hasValue())
531  {
532  const MemObj *obj = var->getMemObj();
534  if (obj->isConstDataOrConstGlobal() || obj->isConstantArray() || obj->isConstantStruct())
535  {
536  if (const SVFConstantInt *consInt = SVFUtil::dyn_cast<SVFConstantInt>(obj->getValue()))
537  {
538  s64_t numeral = consInt->getSExtValue();
539  as[varId] = IntervalValue(numeral, numeral);
540  }
541  else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast<SVFConstantFP>(obj->getValue()))
542  as[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue());
543  else if (SVFUtil::isa<SVFConstantNullPtr>(obj->getValue()))
544  as[varId] = IntervalValue(0, 0);
545  else if (SVFUtil::isa<SVFGlobalValue>(obj->getValue()))
546  {
547  as[varId] = AddressValue(getVirtualMemAddress(varId));
548  }
549 
550  else if (obj->isConstantArray() || obj->isConstantStruct())
551  as[varId] = IntervalValue::top();
552  else
553  as[varId] = IntervalValue::top();
554  }
555  else
556  as[varId] = AddressValue(getVirtualMemAddress(varId));
557  }
558  else
559  as[varId] = AddressValue(getVirtualMemAddress(varId));
560 }
bool isConstantStruct() const
bool isConstDataOrConstGlobal() const
const SVFValue * getValue() const
Get the reference value to this object.
bool isConstantArray() const
const MemObj * getMemObj() const
Return memory object.
Definition: SVFVariables.h:353
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
bool hasValue() const
Definition: SVFVariables.h:112

◆ inLocToAddrsTable()

bool SVF::SVFIR2AbsState::inLocToAddrsTable ( const AbstractState es,
u32_t  id 
) const
inline

whether the memory address stores memory addresses

Definition at line 140 of file SVFIR2AbsState.h.

141  {
142  return es.inAddrToAddrsTable(id);
143  }

◆ inLocToValTable()

bool SVF::SVFIR2AbsState::inLocToValTable ( const AbstractState es,
u32_t  id 
) const
inline

whether the memory address stores a interval value

Definition at line 134 of file SVFIR2AbsState.h.

135  {
136  return es.inAddrToValTable(id);
137  }

◆ inVarTable()

bool SVF::SVFIR2AbsState::inVarTable ( const AbstractState es,
u32_t  id 
) const
inline

Definition at line 110 of file SVFIR2AbsState.h.

111  {
112  return es.inVarToValTable(id) || es.inVarToAddrsTable(id);
113  }

◆ inVarToAddrsTable()

bool SVF::SVFIR2AbsState::inVarToAddrsTable ( const AbstractState es,
u32_t  id 
) const
inline

whether the variable is in varToAddrs table

Definition at line 127 of file SVFIR2AbsState.h.

128  {
129  return es.inVarToAddrsTable(id);
130  }

◆ inVarToValTable()

bool SVF::SVFIR2AbsState::inVarToValTable ( const AbstractState es,
u32_t  id 
) const
inline

whether the variable is in varToVal table

Definition at line 121 of file SVFIR2AbsState.h.

122  {
123  return es.inVarToValTable(id);
124  }

◆ isVirtualMemAddress()

static bool SVF::SVFIR2AbsState::isVirtualMemAddress ( u32_t  val)
inlinestatic

Check bit value of val start with 0x7F000000, filter by 0xFF000000.

Definition at line 180 of file SVFIR2AbsState.h.

181  {
183  }
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
Definition: AbstractState.h:90

◆ narrowAddrs()

void SVFIR2AbsState::narrowAddrs ( AbstractState es,
AbstractState lhs,
const AbstractState rhs 
)

Definition at line 288 of file SVFIR2AbsState.cpp.

289 {
290  for (const auto &rhsItem: rhs._varToAbsVal)
291  {
292  auto lhsIter = lhs._varToAbsVal.find(rhsItem.first);
293  if (lhsIter != lhs._varToAbsVal.end())
294  {
295  if (lhsIter->second.isAddr())
296  {
297  for (const auto &addr: lhsIter->second.getAddrs())
298  {
299  if (!rhsItem.second.getAddrs().contains(addr))
300  {
301  lhsIter->second = rhsItem.second;
302  break;
303  }
304  }
305  }
306  }
307  }
308  for (const auto &rhsItem: rhs._addrToAbsVal)
309  {
310  auto lhsIter = lhs._addrToAbsVal.find(rhsItem.first);
311  if (lhsIter != lhs._addrToAbsVal.end())
312  {
313  if (lhsIter->second.isAddr())
314  {
315  for (const auto& addr : lhsIter->second.getAddrs())
316  {
317  if (!rhsItem.second.getAddrs().contains(addr))
318  {
319  lhsIter->second = rhsItem.second;
320  break;
321  }
322  }
323  }
324  }
325  }
326 }
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.

◆ setRelEs()

void SVF::SVFIR2AbsState::setRelEs ( const RelExeState relEs)
inline

Definition at line 50 of file SVFIR2AbsState.h.

51  {
52  _relEs = relEs;
53  }

◆ widenAddrs()

void SVFIR2AbsState::widenAddrs ( AbstractState es,
AbstractState lhs,
const AbstractState rhs 
)

Definition at line 242 of file SVFIR2AbsState.cpp.

243 {
244  for (const auto &rhsItem: rhs._varToAbsVal)
245  {
246  auto lhsIter = lhs._varToAbsVal.find(rhsItem.first);
247  if (lhsIter != lhs._varToAbsVal.end())
248  {
249  if (rhsItem.second.isAddr())
250  {
251  for (const auto &addr: rhsItem.second.getAddrs())
252  {
253  if (!lhsIter->second.getAddrs().contains(addr))
254  {
255  for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++)
256  {
257  lhsIter->second.join_with(getGepObjAddress(as, getInternalID(addr), i));
258  }
259  }
260  }
261  }
262  }
263  }
264  for (const auto &rhsItem: rhs._addrToAbsVal)
265  {
266  auto lhsIter = lhs._addrToAbsVal.find(rhsItem.first);
267  if (lhsIter != lhs._addrToAbsVal.end())
268  {
269  if (rhsItem.second.isAddr())
270  {
271  for (const auto& addr : rhsItem.second.getAddrs())
272  {
273  if (!lhsIter->second.getAddrs().contains(addr))
274  {
275  for (s32_t i = 0; i < (s32_t)Options::MaxFieldLimit();
276  i++)
277  {
278  lhsIter->second.join_with(
279  getGepObjAddress(as, getInternalID(addr), i));
280  }
281  }
282  }
283  }
284  }
285  }
286 }

Member Data Documentation

◆ _relEs

RelExeState SVF::SVFIR2AbsState::_relEs
private

Definition at line 187 of file SVFIR2AbsState.h.

◆ _svfir

SVFIR* SVF::SVFIR2AbsState::_svfir
private

Definition at line 186 of file SVFIR2AbsState.h.

◆ globalNulladdrs

AbstractValue SVF::SVFIR2AbsState::globalNulladdrs = AddressValue()
static

Definition at line 45 of file SVFIR2AbsState.h.


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