aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-01-02 07:49:53 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-01-02 07:49:53 +0000
commit47f79bb58e42f1a08a7f388b8b1596ded7d49bbb (patch)
tree8324e159a48ba6691881b0b8f637a51683df8070
parenta86bcfb565bdea5bd45634fd2139ac17172a3500 (diff)
Materialize functions whose basic blocks are used by global variables. Fixes
PR11677. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147425 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp10
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h4
-rw-r--r--unittests/CMakeLists.txt1
-rw-r--r--unittests/VMCore/pr11677.cpp64
4 files changed, 78 insertions, 1 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index b86d6e0883..9d10498943 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -27,6 +27,13 @@
#include "llvm/OperandTraits.h"
using namespace llvm;
+void BitcodeReader::materializeForwardReferencedFunctions() {
+ while (!BlockAddrFwdRefs.empty()) {
+ Function *F = BlockAddrFwdRefs.begin()->first;
+ F->Materialize();
+ }
+}
+
void BitcodeReader::FreeState() {
if (BufferOwned)
delete Buffer;
@@ -2779,6 +2786,9 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
}
// Have the BitcodeReader dtor delete 'Buffer'.
R->setBufferOwned(true);
+
+ R->materializeForwardReferencedFunctions();
+
return M;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 978b15b0f0..952d645a4c 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -184,7 +184,9 @@ public:
~BitcodeReader() {
FreeState();
}
-
+
+ void materializeForwardReferencedFunctions();
+
void FreeState();
/// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 2eff1642c4..3cd7f2f051 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -112,6 +112,7 @@ set(VMCoreSources
VMCore/PassManagerTest.cpp
VMCore/ValueMapTest.cpp
VMCore/VerifierTest.cpp
+ VMCore/pr11677.cpp
)
# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug.
diff --git a/unittests/VMCore/pr11677.cpp b/unittests/VMCore/pr11677.cpp
new file mode 100644
index 0000000000..362eec7763
--- /dev/null
+++ b/unittests/VMCore/pr11677.cpp
@@ -0,0 +1,64 @@
+//===- llvm/unittest/VMCore/pr11677.cpp - Test for blockaddr --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+static Module *makeLLVMModule() {
+ Module* Mod = new Module("test-mem", getGlobalContext());
+
+ FunctionType* FuncTy =
+ FunctionType::get(Type::getVoidTy(Mod->getContext()), false);
+ Function* Func = Function::Create(FuncTy,GlobalValue::ExternalLinkage,
+ "func", Mod);
+
+ BasicBlock* Entry = BasicBlock::Create(Mod->getContext(), "entry", Func);
+ new UnreachableInst(Mod->getContext(), Entry);
+
+ BasicBlock* BB = BasicBlock::Create(Mod->getContext(), "bb", Func);
+ new UnreachableInst(Mod->getContext(), BB);
+
+ PointerType* Int8Ptr = Type::getInt8PtrTy(Mod->getContext());
+ new GlobalVariable(*Mod, Int8Ptr, /*isConstant=*/true,
+ GlobalValue::ExternalLinkage,
+ BlockAddress::get(BB), "table");
+
+ return Mod;
+}
+
+static void writeModuleToBuffer(std::vector<unsigned char> &Buffer) {
+ Module *Mod = makeLLVMModule();
+ BitstreamWriter Stream(Buffer);
+ WriteBitcodeToStream(Mod, Stream);
+}
+
+TEST(PR11677, BlockAddr) {
+ std::vector<unsigned char> Mem;
+ writeModuleToBuffer(Mem);
+ StringRef Data((const char*)&Mem[0], Mem.size());
+ MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Data, "test", false);
+ std::string errMsg;
+ Module *m = getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg);
+ PassManager passes;
+ passes.add(createVerifierPass());
+ passes.run(*m);
+}
+}
+}