Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
SVF::AbstractStateManager Class Reference

#include <AbstractStateManager.h>

Public Member Functions

 AbstractStateManager (SVFIR *svfir, AndersenWaveDiff *pta)
 
 ~AbstractStateManager ()
 
const AbstractValuegetAbstractValue (const ValVar *var, const ICFGNode *node)
 
const AbstractValuegetAbstractValue (const ObjVar *var, const ICFGNode *node)
 Read an address-taken variable's content via virtual-address load.
 
const AbstractValuegetAbstractValue (const SVFVar *var, const ICFGNode *node)
 Dispatch to ValVar or ObjVar overload (checks ObjVar first due to inheritance).
 
bool hasAbstractValue (const ValVar *var, const ICFGNode *node) const
 
bool hasAbstractValue (const ObjVar *var, const ICFGNode *node) const
 Check whether an ObjVar has a stored value at node.
 
bool hasAbstractValue (const SVFVar *var, const ICFGNode *node) const
 Dispatch to ValVar or ObjVar overload.
 
void updateAbstractValue (const ValVar *var, const AbstractValue &val, const ICFGNode *node)
 Write a top-level variable's abstract value into abstractTrace[node].
 
void updateAbstractValue (const ObjVar *var, const AbstractValue &val, const ICFGNode *node)
 Write an address-taken variable's content via virtual-address store.
 
void updateAbstractValue (const SVFVar *var, const AbstractValue &val, const ICFGNode *node)
 Dispatch to ValVar or ObjVar overload.
 
AbstractStategetAbstractState (const ICFGNode *node)
 Retrieve the abstract state for a given ICFG node. Asserts if absent.
 
void updateAbstractState (const ICFGNode *node, const AbstractState &state)
 
bool hasAbstractState (const ICFGNode *node)
 Check if an abstract state exists for a given ICFG node.
 
void getAbstractState (const Set< const ValVar * > &vars, AbstractState &result, const ICFGNode *node)
 Retrieve abstract state filtered to specific variable sets.
 
void getAbstractState (const Set< const ObjVar * > &vars, AbstractState &result, const ICFGNode *node)
 
void getAbstractState (const Set< const SVFVar * > &vars, AbstractState &result, const ICFGNode *node)
 
IntervalValue getGepElementIndex (const GepStmt *gep)
 Compute the flattened element index for a GepStmt.
 
IntervalValue getGepByteOffset (const GepStmt *gep)
 Compute the byte offset for a GepStmt.
 
AddressValue getGepObjAddrs (const ValVar *pointer, IntervalValue offset)
 Compute GEP object addresses for a pointer at a given element offset.
 
AbstractValue loadValue (const ValVar *pointer, const ICFGNode *node)
 
void storeValue (const ValVar *pointer, const AbstractValue &val, const ICFGNode *node)
 
const SVFTypegetPointeeElement (const ObjVar *var, const ICFGNode *node)
 Get the pointee type for a pointer variable.
 
u32_t getAllocaInstByteSize (const AddrStmt *addr)
 Get the byte size of a stack allocation.
 
Map< const ICFGNode *, AbstractState > & getTrace ()
 
AbstractStateoperator[] (const ICFGNode *node)
 
Set< const ICFGNode * > getUseSitesOfObjVar (const ObjVar *obj, const ICFGNode *node) const
 Given an ObjVar and its use-site ICFGNode, find all downstream use-site ICFGNodes.
 
Set< const ICFGNode * > getUseSitesOfValVar (const ValVar *var) const
 Given a ValVar, find all use-site ICFGNodes.
 
const ICFGNodegetDefSiteOfValVar (const ValVar *var) const
 Given a ValVar, find its definition-site ICFGNode.
 
const ICFGNodegetDefSiteOfObjVar (const ObjVar *obj, const ICFGNode *node) const
 Given an ObjVar and its use-site ICFGNode, find the definition-site ICFGNode.
 

Private Attributes

SVFIRsvfir
 
SVFGsvfg
 
Map< const ICFGNode *, AbstractStateabstractTrace
 

Detailed Description

Manages abstract states across ICFG nodes and provides a unified API for reading/writing abstract values. Encapsulates the dense vs. semi-sparse lookup strategy so that all consumers (updateStateOnXxx, AEDetector, AbsExtAPI) are sparsity-agnostic.

Two sparsity-dependent behaviors live here:

  1. getAbstractValue(ValVar*): dense reads from current node's state; semi-sparse pulls from def-site.
  2. joinWith (inside AbstractState): dense merges all variables; semi-sparse skips ValVar merge.

Definition at line 48 of file AbstractStateManager.h.

Constructor & Destructor Documentation

◆ AbstractStateManager()

AbstractStateManager::AbstractStateManager ( SVFIR svfir,
AndersenWaveDiff pta 
)

Definition at line 35 of file AbstractStateManager.cpp.

36 : svfir(svfir), svfg(nullptr)
37{
39 {
40 SVFGBuilder memSSA(true);
41 svfg = memSSA.buildFullSVFG(pta);
42 }
43}
static const OptionMap< u32_t > AESparsity
Definition Options.h:243

◆ ~AbstractStateManager()

AbstractStateManager::~AbstractStateManager ( )

Definition at line 45 of file AbstractStateManager.cpp.

46{
47 delete svfg;
48}

Member Function Documentation

◆ getAbstractState() [1/4]

AbstractState & AbstractStateManager::getAbstractState ( const ICFGNode node)

Retrieve the abstract state for a given ICFG node. Asserts if absent.

Definition at line 54 of file AbstractStateManager.cpp.

55{
56 if (abstractTrace.count(node) == 0)
57 {
58 assert(false && "No preAbsTrace for this node");
59 abort();
60 }
61 return abstractTrace[node];
62}
Map< const ICFGNode *, AbstractState > abstractTrace
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ getAbstractState() [2/4]

void AbstractStateManager::getAbstractState ( const Set< const ObjVar * > &  vars,
AbstractState result,
const ICFGNode node 
)

Definition at line 290 of file AbstractStateManager.cpp.

291{
293 for (const ObjVar* var : vars)
294 {
296 result.store(addr, as.load(addr));
297 }
298}
unsigned u32_t
Definition CommandLine.h:18
AbstractState & getAbstractState(const ICFGNode *node)
Retrieve the abstract state for a given ICFG node. Asserts if absent.
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.

◆ getAbstractState() [3/4]

void AbstractStateManager::getAbstractState ( const Set< const SVFVar * > &  vars,
AbstractState result,
const ICFGNode node 
)

Definition at line 300 of file AbstractStateManager.cpp.

301{
303 for (const SVFVar* var : vars)
304 {
305 if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
306 {
307 u32_t id = valVar->getId();
308 result[id] = as[id];
309 }
310 else if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
311 {
313 result.store(addr, as.load(addr));
314 }
315 }
316}

◆ getAbstractState() [4/4]

void AbstractStateManager::getAbstractState ( const Set< const ValVar * > &  vars,
AbstractState result,
const ICFGNode node 
)

Retrieve abstract state filtered to specific variable sets.

Definition at line 280 of file AbstractStateManager.cpp.

281{
283 for (const ValVar* var : vars)
284 {
285 u32_t id = var->getId();
286 result[id] = as[id];
287 }
288}

◆ getAbstractValue() [1/3]

const AbstractValue & AbstractStateManager::getAbstractValue ( const ObjVar var,
const ICFGNode node 
)

Read an address-taken variable's content via virtual-address load.

Definition at line 158 of file AbstractStateManager.cpp.

159{
162 return as.load(addr);
163}

◆ getAbstractValue() [2/3]

const AbstractValue & AbstractStateManager::getAbstractValue ( const SVFVar var,
const ICFGNode node 
)

Dispatch to ValVar or ObjVar overload (checks ObjVar first due to inheritance).

Definition at line 165 of file AbstractStateManager.cpp.

166{
167 // Check ObjVar first since ObjVar inherits from ValVar
168 if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
169 return getAbstractValue(objVar, node);
170 if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
171 return getAbstractValue(valVar, node);
172 assert(false && "Unknown SVFVar kind");
173 abort();
174}
const AbstractValue & getAbstractValue(const ValVar *var, const ICFGNode *node)

◆ getAbstractValue() [3/3]

const AbstractValue & AbstractStateManager::getAbstractValue ( const ValVar var,
const ICFGNode node 
)

Read a top-level variable's abstract value. Dense: reads from abstractTrace[node]. Semi-sparse: checks current state first, then pulls from def-site. Returns top if absent everywhere.

Definition at line 87 of file AbstractStateManager.cpp.

88{
89 u32_t id = var->getId();
91
92 // Constants: store into current node's state and return
94 if (const ConstIntValVar* constInt = SVFUtil::dyn_cast<ConstIntValVar>(var))
95 {
96 as[id] = IntervalValue(constInt->getSExtValue(), constInt->getSExtValue());
97 return as[id];
98 }
99 if (const ConstFPValVar* constFP = SVFUtil::dyn_cast<ConstFPValVar>(var))
100 {
101 as[id] = IntervalValue(constFP->getFPValue(), constFP->getFPValue());
102 return as[id];
103 }
104 if (SVFUtil::isa<ConstNullPtrValVar>(var))
105 {
106 as[id] = AddressValue();
107 return as[id];
108 }
109 if (SVFUtil::isa<ConstDataValVar>(var))
110 {
111 as[id] = IntervalValue::top();
112 return as[id];
113 }
114
115 // Dense mode: try current node's state first.
116 // If absent, fall through to the def-site lookup below — matching
117 // upstream behaviour where getAbstractValue always reads from the
118 // def-site. Returning top or bottom here would be wrong: top loses
119 // concrete values like NULL addresses; bottom misjudges branch
120 // feasibility for uninitialised variables like argc.
121 if (!semiSparse)
122 {
123 if (as.inVarToValTable(id) || as.inVarToAddrsTable(id))
124 return as[id];
125 }
126
127 // Semi-sparse mode: pull from def-site first, then check current state
128 const ICFGNode* defNode = var->getICFGNode();
130 {
132 if (varMap.count(id))
133 return getAbstractState(defNode)[id];
134 }
135
136 // Fallback for call-result ValVars: their getICFGNode() returns
137 // CallICFGNode but the value is written by RetPE at RetICFGNode.
138 if (const CallICFGNode* callNode =
139 defNode ? SVFUtil::dyn_cast<CallICFGNode>(defNode) : nullptr)
140 {
141 const RetICFGNode* retNode = callNode->getRetICFGNode();
143 {
145 if (retMap.count(id))
146 return getAbstractState(retNode)[id];
147 }
148 }
149
150 as[id] = IntervalValue::top();
151 return as[id];
152}
bool hasAbstractState(const ICFGNode *node)
Check if an abstract state exists for a given ICFG node.
const VarToAbsValMap & getVarToVal() const
get var2val map
static IntervalValue top()
Create the IntervalValue [-inf, +inf].

◆ getAllocaInstByteSize()

u32_t AbstractStateManager::getAllocaInstByteSize ( const AddrStmt addr)

Get the byte size of a stack allocation.

Definition at line 504 of file AbstractStateManager.cpp.

505{
506 const ICFGNode* node = addr->getICFGNode();
507 if (const ObjVar* objvar = SVFUtil::dyn_cast<ObjVar>(addr->getRHSVar()))
508 {
510 {
511 return svfir->getBaseObject(objvar->getId())->getByteSizeOfObj();
512 }
513 else
514 {
515 const std::vector<SVFVar*>& sizes = addr->getArrSize();
516 u32_t elementSize = 1;
517 u64_t res = elementSize;
518 for (const SVFVar* value : sizes)
519 {
520 const AbstractValue& sizeVal = getAbstractValue(value, node);
521 IntervalValue itv = sizeVal.getInterval();
522 if (itv.isBottom())
524 res = res * itv.ub().getIntNumeral() > Options::MaxFieldLimit()
525 ? Options::MaxFieldLimit() : res * itv.ub().getIntNumeral();
526 }
527 return (u32_t)res;
528 }
529 }
530 assert(false && "Addr rhs value is not ObjVar");
531 abort();
532}
bool isConstantByteSize() const
Check if byte size is a const value.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:35
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:496
unsigned long long u64_t
Definition GeneralType.h:49

◆ getDefSiteOfObjVar()

const ICFGNode * AbstractStateManager::getDefSiteOfObjVar ( const ObjVar obj,
const ICFGNode node 
) const

Given an ObjVar and its use-site ICFGNode, find the definition-site ICFGNode.

Definition at line 577 of file AbstractStateManager.cpp.

578{
580 {
581 assert(svfg && "SVFG is not built for sparse AE");
582 return svfg->getDefSiteOfObjVar(obj, node);
583 }
584 for (const auto* edge : node->getInEdges())
585 return edge->getSrcNode();
586 return nullptr;
587}
return(char *) p.buffer
const ICFGNode * getDefSiteOfObjVar(const ObjVar *obj, const ICFGNode *node) const
Definition SVFG.cpp:772

◆ getDefSiteOfValVar()

const ICFGNode * AbstractStateManager::getDefSiteOfValVar ( const ValVar var) const

Given a ValVar, find its definition-site ICFGNode.

Definition at line 567 of file AbstractStateManager.cpp.

568{
570 {
571 assert(svfg && "SVFG is not built for sparse AE");
572 return svfg->getDefSiteOfValVar(var);
573 }
574 return var->getICFGNode();
575}
const ICFGNode * getDefSiteOfValVar(const ValVar *var) const
Definition SVFG.cpp:765

◆ getGepByteOffset()

IntervalValue AbstractStateManager::getGepByteOffset ( const GepStmt gep)

Compute the byte offset for a GepStmt.

Definition at line 379 of file AbstractStateManager.cpp.

380{
381 const ICFGNode* node = gep->getICFGNode();
382 if (gep->isConstantOffset())
383 return IntervalValue((s64_t)gep->accumulateConstantByteOffset());
384
385 IntervalValue res(0);
386 for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
387 {
388 const ValVar* idxOperandVar = gep->getOffsetVarAndGepTypePairVec()[i].first;
389 const SVFType* idxOperandType = gep->getOffsetVarAndGepTypePairVec()[i].second;
390
391 if (SVFUtil::isa<SVFArrayType>(idxOperandType) || SVFUtil::isa<SVFPointerType>(idxOperandType))
392 {
394 if (const SVFArrayType* arrOperandType = SVFUtil::dyn_cast<SVFArrayType>(idxOperandType))
395 elemByteSize = arrOperandType->getTypeOfElement()->getByteSize();
396 else if (SVFUtil::isa<SVFPointerType>(idxOperandType))
397 elemByteSize = gep->getAccessPath().gepSrcPointeeType()->getByteSize();
398 else
399 assert(false && "idxOperandType must be ArrType or PtrType");
400
401 if (const ConstIntValVar* op = SVFUtil::dyn_cast<ConstIntValVar>(idxOperandVar))
402 {
403 s64_t lb = (double)Options::MaxFieldLimit() / elemByteSize >= op->getSExtValue()
404 ? op->getSExtValue() * elemByteSize
406 res = res + IntervalValue(lb, lb);
407 }
408 else
409 {
411 if (idxVal.isBottom())
412 res = res + IntervalValue(0, 0);
413 else
414 {
415 s64_t ub = (idxVal.ub().getIntNumeral() < 0) ? 0
416 : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.ub().getIntNumeral()
417 ? elemByteSize * idxVal.ub().getIntNumeral()
418 : Options::MaxFieldLimit();
419 s64_t lb = (idxVal.lb().getIntNumeral() < 0) ? 0
420 : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.lb().getIntNumeral()
421 ? elemByteSize * idxVal.lb().getIntNumeral()
422 : Options::MaxFieldLimit();
423 res = res + IntervalValue(lb, ub);
424 }
425 }
426 }
427 else if (const SVFStructType* structOperandType = SVFUtil::dyn_cast<SVFStructType>(idxOperandType))
428 {
429 res = res + IntervalValue(gep->getAccessPath().getStructFieldOffset(idxOperandVar, structOperandType));
430 }
431 else
432 {
433 assert(false && "gep type pair only support arr/ptr/struct");
434 }
435 }
436 return res;
437}
IntervalValue & getInterval()
Carries around command line options.
Definition Options.h:17
u32_t getByteSize() const
Definition SVFType.h:289
signed long long s64_t
Definition GeneralType.h:50

◆ getGepElementIndex()

IntervalValue AbstractStateManager::getGepElementIndex ( const GepStmt gep)

Compute the flattened element index for a GepStmt.

Definition at line 322 of file AbstractStateManager.cpp.

323{
324 const ICFGNode* node = gep->getICFGNode();
325 if (gep->isConstantOffset())
326 return IntervalValue((s64_t)gep->accumulateConstantOffset());
327
328 IntervalValue res(0);
329 for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
330 {
331 const ValVar* var = gep->getOffsetVarAndGepTypePairVec()[i].first;
332 const SVFType* type = gep->getOffsetVarAndGepTypePairVec()[i].second;
333
335 if (const ConstIntValVar* constInt = SVFUtil::dyn_cast<ConstIntValVar>(var))
336 idxLb = idxUb = constInt->getSExtValue();
337 else
338 {
340 if (idxItv.isBottom())
341 idxLb = idxUb = 0;
342 else
343 {
345 idxUb = idxItv.ub().getIntNumeral();
346 }
347 }
348
349 if (SVFUtil::isa<SVFPointerType>(type))
350 {
351 u32_t elemNum = gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType());
352 idxLb = (double)Options::MaxFieldLimit() / elemNum < idxLb ? Options::MaxFieldLimit() : idxLb * elemNum;
353 idxUb = (double)Options::MaxFieldLimit() / elemNum < idxUb ? Options::MaxFieldLimit() : idxUb * elemNum;
354 }
355 else
356 {
358 {
359 const std::vector<u32_t>& so = PAG::getPAG()->getTypeInfo(type)->getFlattenedElemIdxVec();
360 if (so.empty() || idxUb >= (APOffset)so.size() || idxLb < 0)
361 idxLb = idxUb = 0;
362 else
363 {
366 }
367 }
368 else
369 idxLb = idxUb = 0;
370 }
371 res = res + IntervalValue(idxLb, idxUb);
372 }
373 res.meet_with(IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit()));
374 if (res.isBottom())
375 res = IntervalValue(0);
376 return res;
377}
newitem type
Definition cJSON.cpp:2739
s64_t getIntNumeral() const
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:144
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
Definition IRGraph.cpp:242
const BoundedInt & lb() const
Return the lower bound.
static Option< bool > ModelArrays
Definition Options.h:185
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:118
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:125
s64_t APOffset
Definition GeneralType.h:60

◆ getGepObjAddrs()

AddressValue AbstractStateManager::getGepObjAddrs ( const ValVar pointer,
IntervalValue  offset 
)

Compute GEP object addresses for a pointer at a given element offset.

Definition at line 439 of file AbstractStateManager.cpp.

440{
441 const ICFGNode* node = pointer->getICFGNode();
444 APOffset lb = offset.lb().getIntNumeral() < Options::MaxFieldLimit() ? offset.lb().getIntNumeral()
446 APOffset ub = offset.ub().getIntNumeral() < Options::MaxFieldLimit() ? offset.ub().getIntNumeral()
448 for (APOffset i = lb; i <= ub; i++)
449 {
450 const AbstractValue& addrs = getAbstractValue(pointer, node);
451 for (const auto& addr : addrs.getAddrs())
452 {
453 s64_t baseObj = as.getIDFromAddr(addr);
454 assert(SVFUtil::isa<ObjVar>(svfir->getSVFVar(baseObj)) && "Fail to get the base object address!");
458 }
459 }
460 return gepAddrs;
461}
buffer offset
Definition cJSON.cpp:1113
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:133
const GepObjVar * getGepObjVar(NodeID id) const
Definition SVFIR.h:167
const ICFGNode * getICFGNode() const
u32_t NodeID
Definition GeneralType.h:56

◆ getPointeeElement()

const SVFType * AbstractStateManager::getPointeeElement ( const ObjVar var,
const ICFGNode node 
)

Get the pointee type for a pointer variable.

Definition at line 489 of file AbstractStateManager.cpp.

490{
492 if (!ptrVal.isAddr())
493 return nullptr;
494 for (auto addr : ptrVal.getAddrs())
495 {
497 if (objId == 0)
498 continue;
499 return svfir->getBaseObject(objId)->getType();
500 }
501 return nullptr;
502}
u32_t getIDFromAddr(u32_t addr) const
Return the internal index if addr is an address otherwise return the value of idx.
const SVFType * getType() const
Get obj type.

◆ getTrace()

Map< const ICFGNode *, AbstractState > & SVF::AbstractStateManager::getTrace ( )
inline

Definition at line 154 of file AbstractStateManager.h.

155 {
156 return abstractTrace;
157 }

◆ getUseSitesOfObjVar()

Set< const ICFGNode * > AbstractStateManager::getUseSitesOfObjVar ( const ObjVar obj,
const ICFGNode node 
) const

Given an ObjVar and its use-site ICFGNode, find all downstream use-site ICFGNodes.

Definition at line 538 of file AbstractStateManager.cpp.

539{
541 {
542 assert(svfg && "SVFG is not built for sparse AE");
543 return svfg->getUseSitesOfObjVar(obj, node);
544 }
546 for (const auto* edge : node->getOutEdges())
547 succs.insert(edge->getDstNode());
548 return succs;
549}
const Set< const ICFGNode * > getUseSitesOfObjVar(const ObjVar *obj, const ICFGNode *node) const
Definition SVFG.cpp:815

◆ getUseSitesOfValVar()

Set< const ICFGNode * > AbstractStateManager::getUseSitesOfValVar ( const ValVar var) const

Given a ValVar, find all use-site ICFGNodes.

Definition at line 551 of file AbstractStateManager.cpp.

552{
554 {
555 assert(svfg && "SVFG is not built for sparse AE");
557 }
559 if (const ICFGNode* node = var->getICFGNode())
560 {
561 for (const auto* edge : node->getOutEdges())
562 succs.insert(edge->getDstNode());
563 }
564 return succs;
565}
const Set< const ICFGNode * > getUseSitesOfValVar(const ValVar *var) const
Definition SVFG.cpp:795

◆ hasAbstractState()

bool AbstractStateManager::hasAbstractState ( const ICFGNode node)

Check if an abstract state exists for a given ICFG node.

Definition at line 78 of file AbstractStateManager.cpp.

79{
80 return abstractTrace.count(node) != 0;
81}

◆ hasAbstractValue() [1/3]

bool AbstractStateManager::hasAbstractValue ( const ObjVar var,
const ICFGNode node 
) const

Check whether an ObjVar has a stored value at node.

Definition at line 223 of file AbstractStateManager.cpp.

224{
225 auto it = abstractTrace.find(node);
226 if (it == abstractTrace.end())
227 return false;
228 u32_t objId = var->getId();
229 return it->second.getLocToVal().count(objId) != 0;
230}

◆ hasAbstractValue() [2/3]

bool AbstractStateManager::hasAbstractValue ( const SVFVar var,
const ICFGNode node 
) const

Dispatch to ValVar or ObjVar overload.

Definition at line 232 of file AbstractStateManager.cpp.

233{
234 if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
235 return hasAbstractValue(objVar, node);
236 if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
237 return hasAbstractValue(valVar, node);
238 return false;
239}
bool hasAbstractValue(const ValVar *var, const ICFGNode *node) const

◆ hasAbstractValue() [3/3]

bool AbstractStateManager::hasAbstractValue ( const ValVar var,
const ICFGNode node 
) const

Check whether a ValVar has a real stored value reachable by getAbstractValue. Unlike getAbstractValue, this is side-effect free and does NOT treat the final top-fallback as "present" — so callers that plan to write the fetched value back (e.g. cycle widen/narrow) can distinguish a genuine stored value from the top sentinel.

Definition at line 184 of file AbstractStateManager.cpp.

185{
186 // Constants are always "present" (their value is intrinsic).
187 if (SVFUtil::isa<ConstIntValVar>(var) || SVFUtil::isa<ConstFPValVar>(var) ||
188 SVFUtil::isa<ConstNullPtrValVar>(var) || SVFUtil::isa<ConstDataValVar>(var))
189 return true;
190
191 u32_t id = var->getId();
193
194 // Dense mode: stored at the current node.
195 if (!semiSparse)
196 {
197 auto it = abstractTrace.find(node);
198 if (it != abstractTrace.end() &&
199 (it->second.inVarToValTable(id) || it->second.inVarToAddrsTable(id)))
200 return true;
201 }
202
203 // Semi-sparse (and dense fall-through): check the def-site.
204 const ICFGNode* defNode = var->getICFGNode();
205 if (defNode)
206 {
207 auto it = abstractTrace.find(defNode);
208 if (it != abstractTrace.end() && it->second.getVarToVal().count(id))
209 return true;
210
211 // Fallback for call-result ValVars: value lives at the RetICFGNode.
212 if (const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(defNode))
213 {
214 const RetICFGNode* retNode = callNode->getRetICFGNode();
215 auto rit = abstractTrace.find(retNode);
216 if (rit != abstractTrace.end() && rit->second.getVarToVal().count(id))
217 return true;
218 }
219 }
220 return false;
221}

◆ loadValue()

AbstractValue AbstractStateManager::loadValue ( const ValVar pointer,
const ICFGNode node 
)

Load value through a pointer: resolve pointer's address set via getAbstractValue (sparsity-aware), then load from each ObjVar address.

Parameters
pointerThe pointer SVFVar (ValVar).
nodeThe ICFG node providing context.
Returns
The joined abstract value from all pointed-to objects.

Definition at line 467 of file AbstractStateManager.cpp.

468{
469 const AbstractValue& ptrVal = getAbstractValue(pointer, node);
471 AbstractValue res;
472 for (auto addr : ptrVal.getAddrs())
473 res.join_with(as.load(addr));
474 return res;
475}

◆ operator[]()

AbstractState & SVF::AbstractStateManager::operator[] ( const ICFGNode node)
inline

Definition at line 158 of file AbstractStateManager.h.

159 {
160 return abstractTrace[node];
161 }

◆ storeValue()

void AbstractStateManager::storeValue ( const ValVar pointer,
const AbstractValue val,
const ICFGNode node 
)

Store value through a pointer: resolve pointer's address set via getAbstractValue (sparsity-aware), then store to each ObjVar address.

Parameters
pointerThe pointer SVFVar (ValVar).
valThe value to store.
nodeThe ICFG node providing context.

Definition at line 477 of file AbstractStateManager.cpp.

478{
479 const AbstractValue& ptrVal = getAbstractValue(pointer, node);
481 for (auto addr : ptrVal.getAddrs())
482 as.store(addr, val);
483}

◆ updateAbstractState()

void AbstractStateManager::updateAbstractState ( const ICFGNode node,
const AbstractState state 
)

Definition at line 64 of file AbstractStateManager.cpp.

65{
67 {
68 // Semi-sparse: only replace ObjVar state. ValVars live at their
69 // def-sites and must not be overwritten by state replacement.
70 abstractTrace[node].updateAddrStateOnly(state);
71 }
72 else
73 {
74 abstractTrace[node] = state;
75 }
76}

◆ updateAbstractValue() [1/3]

void AbstractStateManager::updateAbstractValue ( const ObjVar var,
const AbstractValue val,
const ICFGNode node 
)

Write an address-taken variable's content via virtual-address store.

Definition at line 259 of file AbstractStateManager.cpp.

260{
263 as.store(addr, val);
264}

◆ updateAbstractValue() [2/3]

void AbstractStateManager::updateAbstractValue ( const SVFVar var,
const AbstractValue val,
const ICFGNode node 
)

Dispatch to ValVar or ObjVar overload.

Definition at line 266 of file AbstractStateManager.cpp.

267{
268 if (const ObjVar* objVar = SVFUtil::dyn_cast<ObjVar>(var))
270 else if (const ValVar* valVar = SVFUtil::dyn_cast<ValVar>(var))
272 else
273 assert(false && "Unknown SVFVar kind");
274}
void updateAbstractValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
Write a top-level variable's abstract value into abstractTrace[node].

◆ updateAbstractValue() [3/3]

void AbstractStateManager::updateAbstractValue ( const ValVar var,
const AbstractValue val,
const ICFGNode node 
)

Write a top-level variable's abstract value into abstractTrace[node].

Definition at line 245 of file AbstractStateManager.cpp.

246{
247 // In semi-sparse mode, write to the var's def-site so that
248 // getAbstractValue (which reads from def-site) stays consistent.
249 const ICFGNode* target = node;
251 {
252 const ICFGNode* defNode = var->getICFGNode();
253 if (defNode)
254 target = defNode;
255 }
256 abstractTrace[target][var->getId()] = val;
257}

Member Data Documentation

◆ abstractTrace

Map<const ICFGNode*, AbstractState> SVF::AbstractStateManager::abstractTrace
private

Definition at line 182 of file AbstractStateManager.h.

◆ svfg

SVFG* SVF::AbstractStateManager::svfg
private

Definition at line 181 of file AbstractStateManager.h.

◆ svfir

SVFIR* SVF::AbstractStateManager::svfir
private

Definition at line 180 of file AbstractStateManager.h.


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