diff options
author | d0k <d0k@91177308-0d34-0410-b5e6-96231b3b80d8> | 2012-09-21 14:34:31 +0000 |
---|---|---|
committer | d0k <d0k@91177308-0d34-0410-b5e6-96231b3b80d8> | 2012-09-21 14:34:31 +0000 |
commit | 839637d7e9fd7b7586322f05c6a5bc713fda3e8e (patch) | |
tree | 764b03dd38d35679b3aa068a6fc4a88e5cb560f9 /lib | |
parent | c050514cf5d7b21921903f559c518f363bda29f6 (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 0ff4664b2e4..2b2c36ba0f3 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; } } |