36 using namespace SVFUtil;
53 stat->finializeStat();
56 for (
auto& detector: detectors)
57 detector->reportBug();
68 for (
auto it: funcToWTO)
89 for (
auto it = callGraph->begin(); it != callGraph->end(); it++)
92 if (callGraphScc->
isInCycle(it->second->getId()))
93 recursiveFuns.insert(it->second->getFunction());
97 for (
const SVFFunction* fun : svfir->getModule()->getFunctionSet())
99 if(fun->isDeclaration())
101 auto* wto =
new ICFGWTO(icfg, icfg->getFunEntryICFGNode(fun));
103 funcToWTO[fun] = wto;
112 getAbsStateFromTrace(
114 if (
const SVFFunction* fun = svfir->getModule()->getSVFFunction(
"main"))
124 const ICFGNode* node = icfg->getGlobalICFGNode();
130 handleSVFStatement(stmt);
139 std::vector<AbstractState> workList;
143 if (abstractTrace.find(edge->getSrcNode()) != abstractTrace.end())
145 const IntraCFGEdge *intraCfgEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge);
149 if (isBranchFeasible(intraCfgEdge, tmpEs))
151 workList.push_back(tmpEs);
160 workList.push_back(abstractTrace[edge->getSrcNode()]);
168 if (workList.size() == 0)
174 while (!workList.empty())
181 abstractTrace[icfgNode] = preAs;
207 SVFVar* loadVar0 = svfir->getGNode(op0);
211 if (
const LoadStmt *loadStmt = SVFUtil::dyn_cast<LoadStmt>(loadVar0InStmt))
215 else if (
const CopyStmt *copyStmt = SVFUtil::dyn_cast<CopyStmt>(loadVar0InStmt))
217 loadVar0 = svfir->getGNode(copyStmt->getRHSVarID());
221 if (
const LoadStmt *loadStmt = SVFUtil::dyn_cast<LoadStmt>(loadVar0InStmt2))
229 SVFVar* loadVar1 = svfir->getGNode(op1);
233 if (
const LoadStmt *loadStmt = SVFUtil::dyn_cast<LoadStmt>(loadVar1InStmt))
237 else if (
const CopyStmt *copyStmt = SVFUtil::dyn_cast<CopyStmt>(loadVar1InStmt))
239 loadVar1 = svfir->getGNode(copyStmt->getRHSVarID());
243 if (
const LoadStmt *loadStmt = SVFUtil::dyn_cast<LoadStmt>(loadVar1InStmt2))
260 bool b0 = new_es[op0].getInterval().is_numeral();
261 bool b1 = new_es[op1].getInterval().is_numeral();
267 std::swap(load_op0, load_op1);
268 predicate = _switch_lhsrhs_predicate[predicate];
289 predicate = _reverse_predicate[predicate];
295 addrs = new_es[load_op0->
getRHSVarID()].getAddrs();
297 IntervalValue &lhs = new_es[op0].getInterval(), &rhs = new_es[op1].getInterval();
300 case CmpStmt::Predicate::ICMP_EQ:
301 case CmpStmt::Predicate::FCMP_OEQ:
302 case CmpStmt::Predicate::FCMP_UEQ:
307 for (
const auto &addr: addrs)
317 case CmpStmt::Predicate::ICMP_NE:
318 case CmpStmt::Predicate::FCMP_ONE:
319 case CmpStmt::Predicate::FCMP_UNE:
322 case CmpStmt::Predicate::ICMP_UGT:
323 case CmpStmt::Predicate::ICMP_SGT:
324 case CmpStmt::Predicate::FCMP_OGT:
325 case CmpStmt::Predicate::FCMP_UGT:
329 for (
const auto &addr: addrs)
339 case CmpStmt::Predicate::ICMP_UGE:
340 case CmpStmt::Predicate::ICMP_SGE:
341 case CmpStmt::Predicate::FCMP_OGE:
342 case CmpStmt::Predicate::FCMP_UGE:
347 for (
const auto &addr: addrs)
358 case CmpStmt::Predicate::ICMP_ULT:
359 case CmpStmt::Predicate::ICMP_SLT:
360 case CmpStmt::Predicate::FCMP_OLT:
361 case CmpStmt::Predicate::FCMP_ULT:
366 for (
const auto &addr: addrs)
377 case CmpStmt::Predicate::ICMP_ULE:
378 case CmpStmt::Predicate::ICMP_SLE:
379 case CmpStmt::Predicate::FCMP_OLE:
380 case CmpStmt::Predicate::FCMP_ULE:
385 for (
const auto &addr: addrs)
396 case CmpStmt::Predicate::FCMP_FALSE:
398 case CmpStmt::Predicate::FCMP_TRUE:
401 assert(
false &&
"implement this part");
417 workList.
push(cmpVarInStmt);
424 while(!workList.
empty())
427 if (SVFUtil::isa<CopyStmt>(stmt))
432 else if (
const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(stmt))
436 AddressValue &addrs = new_es[load->getRHSVarID()].getAddrs();
437 for (
const auto &addr: addrs)
458 return isSwitchBranchFeasible(cmpVar,
466 if (
const CmpStmt *cmpStmt = SVFUtil::dyn_cast<CmpStmt>(cmpVarInStmt))
468 return isCmpBranchFeasible(cmpStmt,
473 return isSwitchBranchFeasible(
483 stat->getBlockTrace()++;
485 std::deque<const ICFGNode*> worklist;
487 const std::vector<const ICFGNode*>& worklist_vec = icfg->getSubNodes(node);
488 for (
auto it = worklist_vec.begin(); it != worklist_vec.end(); ++it)
491 stat->getICFGNodeTrace()++;
495 handleSVFStatement(stmt);
498 if (
const CallICFGNode* callnode = SVFUtil::dyn_cast<CallICFGNode>(curNode))
500 handleCallSite(callnode);
502 for (
auto& detector: detectors)
503 detector->detect(getAbsStateFromTrace(node), node);
504 stat->countStateSize();
515 handleWTOComponent(wtoNode);
521 if (
const ICFGSingletonWTO* node = SVFUtil::dyn_cast<ICFGSingletonWTO>(wtoNode))
523 if (mergeStatesFromPredecessors(node->getICFGNode()))
524 handleSingletonWTO(node);
527 else if (
const ICFGCycleWTO* cycle = SVFUtil::dyn_cast<ICFGCycleWTO>(wtoNode))
529 if (mergeStatesFromPredecessors(cycle->head()->getICFGNode()))
530 handleCycleWTO(cycle);
535 assert(
false &&
"unknown WTO type!");
541 if (
const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node))
545 extCallPass(callNode);
547 else if (isRecursiveCall(callNode))
549 recursiveCallPass(callNode);
551 else if (isDirectCall(callNode))
553 directCallFunPass(callNode);
555 else if (isIndirectCall(callNode))
557 indirectCallFunPass(callNode);
561 assert(
false &&
"implement this part");
566 assert (
false &&
"it is not call node");
577 callSiteStack.push_back(callNode);
578 utils->handleExtAPI(callNode);
579 for (
auto& detector : detectors)
581 detector->handleStubFunctions(callNode);
583 callSiteStack.pop_back();
594 SkipRecursiveCall(callNode);
598 if (
const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(*retNode->
getSVFStmts().begin()))
600 if (!retPE->getLHSVar()->isPointer() &&
601 !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr())
607 abstractTrace[retNode] = as;
617 callSiteStack.push_back(callNode);
619 abstractTrace[callNode] = as;
624 callSiteStack.pop_back();
628 abstractTrace[retNode] = abstractTrace[callNode];
633 const auto callsiteMaps = svfir->getIndirectCallsites();
634 return callsiteMaps.find(callNode) != callsiteMaps.end();
640 const auto callsiteMaps = svfir->getIndirectCallsites();
641 NodeID call_id = callsiteMaps.at(callNode);
652 callSiteStack.push_back(callNode);
653 abstractTrace[callNode] = as;
655 ICFGWTO* wto = funcToWTO[callfun];
657 callSiteStack.pop_back();
660 abstractTrace[retNode] = abstractTrace[callNode];
669 const ICFGNode* cycle_head = cycle->
head()->getICFGNode();
671 bool increasing =
true;
673 for (
u32_t cur_iter = 0;; cur_iter++)
680 handleWTOComponent(cycle->
head());
685 abstractTrace[cycle_head] = prev_head_state.
widening(cur_head_state);
686 if (abstractTrace[cycle_head] == prev_head_state)
695 abstractTrace[cycle_head] = prev_head_state.
narrowing(cur_head_state);
696 if (abstractTrace[cycle_head] == prev_head_state)
706 handleSingletonWTO(cycle->
head());
715 if (
const AddrStmt *addr = SVFUtil::dyn_cast<AddrStmt>(stmt))
717 updateStateOnAddr(addr);
719 else if (
const BinaryOPStmt *binary = SVFUtil::dyn_cast<BinaryOPStmt>(stmt))
721 updateStateOnBinary(binary);
723 else if (
const CmpStmt *cmp = SVFUtil::dyn_cast<CmpStmt>(stmt))
725 updateStateOnCmp(cmp);
727 else if (SVFUtil::isa<UnaryOPStmt>(stmt))
730 else if (SVFUtil::isa<BranchStmt>(stmt))
734 else if (
const LoadStmt *load = SVFUtil::dyn_cast<LoadStmt>(stmt))
736 updateStateOnLoad(load);
738 else if (
const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(stmt))
740 updateStateOnStore(store);
742 else if (
const CopyStmt *
copy = SVFUtil::dyn_cast<CopyStmt>(stmt))
744 updateStateOnCopy(
copy);
746 else if (
const GepStmt *gep = SVFUtil::dyn_cast<GepStmt>(stmt))
748 updateStateOnGep(gep);
750 else if (
const SelectStmt *select = SVFUtil::dyn_cast<SelectStmt>(stmt))
752 updateStateOnSelect(select);
754 else if (
const PhiStmt *phi = SVFUtil::dyn_cast<PhiStmt>(stmt))
756 updateStateOnPhi(phi);
758 else if (
const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(stmt))
761 updateStateOnCall(callPE);
763 else if (
const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(stmt))
765 updateStateOnRet(retPE);
768 assert(
false &&
"implement this part");
778 if (
const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(*retNode->
getSVFStmts().begin()))
781 if (!retPE->getLHSVar()->isPointer() && !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr())
800 for (
const ICFGNode* node: bb->getICFGNodeList())
802 for (
const SVFStmt *stmt: node->getSVFStmts())
804 if (
const StoreStmt *store = SVFUtil::dyn_cast<StoreStmt>(stmt))
806 const SVFVar *rhsVar = store->getRHSVar();
807 u32_t lhs = store->getLHSVarID();
813 for (
const auto &addr: addrs.
getAddrs())
830 generalNumMap[
"ES_Var_AVG_Num"] = 0;
831 generalNumMap[
"ES_Loc_AVG_Num"] = 0;
832 generalNumMap[
"ES_Var_Addr_AVG_Num"] = 0;
833 generalNumMap[
"ES_Loc_Addr_AVG_Num"] = 0;
840 memUsage = getMemUsage();
843 generalNumMap[
"ES_Var_AVG_Num"] /=
count;
844 generalNumMap[
"ES_Loc_AVG_Num"] /=
count;
845 generalNumMap[
"ES_Var_Addr_AVG_Num"] /=
count;
846 generalNumMap[
"ES_Loc_Addr_AVG_Num"] /=
count;
848 generalNumMap[
"SVF_STMT_NUM"] =
count;
849 generalNumMap[
"ICFG_Node_Num"] = _ae->svfir->getICFG()->nodeNum;
850 u32_t callSiteNum = 0;
851 u32_t extCallSiteNum = 0;
853 for (
const auto &it: *_ae->svfir->getICFG())
855 if (it.second->getFun())
857 funs.insert(it.second->getFun());
859 if (
const CallICFGNode *callNode = dyn_cast<CallICFGNode>(it.second))
871 generalNumMap[
"Func_Num"] = funs.size();
872 generalNumMap[
"EXT_CallSite_Num"] = extCallSiteNum;
873 generalNumMap[
"NonEXT_CallSite_Num"] = callSiteNum;
874 timeStatMap[
"Total_Time(sec)"] = (double)(endTime - startTime) /
TIMEINTERVAL;
883 if (fullName.find(
'/') == std::string::npos)
886 moduleName =
name.substr(0, fullName.find(
'.'));
890 std::string name = fullName.substr(fullName.find(
'/'), fullName.size());
891 moduleName =
name.substr(0, fullName.find(
'.'));
895 SVFUtil::outs() <<
"################ (program : " << moduleName <<
")###############\n";
897 unsigned field_width = 30;
898 for (NUMStatMap::iterator it = generalNumMap.begin(), eit = generalNumMap.end(); it != eit; ++it)
901 std::cout << std::setw(field_width) << it->first << it->second <<
"\n";
903 SVFUtil::outs() <<
"-------------------------------------------------------\n";
904 for (TIMEStatMap::iterator it = timeStatMap.begin(), eit = timeStatMap.end(); it != eit; ++it)
907 SVFUtil::outs() << std::setw(field_width) << it->first << it->second <<
"\n";
911 SVFUtil::outs() <<
"#######################################################" << std::endl;
919 Set<std::string> buf_checkpoint_names = {
"UNSAFE_BUFACCESS",
"SAFE_BUFACCESS"};
921 for (
auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
924 if (
const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
926 if (
const SVFFunction *fun = call->getCalledFunction())
928 if (ae_checkpoint_names.find(fun->getName()) !=
929 ae_checkpoint_names.end())
931 checkpoints.insert(call);
935 if (buf_checkpoint_names.find(fun->getName()) !=
936 buf_checkpoint_names.end())
938 checkpoints.insert(call);
948 if (checkpoints.size() == 0)
985 if (as[cond].getInterval().is_numeral())
987 as[res] = as[cond].getInterval().is_zero() ? as[fval] : as[tval];
992 as[res].join_with(as[fval]);
1006 if (hasAbsStateFromTrace(opICFGNode))
1016 const IntraCFGEdge* intraEdge = SVFUtil::cast<IntraCFGEdge>(edge);
1019 if (isBranchFeasible(intraEdge, tmpEs))
1074 IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
1080 resVal = (lhs + rhs);
1084 resVal = (lhs - rhs);
1088 resVal = (lhs * rhs);
1093 resVal = (lhs / rhs);
1098 resVal = (lhs % rhs);
1101 resVal = (lhs ^ rhs);
1104 resVal = (lhs & rhs);
1107 resVal = (lhs | rhs);
1110 resVal = (lhs >> rhs);
1113 resVal = (lhs << rhs);
1116 resVal = (lhs >> rhs);
1119 assert(
false &&
"undefined binary: ");
1136 if (addrOp0.
equals(addrOp1))
1160 if (as[op0].isInterval() && as[op1].isInterval())
1163 &rhs = as[op1].getInterval();
1171 resVal = (lhs == rhs);
1177 resVal = (lhs != rhs);
1183 resVal = (lhs > rhs);
1189 resVal = (lhs >= rhs);
1195 resVal = (lhs < rhs);
1201 resVal = (lhs <= rhs);
1211 assert(
false &&
"undefined compare: ");
1216 else if (as[op0].isAddr() && as[op1].isAddr())
1219 &rhs = as[op1].getAddrs();
1231 else if (lhs.
empty() && rhs.empty())
1249 else if (lhs.
empty() && rhs.empty())
1264 if (lhs.
size() == 1 && rhs.size() == 1)
1279 if (lhs.
size() == 1 && rhs.size() == 1)
1294 if (lhs.
size() == 1 && rhs.size() == 1)
1309 if (lhs.
size() == 1 && rhs.size() == 1)
1327 assert(
false &&
"undefined compare: ");
1357 if (SVFUtil::isa<SVFIntegerType>(
type))
1360 if (as[var->getId()].getInterval().is_numeral())
1364 int8_t signed_i8_value = as[var->getId()].getInterval().getIntNumeral();
1365 u32_t unsigned_value =
static_cast<uint8_t
>(signed_i8_value);
1368 else if (bits == 16)
1370 s16_t signed_i16_value = as[var->getId()].getInterval().getIntNumeral();
1371 u32_t unsigned_value =
static_cast<u16_t>(signed_i16_value);
1374 else if (bits == 32)
1376 s32_t signed_i32_value = as[var->getId()].getInterval().getIntNumeral();
1377 u32_t unsigned_value =
static_cast<u32_t>(signed_i32_value);
1380 else if (bits == 64)
1382 s64_t signed_i64_value = as[var->getId()].getInterval().getIntNumeral();
1388 assert(
false &&
"cannot support int type other than u8/16/32/64");
1408 u32_t dst_bits = dstType->getByteSize() * 8;
1412 int8_t s8_lb =
static_cast<int8_t
>(int_lb);
1413 int8_t s8_ub =
static_cast<int8_t
>(int_ub);
1417 return utils->getRangeLimitFromType(dstType);
1421 else if (dst_bits == 16)
1426 if (s16_lb > s16_ub)
1429 return utils->getRangeLimitFromType(dstType);
1433 else if (dst_bits == 32)
1438 if (s32_lb > s32_ub)
1441 return utils->getRangeLimitFromType(dstType);
1447 assert(
false &&
"cannot support dst int type other than u8/16/32");
1461 as[lhs] = getZExtValue(as,
copy->getRHSVar());
1465 as[lhs] = as[rhs].getInterval();
1469 as[lhs] = as[rhs].getInterval();
1473 as[lhs] = as[rhs].getInterval();
1477 as[lhs] = as[rhs].getInterval();
1481 as[lhs] = as[rhs].getInterval();
1485 as[lhs] = getTruncValue(as,
copy->getRHSVar(),
copy->getLHSVar()->getType());
1489 as[lhs] = as[rhs].getInterval();
1501 if (as[rhs].isAddr())
1512 assert(
false &&
"undefined copy kind");
AEStat: Statistic for AE.
void performStat() override
Handles external API calls and manages abstract states.
void updateStateOnCall(const CallPE *callPE)
virtual bool isRecursiveCall(const CallICFGNode *callNode)
virtual void recursiveCallPass(const CallICFGNode *callNode)
void updateStateOnStore(const StoreStmt *store)
virtual bool isDirectCall(const CallICFGNode *callNode)
virtual void handleCycleWTO(const ICFGCycleWTO *cycle)
handle wto cycle (loop)
void updateStateOnGep(const GepStmt *gep)
void analyse()
Program entry.
virtual void extCallPass(const CallICFGNode *callNode)
virtual void handleGlobalNode()
Global ICFGNode is handled at the entry of the program,.
bool mergeStatesFromPredecessors(const ICFGNode *icfgNode)
virtual void directCallFunPass(const CallICFGNode *callNode)
void handleWTOComponent(const ICFGWTOComp *wtoComp)
virtual bool isExtCall(const CallICFGNode *callNode)
virtual bool isIndirectCall(const CallICFGNode *callNode)
void initWTO()
Mark recursive functions in the call graph.
AbstractInterpretation()
Constructor.
void updateStateOnPhi(const PhiStmt *phi)
bool isBranchFeasible(const IntraCFGEdge *intraEdge, AbstractState &as)
bool isSwitchBranchFeasible(const SVFVar *var, s64_t succ, AbstractState &as)
void updateStateOnSelect(const SelectStmt *select)
virtual void handleSVFStatement(const SVFStmt *stmt)
virtual void indirectCallFunPass(const CallICFGNode *callNode)
virtual void runOnModule(ICFG *icfg)
void updateStateOnAddr(const AddrStmt *addr)
virtual ~AbstractInterpretation()
Destructor.
bool isCmpBranchFeasible(const CmpStmt *cmpStmt, s64_t succ, AbstractState &as)
virtual void handleCallSite(const ICFGNode *node)
void updateStateOnRet(const RetPE *retPE)
void handleWTOComponents(const std::list< const ICFGWTOComp * > &wtoComps)
Hanlde two types of WTO components (singleton and cycle)
void updateStateOnCopy(const CopyStmt *copy)
void updateStateOnLoad(const LoadStmt *load)
void updateStateOnBinary(const BinaryOPStmt *binary)
virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto)
handle instructions in svf basic blocks
void updateStateOnCmp(const CmpStmt *cmp)
virtual void SkipRecursiveCall(const CallICFGNode *callnode)
void store(u32_t addr, const AbstractValue &val)
virtual bool inAddrToValTable(u32_t id) const
whether the memory address stores abstract value
void joinWith(const AbstractState &other)
domain join with other, important! other widen this.
IntervalValue getElementIndex(const GepStmt *gep)
virtual AbstractValue & load(u32_t addr)
AbstractValue loadValue(NodeID varId)
bool inVarToAddrsTable(u32_t id) const
whether the variable is in varToAddrs table
AbstractState narrowing(const AbstractState &other)
domain narrow with other, and return the narrowed domain
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
virtual bool inVarToValTable(u32_t id) const
whether the variable is in varToVal table
void storeValue(NodeID varId, AbstractValue val)
AddressValue getGepObjAddrs(u32_t pointer, IntervalValue offset)
void initObjVar(ObjVar *objVar)
AbstractState widening(const AbstractState &other)
domain widen with other, and return the widened domain
void meet_with(const AbstractValue &other)
void join_with(const AbstractValue &other)
AddressValue & getAddrs()
bool equals(const AddressValue &rhs) const
bool hasIntersect(const AddressValue &other)
AddrSet::const_iterator begin() const
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
NodeID getRHSVarID() const
NodeID getLHSVarID() const
SVFVar * getRHSVar() const
s64_t getIntNumeral() const
const SVFFunction * getCalledFunction() const
const RetICFGNode * getRetICFGNode() const
Return callsite.
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
@ 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
bool push(const Data &data)
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
const SVFStmtList & getSVFStmts() const
void meet_with(const IntervalValue &other)
Return a intersected IntervalValue.
static BoundedInt minus_infinity()
Get minus infinity -inf.
const BoundedInt & lb() const
Return the lower bound.
const BoundedInt & ub() const
Return the upper bound.
static BoundedInt plus_infinity()
Get plus infinity +inf.
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
s64_t getSuccessorCondValue() const
const SVFVar * getCondition() const
NodeID getOpVarID(u32_t pos) const
u32_t getOpVarNum() const
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
static const Option< u32_t > WidenDelay
static const Option< bool > PStat
static const Option< bool > BufferOverflowCheck
buffer overflow checker, Default: false
const ICFGNode * getOpICFGNode(u32_t op_idx) const
Return the corresponding ICFGNode of this operand.
CallGraphSCC * getCallGraphSCC() const
Return call graph SCC.
PTACallGraph * getCallGraph() const
Return call graph.
bool isInCycle(NodeID n) const
whether the node is in a cycle
NodeID getId() const
Get ID.
const std::vector< const SVFBasicBlock * > & getReachableBBs() const
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
ICFGNode * getICFGNode() const
bool isConstDataOrAggDataButNotNullPtr() const
virtual bool isPointer() const
Whether it is a pointer.
virtual const SVFType * getType() const
Return type of the value.
const SVFValue * getValue() const
Get/has methods of the components.
const SVFVar * getTrueValue() const
const SVFVar * getCondition() const
const SVFVar * getFalseValue() const
const WTONode< GraphT > * head() const
Return the head of the cycle.
const WTOComponentRefList & getWTOComponents() const
Get all wto components in WTO cycle.
const NodeT * getICFGNode() const
Return the graph node.
const WTOComponentRefList & getWTOComponents() const
Get all wto components in WTO.
bool isExtCall(const SVFFunction *fun)
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
std::ostream & errs()
Overwrite llvm::errs()
std::ostream & outs()
Overwrite llvm::outs()
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set