Static Value-Flow Analysis
Loading...
Searching...
No Matches
Functions
SVF::LLVMUtil Namespace Reference

Functions

bool isCallSite (const Instruction *inst)
 Whether an instruction is a call or invoke instruction.
 
bool isCallSite (const Value *val)
 Whether an instruction is a call or invoke instruction.
 
double getDoubleValue (const ConstantFP *fpValue)
 
std::pair< s64_t, u64_tgetIntegerValue (const ConstantInt *intValue)
 
const CallBasegetLLVMCallSite (const Value *value)
 Return LLVM callsite given a value.
 
const FunctiongetCallee (const CallBase *cs)
 
const FunctiongetLLVMFunction (const Value *val)
 Return LLVM function if this value is.
 
const FunctiongetProgFunction (const std::string &funName)
 Get program entry function from module.
 
bool isProgEntryFunction (const Function *fun)
 Check whether a function is an entry function (i.e., main)
 
bool isBlackholeSym (const Value *val)
 Check whether this value is a black hole.
 
bool isNullPtrSym (const Value *val)
 Check whether this value is a black hole.
 
static TypegetPtrElementType (const PointerType *pty)
 
u32_t getNumOfElements (const Type *ety)
 Return size of this object based on LLVM value.
 
bool isObject (const Value *ref)
 Return true if this value refers to a object.
 
bool isUncalledFunction (const Function *fun)
 whether this is a function without any possible caller?
 
bool ArgInDeadFunction (const Value *val)
 whether this is an argument in dead function
 
bool ArgInProgEntryFunction (const Value *val)
 Return true if this is an argument of a program entry function (e.g. main)
 
bool isPtrInUncalledFunction (const Value *value)
 Return true if this is value in a dead function (function without any caller)
 
bool isNoCallerFunction (const Function *fun)
 Function does not have any possible caller in the call graph.
 
bool isArgOfUncalledFunction (const Value *val)
 Return true if the argument in a function does not have a caller.
 
bool basicBlockHasRetInst (const BasicBlock *bb)
 Return true if the function has a return instruction.
 
bool functionDoesNotRet (const Function *fun)
 
void getFunReachableBBs (const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
 Get reachable basic block from function entry.
 
const ValuestripConstantCasts (const Value *val)
 Strip off the constant casts.
 
const ValuestripAllCasts (const Value *val)
 Strip off the all casts.
 
const ValuegetFirstUseViaCastInst (const Value *val)
 
const ConstantExprisGepConstantExpr (const Value *val)
 Return corresponding constant expression, otherwise return nullptr.
 
const ConstantExprisInt2PtrConstantExpr (const Value *val)
 
const ConstantExprisPtr2IntConstantExpr (const Value *val)
 
const ConstantExprisCastConstantExpr (const Value *val)
 
const ConstantExprisSelectConstantExpr (const Value *val)
 
const ConstantExprisTruncConstantExpr (const Value *val)
 
const ConstantExprisCmpConstantExpr (const Value *val)
 
const ConstantExprisBinaryConstantExpr (const Value *val)
 
const ConstantExprisUnaryConstantExpr (const Value *val)
 
static DataLayoutgetDataLayout (Module *mod)
 
void getNextInsts (const Instruction *curInst, std::vector< const Instruction * > &instList)
 Get the next instructions following control flow.
 
bool isNoPrecessorBasicBlock (const BasicBlock *bb)
 
bool isIRFile (const std::string &filename)
 Check whether a file is an LLVM IR file.
 
void processArguments (int argc, char **argv, int &arg_num, char **arg_value, std::vector< std::string > &moduleNameVec)
 Parse argument for multi-module analysis.
 
const std::string getSourceLoc (const Value *val)
 
const std::string getSourceLocOfFunction (const Function *F)
 
bool isIntrinsicInst (const Instruction *inst)
 Return true if it is an intrinsic instruction.
 
bool isIntrinsicFun (const Function *func)
 
std::vector< const Function * > getCalledFunctions (const Function *F)
 Get all called funcions in a parent function.
 
std::string restoreFuncName (std::string funcName)
 
bool isExtCall (const Function *fun)
 
bool isMemcpyExtFun (const Function *fun)
 
bool isMemsetExtFun (const Function *fun)
 
u32_t getHeapAllocHoldingArgPosition (const Function *fun)
 
const FunObjVargetFunObjVar (const std::string &name)
 
bool isConstDataOrAggData (const Value *val)
 Return true if the value refers to constant data, e.g., i32 0.
 
const ValuegetGlobalRep (const Value *val)
 find the unique defined global across multiple modules
 
bool isConstantObjSym (const Value *val)
 Check whether this value points-to a constant object.
 
void viewCFG (const Function *fun)
 
void viewCFGOnly (const Function *fun)
 
std::string dumpValue (const Value *val)
 
std::string dumpType (const Type *type)
 
std::string dumpValueAndDbgInfo (const Value *val)
 
bool isHeapAllocExtCallViaRet (const Instruction *inst)
 
bool isHeapAllocExtCallViaArg (const Instruction *inst)
 
bool isHeapAllocExtCall (const Instruction *inst)
 
bool isStackAllocExtCallViaRet (const Instruction *inst)
 
bool isStackAllocExtCall (const Instruction *inst)
 
bool isHeapObj (const Value *val)
 
bool isStackObj (const Value *val)
 
bool isNonInstricCallSite (const Instruction *inst)
 Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
 
const FunctiongetProgEntryFunction (Module &module)
 Get program entry function from module.
 

Function Documentation

◆ ArgInDeadFunction()

bool SVF::LLVMUtil::ArgInDeadFunction ( const Value val)
inline

whether this is an argument in dead function

Definition at line 162 of file LLVMUtil.h.

163{
164 return SVFUtil::isa<Argument>(val)
165 && isUncalledFunction(SVFUtil::cast<Argument>(val)->getParent());
166}
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
Definition LLVMUtil.cpp:159
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ ArgInProgEntryFunction()

bool SVF::LLVMUtil::ArgInProgEntryFunction ( const Value val)
inline

Return true if this is an argument of a program entry function (e.g. main)

Definition at line 170 of file LLVMUtil.h.

171{
172 return SVFUtil::isa<Argument>(val) &&
173 LLVMUtil::isProgEntryFunction(
174 SVFUtil::cast<Argument>(val)->getParent());
175}

◆ basicBlockHasRetInst()

bool SVF::LLVMUtil::basicBlockHasRetInst ( const BasicBlock bb)

Return true if the function has a return instruction.

Return true if the basic block has a return instruction

Definition at line 110 of file LLVMUtil.cpp.

111{
112 for (BasicBlock::const_iterator it = bb->begin(), eit = bb->end();
113 it != eit; ++it)
114 {
115 if(SVFUtil::isa<ReturnInst>(*it))
116 return true;
117 }
118 return false;
119}

◆ dumpType()

std::string SVF::LLVMUtil::dumpType ( const Type type)

Definition at line 627 of file LLVMUtil.cpp.

628{
629 std::string str;
630 llvm::raw_string_ostream rawstr(str);
631 if (type)
632 rawstr << " " << *type << " ";
633 else
634 rawstr << " llvm type is null";
635 return rawstr.str();
636}
newitem type
Definition cJSON.cpp:2739

◆ dumpValue()

std::string SVF::LLVMUtil::dumpValue ( const Value val)

Definition at line 616 of file LLVMUtil.cpp.

617{
618 std::string str;
619 llvm::raw_string_ostream rawstr(str);
620 if (val)
621 rawstr << " " << *val << " ";
622 else
623 rawstr << " llvm Value is null";
624 return rawstr.str();
625}

◆ dumpValueAndDbgInfo()

std::string SVF::LLVMUtil::dumpValueAndDbgInfo ( const Value val)

Definition at line 638 of file LLVMUtil.cpp.

639{
640 std::string str;
641 llvm::raw_string_ostream rawstr(str);
642 if (val)
644 else
645 rawstr << " llvm Value is null";
646 return rawstr.str();
647}
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:454
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:616

◆ functionDoesNotRet()

bool SVF::LLVMUtil::functionDoesNotRet ( const Function fun)

Return true if the function has a return instruction reachable from function entry

Definition at line 124 of file LLVMUtil.cpp.

125{
126 if (LLVMUtil::isExtCall(fun))
127 {
128 return fun->getReturnType()->isVoidTy();
129 }
130 std::vector<const BasicBlock*> bbVec;
132 bbVec.push_back(&fun->getEntryBlock());
133 while(!bbVec.empty())
134 {
135 const BasicBlock* bb = bbVec.back();
136 bbVec.pop_back();
137 if (basicBlockHasRetInst(bb))
138 {
139 return false;
140 }
141
143 sit != esit; ++sit)
144 {
145 const BasicBlock* succbb = (*sit);
146 if(visited.find(succbb)==visited.end())
147 visited.insert(succbb);
148 else
149 continue;
150 bbVec.push_back(succbb);
151 }
152 }
153 return true;
154}
bool isExtCall(const Function *fun)
Definition LLVMUtil.cpp:385
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:90
llvm::succ_const_iterator succ_const_iterator
LLVM Iterators.
Definition BasicTypes.h:287

◆ getCalledFunctions()

std::vector< const Function * > SVF::LLVMUtil::getCalledFunctions ( const Function F)

Get all called funcions in a parent function.

Definition at line 365 of file LLVMUtil.cpp.

366{
367 std::vector<const Function *> calledFunctions;
368 for (const Instruction &I : instructions(F))
369 {
370 if (const CallBase *callInst = SVFUtil::dyn_cast<CallBase>(&I))
371 {
372 Function *calledFunction = callInst->getCalledFunction();
373 if (calledFunction)
374 {
376 std::vector<const Function *> nestedCalledFunctions = getCalledFunctions(calledFunction);
378 }
379 }
380 }
381 return calledFunctions;
382}
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition LLVMUtil.cpp:365
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::Function Function
Definition BasicTypes.h:89
llvm::Instruction Instruction
Definition BasicTypes.h:91

◆ getCallee()

const Function * SVF::LLVMUtil::getCallee ( const CallBase cs)
inline

Definition at line 100 of file LLVMUtil.h.

101{
102 // FIXME: do we need to strip-off the casts here to discover more library functions
103 return SVFUtil::dyn_cast<Function>(cs->getCalledOperand()->stripPointerCasts());
104}

◆ getDataLayout()

static DataLayout * SVF::LLVMUtil::getDataLayout ( Module mod)
inlinestatic

Definition at line 319 of file LLVMUtil.h.

320{
321 static DataLayout *dl = nullptr;
322 if (dl == nullptr)
323#if LLVM_VERSION_MAJOR >= 19
324 dl = new DataLayout(mod->getDataLayout());
325#else
326 dl = new DataLayout(mod);
327#endif
328 return dl;
329}
llvm::DataLayout DataLayout
Definition BasicTypes.h:112

◆ getDoubleValue()

double SVF::LLVMUtil::getDoubleValue ( const ConstantFP fpValue)
inline

Definition at line 57 of file LLVMUtil.h.

58{
59 double dval = 0;
60 if (fpValue->isNormalFP())
61 {
62 const llvm::fltSemantics& semantics = fpValue->getValueAPF().getSemantics();
63 if (&semantics == &llvm::APFloat::IEEEhalf() ||
64 &semantics == &llvm::APFloat::IEEEsingle() ||
65 &semantics == &llvm::APFloat::IEEEdouble() ||
66 &semantics == &llvm::APFloat::IEEEquad() ||
67 &semantics == &llvm::APFloat::x87DoubleExtended())
68 {
69 dval = fpValue->getValueAPF().convertToDouble();
70 }
71 else
72 {
73 assert (false && "Unsupported floating point type");
74 abort();
75 }
76 }
77 else
78 {
79 // other cfp type, like isZero(), isInfinity(), isNegative(), etc.
80 // do nothing
81 }
82 return dval;
83}

◆ getFirstUseViaCastInst()

const Value * SVF::LLVMUtil::getFirstUseViaCastInst ( const Value val)

Return the bitcast instruction right next to val, otherwise return nullptr

If type is void* (i8*) and val is immediately used at a bitcast instruction

Definition at line 279 of file LLVMUtil.cpp.

280{
281 assert(SVFUtil::isa<PointerType>(val->getType()) && "this value should be a pointer type!");
283 const Value *latestUse = nullptr;
284 for (const auto &it : val->uses())
285 {
286 if (SVFUtil::isa<BitCastInst>(it.getUser()))
287 latestUse = it.getUser();
288 else
289 latestUse = nullptr;
290 }
291 return latestUse;
292}
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86

◆ getFunObjVar()

const FunObjVar * SVF::LLVMUtil::getFunObjVar ( const std::string &  name)

Definition at line 437 of file LLVMUtil.cpp.

438{
440}
const char *const name
Definition cJSON.h:264
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:270
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:133

◆ getFunReachableBBs()

void SVF::LLVMUtil::getFunReachableBBs ( const Function fun,
std::vector< const SVFBasicBlock * > &  reachableBBs 
)

Get reachable basic block from function entry.

Return reachable bbs from function entry

Definition at line 76 of file LLVMUtil.cpp.

77{
78 assert(!LLVMUtil::isExtCall(fun) && "The calling function cannot be an external function.");
79 //initial DominatorTree
81
83 std::vector<const BasicBlock*> bbVec;
84 bbVec.push_back(&fun->getEntryBlock());
85 while(!bbVec.empty())
86 {
87 const BasicBlock* bb = bbVec.back();
88 bbVec.pop_back();
90 reachableBBs.push_back(svfbb);
91 if(DomTreeNode *dtNode = dt.getNode(const_cast<BasicBlock*>(bb)))
92 {
93 for (DomTreeNode::iterator DI = dtNode->begin(), DE = dtNode->end();
94 DI != DE; ++DI)
95 {
96 const BasicBlock* succbb = (*DI)->getBlock();
97 if(visited.find(succbb)==visited.end())
98 visited.insert(succbb);
99 else
100 continue;
101 bbVec.push_back(succbb);
102 }
103 }
104 }
105}
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb)
Definition LLVMModule.h:301
DominatorTree & getDomTree(const Function *fun)
llvm::DomTreeNode DomTreeNode
Definition BasicTypes.h:141
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:140

◆ getGlobalRep()

const Value * SVF::LLVMUtil::getGlobalRep ( const Value val)

find the unique defined global across multiple modules

Definition at line 441 of file LLVMUtil.cpp.

442{
443 if (const GlobalVariable* gvar = SVFUtil::dyn_cast<GlobalVariable>(val))
444 {
445 if (LLVMModuleSet::getLLVMModuleSet()->hasGlobalRep(gvar))
447 }
448 return val;
449}
GlobalVariable * getGlobalRep(const GlobalVariable *val) const
Definition LLVMModule.h:362
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:137

◆ getHeapAllocHoldingArgPosition()

u32_t SVF::LLVMUtil::getHeapAllocHoldingArgPosition ( const Function fun)

Definition at line 402 of file LLVMUtil.cpp.

403{
405}
s32_t get_alloc_arg_pos(const Function *F)

◆ getIntegerValue()

std::pair< s64_t, u64_t > SVF::LLVMUtil::getIntegerValue ( const ConstantInt intValue)
inline

Definition at line 85 of file LLVMUtil.h.

86{
87 if (intValue->getBitWidth() <= 64 && intValue->getBitWidth() >= 1)
88 return std::make_pair(intValue->getSExtValue(), intValue->getZExtValue());
89 else
90 return std::make_pair(0,0);
91}

◆ getLLVMCallSite()

const CallBase * SVF::LLVMUtil::getLLVMCallSite ( const Value value)
inline

Return LLVM callsite given a value.

Definition at line 94 of file LLVMUtil.h.

95{
96 assert(isCallSite(value) && "not a callsite?");
97 return SVFUtil::cast<CallBase>(value);
98}
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:47

◆ getLLVMFunction()

const Function * SVF::LLVMUtil::getLLVMFunction ( const Value val)
inline

Return LLVM function if this value is.

Definition at line 107 of file LLVMUtil.h.

108{
109 return SVFUtil::dyn_cast<Function>(val->stripPointerCasts());
110}

◆ getNextInsts()

void SVF::LLVMUtil::getNextInsts ( const Instruction curInst,
std::vector< const Instruction * > &  instList 
)

Get the next instructions following control flow.

Definition at line 589 of file LLVMUtil.cpp.

590{
591 if (!curInst->isTerminator())
592 {
593 const Instruction* nextInst = curInst->getNextNode();
596 else
597 instList.push_back(nextInst);
598 }
599 else
600 {
601 const BasicBlock *BB = curInst->getParent();
602 // Visit all successors of BB in the CFG
603 for (succ_const_iterator it = succ_begin(BB), ie = succ_end(BB); it != ie; ++it)
604 {
605 const Instruction* nextInst = &((*it)->front());
607 getNextInsts(nextInst, instList);
608 else
609 instList.push_back(nextInst);
610 }
611 }
612}
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:204
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:589

◆ getNumOfElements()

u32_t SVF::LLVMUtil::getNumOfElements ( const Type ety)

Return size of this object based on LLVM value.

Return size of this Object

Definition at line 297 of file LLVMUtil.cpp.

298{
299 assert(ety && "type is null?");
300 u32_t numOfFields = 1;
301 if (SVFUtil::isa<StructType, ArrayType>(ety))
302 {
305 else
307 }
308 return numOfFields;
309}
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
static Option< bool > ModelArrays
Definition Options.h:178
StInfo * getTypeInfo()
Definition SVFType.h:273
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:164
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:170
unsigned u32_t
Definition GeneralType.h:67

◆ getProgEntryFunction()

const Function * SVF::LLVMUtil::getProgEntryFunction ( Module module)
inline

Get program entry function from module.

Definition at line 428 of file LLVMUtil.h.

429{
430 for (auto it = module.begin(), eit = module.end(); it != eit; ++it)
431 {
432 const Function *fun = &(*it);
433 if (isProgEntryFunction(fun))
434 return (fun);
435 }
436 return nullptr;
437}
bool isProgEntryFunction(const Function *fun)
Check whether a function is an entry function (i.e., main)
Definition LLVMUtil.h:116

◆ getProgFunction()

const Function * SVF::LLVMUtil::getProgFunction ( const std::string &  funName)

Get program entry function from module.

Definition at line 41 of file LLVMUtil.cpp.

42{
43 for (const Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
44 {
45 for (const Function& fun : M)
46 {
47 if (fun.getName() == funName)
48 return &fun;
49 }
50 }
51 return nullptr;
52}
llvm::Module Module
Definition BasicTypes.h:88

◆ getPtrElementType()

static Type * SVF::LLVMUtil::getPtrElementType ( const PointerType pty)
inlinestatic

Definition at line 134 of file LLVMUtil.h.

135{
136#if (LLVM_VERSION_MAJOR < 14)
137 return pty->getPointerElementType();
138#elif (LLVM_VERSION_MAJOR < 17)
139 assert(!pty->isOpaque() && "Opaque Pointer is used, please recompile the source adding '-Xclang -no-opaque-pointers'");
140 return pty->getNonOpaquePointerElementType();
141#else
142 (void)pty; // Suppress warning of unused variable under release build
143 assert(false && "llvm version 17+ only support opaque pointers!");
144 return nullptr;
145#endif
146}

◆ getSourceLoc()

const std::string SVF::LLVMUtil::getSourceLoc ( const Value val)

Get the meta data (line number and file name) info of a LLVM value

Definition at line 454 of file LLVMUtil.cpp.

455{
456 if(val==nullptr) return "{ empty val }";
457
458 std::string str;
459 std::stringstream rawstr(str);
460 rawstr << "{ ";
461
462 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(val))
463 {
464 if (SVFUtil::isa<AllocaInst>(inst))
465 {
466#if LLVM_VERSION_MAJOR >= 20
467 for (llvm::DbgVariableRecord *DVR : llvm::findDVRDeclares(const_cast<Instruction*>(inst)))
468 {
469 llvm::DIVariable *DIVar = DVR->getVariable();
470 rawstr << "\"ln\": " << DIVar->getLine() << ", \"fl\": \"" << DIVar->getFilename().str() << "\"";
471 break;
472 }
473#else
474#if LLVM_VERSION_MAJOR > 16
475 for (llvm::DbgInfoIntrinsic *DII : llvm::findDbgDeclares(const_cast<Instruction*>(inst)))
476#else
478#endif
479 {
480 if (llvm::DbgDeclareInst *DDI = SVFUtil::dyn_cast<llvm::DbgDeclareInst>(DII))
481 {
482 llvm::DIVariable *DIVar = SVFUtil::cast<llvm::DIVariable>(DDI->getVariable());
483 rawstr << "\"ln\": " << DIVar->getLine() << ", \"fl\": \"" << DIVar->getFilename().str() << "\"";
484 break;
485 }
486 }
487#endif
488 }
489 else if (MDNode *N = inst->getMetadata("dbg")) // Here I is an LLVM instruction
490 {
491 llvm::DILocation* Loc = SVFUtil::cast<llvm::DILocation>(N); // DILocation is in DebugInfo.h
492 unsigned Line = Loc->getLine();
493 unsigned Column = Loc->getColumn();
494 std::string File = Loc->getFilename().str();
495 //StringRef Dir = Loc.getDirectory();
496 if(File.empty() || Line == 0)
497 {
498 auto inlineLoc = Loc->getInlinedAt();
499 if(inlineLoc)
500 {
501 Line = inlineLoc->getLine();
502 Column = inlineLoc->getColumn();
503 File = inlineLoc->getFilename().str();
504 }
505 }
506 rawstr << "\"ln\": " << Line << ", \"cl\": " << Column << ", \"fl\": \"" << File << "\"";
507 }
508 }
509 else if (const Argument* argument = SVFUtil::dyn_cast<Argument>(val))
510 {
511 if (argument->getArgNo()%10 == 1)
512 rawstr << argument->getArgNo() << "st";
513 else if (argument->getArgNo()%10 == 2)
514 rawstr << argument->getArgNo() << "nd";
515 else if (argument->getArgNo()%10 == 3)
516 rawstr << argument->getArgNo() << "rd";
517 else
518 rawstr << argument->getArgNo() << "th";
519 rawstr << " arg " << argument->getParent()->getName().str() << " "
520 << getSourceLocOfFunction(argument->getParent());
521 }
522 else if (const GlobalVariable* gvar = SVFUtil::dyn_cast<GlobalVariable>(val))
523 {
524 rawstr << "Glob ";
525 NamedMDNode* CU_Nodes = gvar->getParent()->getNamedMetadata("llvm.dbg.cu");
526 if(CU_Nodes)
527 {
528 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i)
529 {
530 llvm::DICompileUnit *CUNode = SVFUtil::cast<llvm::DICompileUnit>(CU_Nodes->getOperand(i));
531 for (llvm::DIGlobalVariableExpression *GV : CUNode->getGlobalVariables())
532 {
533 llvm::DIGlobalVariable * DGV = GV->getVariable();
534
535 if(DGV->getName() == gvar->getName())
536 {
537 rawstr << "\"ln\": " << DGV->getLine() << ", \"fl\": \"" << DGV->getFilename().str() << "\"";
538 }
539
540 }
541 }
542 }
543 }
544 else if (const Function* func = SVFUtil::dyn_cast<Function>(val))
545 {
547 }
548 else if (const BasicBlock* bb = SVFUtil::dyn_cast<BasicBlock>(val))
549 {
550 auto nonPhiIt = bb->getFirstNonPHIIt();
551 rawstr << "\"basic block\": " << bb->getName().str() << ", \"location\": " << getSourceLoc(nonPhiIt != bb->end() ? &*nonPhiIt : nullptr);
552 }
554 {
555 rawstr << "constant data";
556 }
557 else
558 {
559 rawstr << "N/A";
560 }
561 rawstr << " }";
562
563 if(rawstr.str()=="{ }")
564 return "";
565 return rawstr.str();
566}
else
Definition cJSON.cpp:2292
for(i=0;a &&(i<(size_t) count);i++)
Definition cJSON.cpp:2569
const std::string getSourceLocOfFunction(const Function *F)
Definition LLVMUtil.cpp:572
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:378
llvm::NamedMDNode NamedMDNode
LLVM metadata and debug information.
Definition BasicTypes.h:115
llvm::Argument Argument
Definition BasicTypes.h:152
llvm::MDNode MDNode
Definition BasicTypes.h:116

◆ getSourceLocOfFunction()

const std::string SVF::LLVMUtil::getSourceLocOfFunction ( const Function F)

Get source code line number of a function according to debug info

Definition at line 572 of file LLVMUtil.cpp.

573{
574 std::string str;
575 std::stringstream rawstr(str);
576 /*
577 * https://reviews.llvm.org/D18074?id=50385
578 * looks like the relevant
579 */
580 if (llvm::DISubprogram *SP = F->getSubprogram())
581 {
582 if (SP->describes(F))
583 rawstr << "\"ln\": " << SP->getLine() << ", \"file\": \"" << SP->getFilename().str() << "\"";
584 }
585 return rawstr.str();
586}

◆ isArgOfUncalledFunction()

bool SVF::LLVMUtil::isArgOfUncalledFunction ( const Value val)
inline

Return true if the argument in a function does not have a caller.

Definition at line 191 of file LLVMUtil.h.

192{
193 return SVFUtil::isa<Argument>(val)
194 && isNoCallerFunction(SVFUtil::cast<Argument>(val)->getParent());
195}
bool isNoCallerFunction(const Function *fun)
Function does not have any possible caller in the call graph.
Definition LLVMUtil.h:185

◆ isBinaryConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isBinaryConstantExpr ( const Value val)
inline

Definition at line 296 of file LLVMUtil.h.

297{
298 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
299 {
300 if ((constExpr->getOpcode() >= Instruction::BinaryOpsBegin) &&
301 (constExpr->getOpcode() <= Instruction::BinaryOpsEnd))
302 return constExpr;
303 }
304 return nullptr;
305}
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124

◆ isBlackholeSym()

bool SVF::LLVMUtil::isBlackholeSym ( const Value val)
inline

Check whether this value is a black hole.

Definition at line 123 of file LLVMUtil.h.

124{
125 return SVFUtil::isa<UndefValue>(val);
126}

◆ isCallSite() [1/2]

bool SVF::LLVMUtil::isCallSite ( const Instruction inst)
inline

Whether an instruction is a call or invoke instruction.

Definition at line 47 of file LLVMUtil.h.

48{
49 return SVFUtil::isa<CallBase>(inst);
50}

◆ isCallSite() [2/2]

bool SVF::LLVMUtil::isCallSite ( const Value val)
inline

Whether an instruction is a call or invoke instruction.

Definition at line 52 of file LLVMUtil.h.

53{
54 return SVFUtil::isa<CallBase>(val);
55}

◆ isCastConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isCastConstantExpr ( const Value val)
inline

Definition at line 251 of file LLVMUtil.h.

252{
253 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
254 {
255 if (constExpr->getOpcode() == Instruction::BitCast)
256 return constExpr;
257 }
258 return nullptr;
259}

◆ isCmpConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isCmpConstantExpr ( const Value val)
inline

Definition at line 285 of file LLVMUtil.h.

286{
287 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
288 {
289 if (constExpr->getOpcode() == Instruction::ICmp ||
290 constExpr->getOpcode() == Instruction::FCmp)
291 return constExpr;
292 }
293 return nullptr;
294}

◆ isConstantObjSym()

bool SVF::LLVMUtil::isConstantObjSym ( const Value val)

Check whether this value points-to a constant object.

Check whether this value points-to a constant object

Definition at line 747 of file CppUtil.cpp.

748{
749 if (const GlobalVariable* v = SVFUtil::dyn_cast<GlobalVariable>(val))
750 {
752 return false;
753 else if (!v->hasInitializer())
754 {
755 return !v->isExternalLinkage(v->getLinkage());
756 }
757 else
758 {
759 StInfo *stInfo = LLVMModuleSet::getLLVMModuleSet()->getSVFType(v->getInitializer()->getType())->getTypeInfo();
760 const std::vector<const SVFType*> &fields = stInfo->getFlattenFieldTypes();
761 for (std::vector<const SVFType*>::const_iterator it = fields.begin(), eit = fields.end(); it != eit; ++it)
762 {
763 const SVFType* elemTy = *it;
764 assert(!SVFUtil::isa<SVFFunctionType>(elemTy) && "Initializer of a global is a function?");
765 if (SVFUtil::isa<SVFPointerType>(elemTy))
766 return false;
767 }
768
769 return v->isConstant();
770 }
771 }
773}
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition SVFType.h:131
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336

◆ isConstDataOrAggData()

bool SVF::LLVMUtil::isConstDataOrAggData ( const Value val)
inline

Return true if the value refers to constant data, e.g., i32 0.

Definition at line 378 of file LLVMUtil.h.

379{
380 return SVFUtil::isa<ConstantData, ConstantAggregate,
382}
llvm::ConstantData ConstantData
Definition BasicTypes.h:120
llvm::MetadataAsValue MetadataAsValue
Definition BasicTypes.h:106
llvm::ConstantAggregate ConstantAggregate
Definition BasicTypes.h:121
llvm::BlockAddress BlockAddress
Definition BasicTypes.h:95

◆ isExtCall()

bool SVF::LLVMUtil::isExtCall ( const Function fun)

Definition at line 385 of file LLVMUtil.cpp.

386{
387 return fun && LLVMModuleSet::getLLVMModuleSet()->is_ext(fun);
388}
bool is_ext(const Function *F)

◆ isGepConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isGepConstantExpr ( const Value val)
inline

Return corresponding constant expression, otherwise return nullptr.

Definition at line 221 of file LLVMUtil.h.

222{
223 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
224 {
225 if (constExpr->getOpcode() == Instruction::GetElementPtr)
226 return constExpr;
227 }
228 return nullptr;
229}

◆ isHeapAllocExtCall()

bool SVF::LLVMUtil::isHeapAllocExtCall ( const Instruction inst)
inline

Definition at line 406 of file LLVMUtil.h.

407{
409}
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition LLVMUtil.cpp:649
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:664

◆ isHeapAllocExtCallViaArg()

bool SVF::LLVMUtil::isHeapAllocExtCallViaArg ( const Instruction inst)

Definition at line 664 of file LLVMUtil.cpp.

665{
666 if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
667 {
668 const Function* fun = call->getCalledFunction();
669 return fun &&
671 }
672 else
673 {
674 return false;
675 }
676}
bool is_arg_alloc(const Function *F)

◆ isHeapAllocExtCallViaRet()

bool SVF::LLVMUtil::isHeapAllocExtCallViaRet ( const Instruction inst)

Definition at line 649 of file LLVMUtil.cpp.

650{
652 bool isPtrTy = inst->getType()->isPointerTy();
653 if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
654 {
655 const Function* fun = call->getCalledFunction();
656 return fun && isPtrTy &&
657 (pSet->is_alloc(fun) ||
658 pSet->is_realloc(fun));
659 }
660 else
661 return false;
662}

◆ isHeapObj()

bool SVF::LLVMUtil::isHeapObj ( const Value val)

Check if a given value represents a heap object.

Parameters
valThe value to check.
Returns
True if the value represents a heap object, false otherwise.

Definition at line 698 of file LLVMUtil.cpp.

699{
700 // Check if the value is an argument in the program entry function
702 {
703 // Return true if the value does not have a first use via cast instruction
705 }
706 // Check if the value is an instruction and if it is a heap allocation external call
707 else if (SVFUtil::isa<Instruction>(val) &&
708 LLVMUtil::isHeapAllocExtCall(SVFUtil::cast<Instruction>(val)))
709 {
710 return true;
711 }
712 // Return false if none of the above conditions are met
713 return false;
714}
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:279
bool isHeapAllocExtCall(const Instruction *inst)
Definition LLVMUtil.h:406
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition LLVMUtil.h:170

◆ isInt2PtrConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isInt2PtrConstantExpr ( const Value val)
inline

Definition at line 231 of file LLVMUtil.h.

232{
233 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
234 {
235 if (constExpr->getOpcode() == Instruction::IntToPtr)
236 return constExpr;
237 }
238 return nullptr;
239}

◆ isIntrinsicFun()

bool SVF::LLVMUtil::isIntrinsicFun ( const Function func)

Definition at line 191 of file LLVMUtil.cpp.

192{
193 if (func && (func->getIntrinsicID() == llvm::Intrinsic::donothing ||
194 func->getIntrinsicID() == llvm::Intrinsic::dbg_declare ||
195 func->getIntrinsicID() == llvm::Intrinsic::dbg_label ||
196 func->getIntrinsicID() == llvm::Intrinsic::dbg_value))
197 {
198 return true;
199 }
200 return false;
201}

◆ isIntrinsicInst()

bool SVF::LLVMUtil::isIntrinsicInst ( const Instruction inst)

Return true if it is an intrinsic instruction.

Definition at line 204 of file LLVMUtil.cpp.

205{
206 if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
207 {
208 const Function* func = call->getCalledFunction();
209 if (isIntrinsicFun(func))
210 {
211 return true;
212 }
213 }
214 return false;
215}
bool isIntrinsicFun(const Function *func)
Definition LLVMUtil.cpp:191

◆ isIRFile()

bool SVF::LLVMUtil::isIRFile ( const std::string &  filename)

Check whether a file is an LLVM IR file.

Definition at line 316 of file LLVMUtil.cpp.

317{
318 llvm::LLVMContext context;
319 llvm::SMDiagnostic err;
320
321 // Parse the input LLVM IR file into a module
322 std::unique_ptr<llvm::Module> module = llvm::parseIRFile(filename, err, context);
323
324 // Check if the parsing succeeded
325 if (!module)
326 {
327 err.print("isIRFile", llvm::errs());
328 return false; // Not an LLVM IR file
329 }
330
331 return true; // It is an LLVM IR file
332}

◆ isMemcpyExtFun()

bool SVF::LLVMUtil::isMemcpyExtFun ( const Function fun)

Definition at line 390 of file LLVMUtil.cpp.

391{
392 return fun && LLVMModuleSet::getLLVMModuleSet()->is_memcpy(fun);
393}
bool is_memcpy(const Function *F)

◆ isMemsetExtFun()

bool SVF::LLVMUtil::isMemsetExtFun ( const Function fun)

Definition at line 396 of file LLVMUtil.cpp.

397{
398 return fun && LLVMModuleSet::getLLVMModuleSet()->is_memset(fun);
399}
bool is_memset(const Function *F)

◆ isNoCallerFunction()

bool SVF::LLVMUtil::isNoCallerFunction ( const Function fun)
inline

Function does not have any possible caller in the call graph.

Return true if the function does not have a caller (either it is a main function or a dead function)

Definition at line 185 of file LLVMUtil.h.

186{
187 return isUncalledFunction(fun) || LLVMUtil::isProgEntryFunction(fun);
188}

◆ isNonInstricCallSite()

bool SVF::LLVMUtil::isNonInstricCallSite ( const Instruction inst)

Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.

Definition at line 736 of file LLVMUtil.cpp.

737{
738 bool res = false;
739
740 if(isIntrinsicInst(inst))
741 res = false;
742 else
743 res = isCallSite(inst);
744 return res;
745}

◆ isNoPrecessorBasicBlock()

bool SVF::LLVMUtil::isNoPrecessorBasicBlock ( const BasicBlock bb)
inline

Basic block does not have predecessors map-1.cpp.bc try.cont: ; No predecessors! call void @llvm.trap() unreachable

Definition at line 341 of file LLVMUtil.h.

342{
343 return bb != &bb->getParent()->getEntryBlock() &&
344 pred_empty(bb);
345}

◆ isNullPtrSym()

bool SVF::LLVMUtil::isNullPtrSym ( const Value val)
inline

Check whether this value is a black hole.

Definition at line 129 of file LLVMUtil.h.

130{
131 return SVFUtil::dyn_cast<ConstantPointerNull>(val);
132}

◆ isObject()

bool SVF::LLVMUtil::isObject ( const Value ref)

Return true if this value refers to a object.

A value represents an object if it is 1) function, 2) global 3) stack 4) heap

Definition at line 61 of file LLVMUtil.cpp.

62{
63 if (SVFUtil::isa<Instruction>(ref) && isHeapAllocExtCallViaRet(SVFUtil::cast<Instruction>(ref)))
64 return true;
65 if (SVFUtil::isa<GlobalVariable>(ref))
66 return true;
67 if (SVFUtil::isa<Function, AllocaInst>(ref))
68 return true;
69
70 return false;
71}

◆ isProgEntryFunction()

bool SVF::LLVMUtil::isProgEntryFunction ( const Function fun)
inline

Check whether a function is an entry function (i.e., main)

Definition at line 116 of file LLVMUtil.h.

117{
118 const char* main_name=Options::SVFMain() ? "svf.main" : "main";
119 return fun && fun->getName() == main_name;
120}

◆ isPtr2IntConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isPtr2IntConstantExpr ( const Value val)
inline

Definition at line 241 of file LLVMUtil.h.

242{
243 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
244 {
245 if (constExpr->getOpcode() == Instruction::PtrToInt)
246 return constExpr;
247 }
248 return nullptr;
249}

◆ isPtrInUncalledFunction()

bool SVF::LLVMUtil::isPtrInUncalledFunction ( const Value value)

Return true if this is value in a dead function (function without any caller)

Return true if this is a value in a dead function (function without any caller)

Definition at line 176 of file LLVMUtil.cpp.

177{
178 if(const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
179 {
180 if(isUncalledFunction(inst->getParent()->getParent()))
181 return true;
182 }
183 else if(const Argument* arg = SVFUtil::dyn_cast<Argument>(value))
184 {
185 if(isUncalledFunction(arg->getParent()))
186 return true;
187 }
188 return false;
189}

◆ isSelectConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isSelectConstantExpr ( const Value val)
inline

Definition at line 261 of file LLVMUtil.h.

262{
263 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
264 {
265 if (constExpr->getOpcode() == Instruction::Select)
266 return constExpr;
267 }
268 return nullptr;
269}

◆ isStackAllocExtCall()

bool SVF::LLVMUtil::isStackAllocExtCall ( const Instruction inst)
inline

Definition at line 413 of file LLVMUtil.h.

414{
415 return isStackAllocExtCallViaRet(inst);
416}
bool isStackAllocExtCallViaRet(const Instruction *inst)
Definition LLVMUtil.cpp:678

◆ isStackAllocExtCallViaRet()

bool SVF::LLVMUtil::isStackAllocExtCallViaRet ( const Instruction inst)

Definition at line 678 of file LLVMUtil.cpp.

679{
681 bool isPtrTy = inst->getType()->isPointerTy();
682 if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
683 {
684 const Function* fun = call->getCalledFunction();
685 return fun && isPtrTy &&
686 pSet->is_alloc_stack_ret(fun);
687 }
688 else
689 return false;
690}

◆ isStackObj()

bool SVF::LLVMUtil::isStackObj ( const Value val)
Parameters
valThe value to check.
Returns
True if the value represents a stack object, false otherwise.

Definition at line 720 of file LLVMUtil.cpp.

721{
722 if (SVFUtil::isa<AllocaInst>(val))
723 {
724 return true;
725 }
726 // Check if the value is an instruction and if it is a stack allocation external call
727 else if (SVFUtil::isa<Instruction>(val) &&
728 LLVMUtil::isStackAllocExtCall(SVFUtil::cast<Instruction>(val)))
729 {
730 return true;
731 }
732 // Return false if none of the above conditions are met
733 return false;
734}
bool isStackAllocExtCall(const Instruction *inst)
Definition LLVMUtil.h:413

◆ isTruncConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isTruncConstantExpr ( const Value val)
inline

Definition at line 271 of file LLVMUtil.h.

272{
273 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
274 {
275 if (constExpr->getOpcode() == Instruction::Trunc ||
276 constExpr->getOpcode() == Instruction::FPTrunc ||
277 constExpr->getOpcode() == Instruction::ZExt ||
278 constExpr->getOpcode() == Instruction::SExt ||
279 constExpr->getOpcode() == Instruction::FPExt)
280 return constExpr;
281 }
282 return nullptr;
283}

◆ isUnaryConstantExpr()

const ConstantExpr * SVF::LLVMUtil::isUnaryConstantExpr ( const Value val)
inline

Definition at line 307 of file LLVMUtil.h.

308{
309 if (const ConstantExpr* constExpr = SVFUtil::dyn_cast<ConstantExpr>(val))
310 {
311 if ((constExpr->getOpcode() >= Instruction::UnaryOpsBegin) &&
312 (constExpr->getOpcode() <= Instruction::UnaryOpsEnd))
313 return constExpr;
314 }
315 return nullptr;
316}

◆ isUncalledFunction()

bool SVF::LLVMUtil::isUncalledFunction ( const Function fun)

whether this is a function without any possible caller?

Method for dead function, which does not have any possible caller function address is not taken and never be used in call or invoke instruction

Return true if this is a function without any possible caller

Definition at line 159 of file LLVMUtil.cpp.

160{
161 if(fun->hasAddressTaken())
162 return false;
164 return false;
165 for (Value::const_user_iterator i = fun->user_begin(), e = fun->user_end(); i != e; ++i)
166 {
168 return false;
169 }
170 return true;
171}

◆ processArguments()

void SVF::LLVMUtil::processArguments ( int  argc,
char **  argv,
int arg_num,
char **  arg_value,
std::vector< std::string > &  moduleNameVec 
)

Parse argument for multi-module analysis.

Get the names of all modules into a vector And process arguments

Definition at line 337 of file LLVMUtil.cpp.

339{
340 bool first_ir_file = true;
341 for (int i = 0; i < argc; ++i)
342 {
343 std::string argument(argv[i]);
345 {
346 if (find(moduleNameVec.begin(), moduleNameVec.end(), argument)
347 == moduleNameVec.end())
348 moduleNameVec.push_back(argument);
349 if (first_ir_file)
350 {
352 arg_num++;
353 first_ir_file = false;
354 }
355 }
356 else
357 {
359 arg_num++;
360 }
361 }
362}
bool isIRFile(const std::string &filename)
Check whether a file is an LLVM IR file.
Definition LLVMUtil.cpp:316

◆ restoreFuncName()

std::string SVF::LLVMUtil::restoreFuncName ( std::string  funcName)

Definition at line 408 of file LLVMUtil.cpp.

409{
410 assert(!funcName.empty() && "Empty function name");
411 // Some function names change due to mangling, such as "fopen" to "\01_fopen" on macOS.
412 // Since C function names cannot include '.', change the function name from llvm.memcpy.p0i8.p0i8.i64 to llvm_memcpy_p0i8_p0i8_i64."
413 bool hasSpecialPrefix = funcName[0] == '\01';
414 bool hasDot = funcName.find('.') != std::string::npos;
415
416 if (!hasDot && !hasSpecialPrefix)
417 return funcName;
418
419 // Remove prefix "\01_" or "\01"
421 {
422 const std::string prefix1 = "\01_";
423 const std::string prefix2 = "\01";
424 if (funcName.substr(0, prefix1.length()) == prefix1)
425 funcName = funcName.substr(prefix1.length());
426 else if (funcName.substr(0, prefix2.length()) == prefix2)
427 funcName = funcName.substr(prefix2.length());
428 }
429 // Replace '.' with '_'
430 if (hasDot)
431 std::replace(funcName.begin(), funcName.end(), '.', '_');
432
433 return funcName;
434}

◆ stripAllCasts()

const Value * SVF::LLVMUtil::stripAllCasts ( const Value val)

Strip off the all casts.

Strip all casts

Definition at line 251 of file LLVMUtil.cpp.

252{
253 while (true)
254 {
255 if (const CastInst *ci = SVFUtil::dyn_cast<CastInst>(val))
256 {
257 val = ci->getOperand(0);
258 }
259 else if (const ConstantExpr *ce = SVFUtil::dyn_cast<ConstantExpr>(val))
260 {
261 if(ce->isCast())
262 val = ce->getOperand(0);
263 else
264 return val;
265 }
266 else
267 {
268 return val;
269 }
270 }
271 return nullptr;
272}
llvm::CastInst CastInst
Definition BasicTypes.h:165

◆ stripConstantCasts()

const Value * SVF::LLVMUtil::stripConstantCasts ( const Value val)

Strip off the constant casts.

Strip constant casts

Definition at line 220 of file LLVMUtil.cpp.

221{
222 if (SVFUtil::isa<GlobalValue>(val) || isInt2PtrConstantExpr(val))
223 return val;
224 else if (const ConstantExpr *CE = SVFUtil::dyn_cast<ConstantExpr>(val))
225 {
226 if (Instruction::isCast(CE->getOpcode()))
227 return stripConstantCasts(CE->getOperand(0));
228 }
229 return val;
230}
const Value * stripConstantCasts(const Value *val)
Strip off the constant casts.
Definition LLVMUtil.cpp:220
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:231

◆ viewCFG()

void SVF::LLVMUtil::viewCFG ( const Function fun)

Definition at line 232 of file LLVMUtil.cpp.

233{
234 if (fun != nullptr)
235 {
236 fun->viewCFG();
237 }
238}

◆ viewCFGOnly()

void SVF::LLVMUtil::viewCFGOnly ( const Function fun)

Definition at line 240 of file LLVMUtil.cpp.

241{
242 if (fun != nullptr)
243 {
244 fun->viewCFGOnly();
245 }
246}