aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2012-09-25 17:30:25 -0700
committerDerek Schuff <dschuff@chromium.org>2012-09-25 18:01:23 -0700
commita27c28b1427dc2082ab2b31efdbb25f9fde31b61 (patch)
tree6f3ff025f542ca3f66a1a01cbf239aeef7784511 /lib/Bitcode/Reader/BitcodeReader.cpp
parent0e15ffd8cb1ec642eddb96380660914ff2b007e1 (diff)
parentbc4021f31eaa97ee52655828da3e3de14a39e4a6 (diff)
Merge commit 'bc4021f31eaa97ee52655828da3e3de14a39e4a6'
Conflicts: lib/MC/MCAssembler.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp lib/Target/X86/X86ISelLowering.h
Diffstat (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 9130ddef16..4a11223711 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");
}
//===----------------------------------------------------------------------===//
@@ -197,7 +199,7 @@ namespace {
/// @brief A class for maintaining the slot number definition
/// as a placeholder for the actual definition for forward constants defs.
class ConstantPlaceHolder : public ConstantExpr {
- void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
+ void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION;
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
@@ -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;
}
}