From 1d953bebe135a74fda947b440cc213865a275618 Mon Sep 17 00:00:00 2001 From: jumormt Date: Wed, 6 Dec 2023 15:28:06 +1100 Subject: [PATCH 1/2] do not connect return BB edge for no return function that does not have an exit BB --- svf/lib/Util/CFBasicBlockGBuilder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/svf/lib/Util/CFBasicBlockGBuilder.cpp b/svf/lib/Util/CFBasicBlockGBuilder.cpp index e9005d9ae..efa9073c4 100644 --- a/svf/lib/Util/CFBasicBlockGBuilder.cpp +++ b/svf/lib/Util/CFBasicBlockGBuilder.cpp @@ -194,6 +194,8 @@ void CFBasicBlockGBuilder::addInterProceduralEdge(ICFG *icfg, { if (const RetCFGEdge *retEdge = SVFUtil::dyn_cast(icfgEdge)) { + // no return function does not have an exit BB + if(!retEdge->getSrcNode()->getBB()) continue; CFBasicBlockEdge *pEdge = new CFBasicBlockEdge(bbToNodes[retEdge->getSrcNode()->getBB()].back(), bbNodes.second[i], retEdge); From d2c158bb48712a0c47309c0b46dff4ef847da179 Mon Sep 17 00:00:00 2001 From: jumormt Date: Wed, 6 Dec 2023 15:55:20 +1100 Subject: [PATCH 2/2] set last bb as exit bb for no return func --- svf-llvm/lib/LLVMModule.cpp | 4 ++++ svf/include/SVFIR/SVFValue.h | 7 +------ svf/lib/Graphs/ICFG.cpp | 6 +----- svf/lib/SVFIR/SVFValue.cpp | 8 ++++++++ svf/lib/Util/CFBasicBlockGBuilder.cpp | 4 ++-- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index bec5118a6..ee2ea5246 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -364,6 +364,10 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func) LLVMUtil::getPrevInsts(inst, getSVFInstruction(inst)->getPredInstructions()); } } + // For no return functions, we set the last block as exit BB + // This ensures that each function that has definition must have an exit BB + if(svfFun->exitBlock == nullptr && svfFun->hasBasicBlock()) svfFun->setExitBlock( + const_cast(svfFun->back())); } diff --git a/svf/include/SVFIR/SVFValue.h b/svf/include/SVFIR/SVFValue.h index 681a8ffcf..506a0eb36 100644 --- a/svf/include/SVFIR/SVFValue.h +++ b/svf/include/SVFIR/SVFValue.h @@ -415,12 +415,7 @@ class SVFFunction : public SVFValue /// Carefully! when you call getExitBB, you need ensure the function has return instruction /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 - inline const SVFBasicBlock* getExitBB() const - { - assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); - assert((hasReturn() && exitBlock) && "ensure the function has a single basic block containing a return instruction!"); - return exitBlock; - } + const SVFBasicBlock* getExitBB() const; void setExitBlock(SVFBasicBlock *bb); diff --git a/svf/lib/Graphs/ICFG.cpp b/svf/lib/Graphs/ICFG.cpp index 76fc4a783..bae8bff3e 100644 --- a/svf/lib/Graphs/ICFG.cpp +++ b/svf/lib/Graphs/ICFG.cpp @@ -54,11 +54,7 @@ FunExitICFGNode::FunExitICFGNode(NodeID id, const SVFFunction* f) // if function is implemented if (f->begin() != f->end()) { - // ensure the enclosing function has exit basic block - if (f->hasReturn()) - { - bb = f->getExitBB(); - } + bb = f->getExitBB(); } } diff --git a/svf/lib/SVFIR/SVFValue.cpp b/svf/lib/SVFIR/SVFValue.cpp index 106823254..be463e529 100644 --- a/svf/lib/SVFIR/SVFValue.cpp +++ b/svf/lib/SVFIR/SVFValue.cpp @@ -190,6 +190,14 @@ bool SVFFunction::isVarArg() const return varArg; } +const SVFBasicBlock *SVFFunction::getExitBB() const +{ + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + assert((!hasReturn() || exitBlock->back()->isRetInst()) && "last inst must be return inst"); + assert(exitBlock && "must have an exitBlock"); + return exitBlock; +} + void SVFFunction::setExitBlock(SVFBasicBlock *bb) { assert(!exitBlock && "have already set exit Basicblock!"); diff --git a/svf/lib/Util/CFBasicBlockGBuilder.cpp b/svf/lib/Util/CFBasicBlockGBuilder.cpp index efa9073c4..cdef899de 100644 --- a/svf/lib/Util/CFBasicBlockGBuilder.cpp +++ b/svf/lib/Util/CFBasicBlockGBuilder.cpp @@ -194,8 +194,8 @@ void CFBasicBlockGBuilder::addInterProceduralEdge(ICFG *icfg, { if (const RetCFGEdge *retEdge = SVFUtil::dyn_cast(icfgEdge)) { - // no return function does not have an exit BB - if(!retEdge->getSrcNode()->getBB()) continue; + // no return function + if(!retEdge->getSrcNode()->getFun()->hasReturn()) continue; CFBasicBlockEdge *pEdge = new CFBasicBlockEdge(bbToNodes[retEdge->getSrcNode()->getBB()].back(), bbNodes.second[i], retEdge);