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
This commit is contained in:
Benjamin Kramer 2012-09-21 14:34:31 +00:00
parent 01fa41a106
commit 122f5e5a5b
2 changed files with 37 additions and 6 deletions

View File

@ -52,6 +52,8 @@ void BitcodeReader::FreeState() {
std::vector<Function*>().swap(FunctionsWithBodies); std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear(); DeferredFunctionInfo.clear();
MDKindMap.clear(); MDKindMap.clear();
assert(BlockAddrFwdRefs.empty() && "Unresolved blockaddress fwd references");
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -1300,13 +1302,27 @@ bool BitcodeReader::ParseConstants() {
Function *Fn = Function *Fn =
dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy)); dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record"); if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(), // If the function is already parsed we can insert the block address right
Type::getInt8Ty(Context), // 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, false, GlobalValue::InternalLinkage,
0, ""); 0, "");
BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef)); BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
V = FwdRef; V = FwdRef;
}
break; break;
} }
} }

View File

@ -28,3 +28,18 @@ here:
end: end:
ret void 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
}