-
Notifications
You must be signed in to change notification settings - Fork 436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix a bug: 'getExitBB' of SVFFunction may get incorrect exit block. #1262
Changes from 2 commits
5cce7dd
5443381
965c5a1
57ff663
0da2dd6
7a0b4d6
a7e0a0f
dcaf079
5a9fd4f
408dfc0
f899a36
6ea914d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -320,6 +320,15 @@ class SVFFunction : public SVFValue | |
std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function | ||
std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function | ||
std::vector<std::string> annotations; /// annotations of this function | ||
SVFBasicBlock *entryBlock; /// entry BasicBlock of this function | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we don't need an entryBlock because it is always the first block in allBBs. This is consistent with LLVM's API called getEntryBlock(), which simply returns the front of its basic blocks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for your review. Yeah, here is redundant. |
||
SVFBasicBlock *exitBlock; /// exit BasicBlock of this function | ||
SVFBasicBlock *uniqueExitBlock; /// multi exit BasicBlocks connect to a single unique Exit Block | ||
|
||
private: | ||
/// get dummy exit basic block. if not exits, then create it, else return | ||
/// @param exitBB one of multi exit Basic Blocks | ||
/// @return the dummy exit basic block | ||
SVFBasicBlock* getUniqueExitBlock(SVFBasicBlock* exitBB); | ||
|
||
protected: | ||
///@{ attributes to be set only through Module builders e.g., LLVMModule | ||
|
@@ -409,15 +418,28 @@ class SVFFunction : public SVFValue | |
inline const SVFBasicBlock* getEntryBlock() const | ||
{ | ||
assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); | ||
return allBBs.front(); | ||
assert(entryBlock && "have not yet set entry Basicblock"); | ||
return entryBlock; | ||
} | ||
|
||
inline void setEntryBlock(SVFBasicBlock *bb) | ||
{ | ||
assert(!entryBlock && "function already has entry Basicblock."); | ||
entryBlock = bb; | ||
} | ||
|
||
inline const SVFBasicBlock* getExitBB() const | ||
{ | ||
assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); | ||
return allBBs.back(); | ||
assert(exitBlock && "have not yet set exit Basicblock"); | ||
assert((!uniqueExitBlock || uniqueExitBlock == exitBlock) && "unique exit basic block must be null or just equal to exit block"); | ||
return exitBlock; | ||
} | ||
|
||
/// set exit basic block, if multi exit basic blocks exist, | ||
/// then create a unique basic block, and set the unique exit basic block | ||
void setExitBlock(SVFBasicBlock *bb); | ||
|
||
inline const SVFBasicBlock* front() const | ||
{ | ||
return getEntryBlock(); | ||
|
@@ -520,6 +542,7 @@ class SVFBasicBlock : public SVFValue | |
friend class SVFIRWriter; | ||
friend class SVFIRReader; | ||
friend class SVFIRBuilder; | ||
friend class SVFFunction; | ||
|
||
public: | ||
typedef std::vector<const SVFInstruction*>::const_iterator const_iterator; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should consider the unreachable blocks introduced by instructions such as exit(0). These blocks are not function exit blocks and cannot be connected to the unique exit block. A valid function exit should end with a return instruction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my knowledge, each llvm function can only have one return instruction. This means there should be only one function exit block? In that way, no extra unique function exit block is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we do not need an extra unique exit block
theoretically
.I would like to improve robustness of SVF: when someone generate a
valid
bitcode file like above, we should handle it correctly.And I have a question, why my first pr can't pass the testcases. I guess the following assert leads to fail to pass the testcase (
maybe multi exit basic block
)Because I have no testcases, so I can only guess the reason...