aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-09-21 14:34:31 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-09-21 14:34:31 +0000
commit122f5e5a5b04e3c364d13913c14ee14f9b7ba387 (patch)
tree764b03dd38d35679b3aa068a6fc4a88e5cb560f9
parent01fa41a106ed0ff86c3b9ffe0843679211bf487c (diff)
downloadexternal_llvm-122f5e5a5b04e3c364d13913c14ee14f9b7ba387.zip
external_llvm-122f5e5a5b04e3c364d13913c14ee14f9b7ba387.tar.gz
external_llvm-122f5e5a5b04e3c364d13913c14ee14f9b7ba387.tar.bz2
BitcodeReader: Correctly insert blockaddress constant referring to a already parsed function.
We inserted a placeholder that was never replaced because the function was already visited. Assert that all placeholders have been resolved when tearing down the bitcode reader. Fixes PR13895. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164369 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp28
-rw-r--r--test/Bitcode/blockaddress.ll15
2 files changed, 37 insertions, 6 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 0ff4664..2b2c36b 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -52,6 +52,8 @@ void BitcodeReader::FreeState() {
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
MDKindMap.clear();
+
+ assert(BlockAddrFwdRefs.empty() && "Unresolved blockaddress fwd references");
}
//===----------------------------------------------------------------------===//
@@ -1300,13 +1302,27 @@ bool BitcodeReader::ParseConstants() {
Function *Fn =
dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
-
- GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
- Type::getInt8Ty(Context),
+
+ // If the function is already parsed we can insert the block address right
+ // away.
+ if (!Fn->empty()) {
+ Function::iterator BBI = Fn->begin(), BBE = Fn->end();
+ for (size_t I = 0, E = Record[2]; I != E; ++I) {
+ if (BBI == BBE)
+ return Error("Invalid blockaddress block #");
+ ++BBI;
+ }
+ V = BlockAddress::get(Fn, BBI);
+ } else {
+ // Otherwise insert a placeholder and remember it so it can be inserted
+ // when the function is parsed.
+ GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+ Type::getInt8Ty(Context),
false, GlobalValue::InternalLinkage,
- 0, "");
- BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
- V = FwdRef;
+ 0, "");
+ BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+ V = FwdRef;
+ }
break;
}
}
diff --git a/test/Bitcode/blockaddress.ll b/test/Bitcode/blockaddress.ll
index b9f3341..8ac54be 100644
--- a/test/Bitcode/blockaddress.ll
+++ b/test/Bitcode/blockaddress.ll
@@ -28,3 +28,18 @@ here:
end:
ret void
}
+
+; PR13895
+define void @doitagain(i8** nocapture %pptr) {
+; CHECK: define void @doitagain
+entry:
+ br label %here
+
+here:
+ store i8* blockaddress(@doit, %here), i8** %pptr, align 8
+; CHECK: blockaddress(@doit, %here)
+ br label %end
+
+end:
+ ret void
+}