summaryrefslogtreecommitdiff
path: root/lib/IR/BasicBlock.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-07 09:15:29 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-07 09:15:29 +0000
commit2822246ecee6237c706730ad519dc394918efe45 (patch)
tree36a25b8484d0f47e28e6f06b74acc66c3a53346b /lib/IR/BasicBlock.cpp
parent2b4a535b701656dfcc14ab362b72fa6664d4d2cd (diff)
[IR] Make getFirstNonPHI return null if the BB is empty
getFirstNonPHI's documentation states that it returns null if there is no non-PHI instruction. However, it instead returns a pointer to the end iterator. The implementation of getFirstNonPHI claims that dereferencing the iterator will result in an assertion failure but this doesn't occur. Instead, machinery like getFirstInsertionPt will attempt to isa<> this invalid memory which results in unpredictable behavior. Instead, make getFirst* return null if no such instruction exists. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241570 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR/BasicBlock.cpp')
-rw-r--r--lib/IR/BasicBlock.cpp51
1 files changed, 22 insertions, 29 deletions
diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp
index 77cb10d5b6b..0a0449434a7 100644
--- a/lib/IR/BasicBlock.cpp
+++ b/lib/IR/BasicBlock.cpp
@@ -163,47 +163,40 @@ CallInst *BasicBlock::getTerminatingMustTailCall() {
}
Instruction* BasicBlock::getFirstNonPHI() {
- BasicBlock::iterator i = begin();
- // All valid basic blocks should have a terminator,
- // which is not a PHINode. If we have an invalid basic
- // block we'll get an assertion failure when dereferencing
- // a past-the-end iterator.
- while (isa<PHINode>(i)) ++i;
- return &*i;
+ for (Instruction &I : *this)
+ if (!isa<PHINode>(I))
+ return &I;
+ return nullptr;
}
Instruction* BasicBlock::getFirstNonPHIOrDbg() {
- BasicBlock::iterator i = begin();
- // All valid basic blocks should have a terminator,
- // which is not a PHINode. If we have an invalid basic
- // block we'll get an assertion failure when dereferencing
- // a past-the-end iterator.
- while (isa<PHINode>(i) || isa<DbgInfoIntrinsic>(i)) ++i;
- return &*i;
+ for (Instruction &I : *this)
+ if (!isa<PHINode>(I) && !isa<DbgInfoIntrinsic>(I))
+ return &I;
+ return nullptr;
}
Instruction* BasicBlock::getFirstNonPHIOrDbgOrLifetime() {
- // All valid basic blocks should have a terminator,
- // which is not a PHINode. If we have an invalid basic
- // block we'll get an assertion failure when dereferencing
- // a past-the-end iterator.
- BasicBlock::iterator i = begin();
- for (;; ++i) {
- if (isa<PHINode>(i) || isa<DbgInfoIntrinsic>(i))
+ for (Instruction &I : *this) {
+ if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
continue;
- const IntrinsicInst *II = dyn_cast<IntrinsicInst>(i);
- if (!II)
- break;
- if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
- II->getIntrinsicID() != Intrinsic::lifetime_end)
- break;
+ if (auto *II = dyn_cast<IntrinsicInst>(&I))
+ if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
+ II->getIntrinsicID() == Intrinsic::lifetime_end)
+ continue;
+
+ return &I;
}
- return &*i;
+ return nullptr;
}
BasicBlock::iterator BasicBlock::getFirstInsertionPt() {
- iterator InsertPt = getFirstNonPHI();
+ Instruction *FirstNonPHI = getFirstNonPHI();
+ if (!FirstNonPHI)
+ return end();
+
+ iterator InsertPt = FirstNonPHI;
if (isa<LandingPadInst>(InsertPt)) ++InsertPt;
return InsertPt;
}