Do not destroy external linkage when deleting function body
authorPetar Jovanovic <petar.jovanovic@imgtec.com>
Tue, 23 Sep 2014 12:54:19 +0000 (12:54 +0000)
committerPetar Jovanovic <petar.jovanovic@imgtec.com>
Tue, 23 Sep 2014 12:54:19 +0000 (12:54 +0000)
The function deleteBody() converts the linkage to external and thus destroys
original linkage type value. Lack of correct linkage type causes wrong
relocations to be emitted later.
Calling dropAllReferences() instead of deleteBody() will fix the issue.

Differential Revision: http://reviews.llvm.org/D5415

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218302 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bitcode/Reader/BitcodeReader.cpp
unittests/Bitcode/BitReaderTest.cpp

index 80afb56e746bb63c60f497bcf627d615c764e96b..f113c2c71d1d6770f9754b66aa66aef50d77408b 100644 (file)
@@ -3347,7 +3347,7 @@ void BitcodeReader::Dematerialize(GlobalValue *GV) {
   assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
 
   // Just forget the function body, we can remat it later.
   assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
 
   // Just forget the function body, we can remat it later.
-  F->deleteBody();
+  F->dropAllReferences();
 }
 
 std::error_code BitcodeReader::MaterializeModule(Module *M) {
 }
 
 std::error_code BitcodeReader::MaterializeModule(Module *M) {
index a27332b5b3550fee995d5bb1f63b4b9102b55981..04c795038fcaeae9d9670a2ae32692314872eff9 100644 (file)
@@ -58,6 +58,30 @@ static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
   return std::unique_ptr<Module>(ModuleOrErr.get());
 }
 
   return std::unique_ptr<Module>(ModuleOrErr.get());
 }
 
+TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
+  SmallString<1024> Mem;
+
+  LLVMContext Context;
+  std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+      Context, Mem, "define internal i32 @func() {\n"
+                      "ret i32 0\n"
+                    "}\n");
+
+  EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+  M->getFunction("func")->Materialize();
+  EXPECT_FALSE(M->getFunction("func")->empty());
+  EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
+              GlobalValue::InternalLinkage);
+
+  // Check that the linkage type is preserved after dematerialization.
+  M->getFunction("func")->Dematerialize();
+  EXPECT_TRUE(M->getFunction("func")->empty());
+  EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
+              GlobalValue::InternalLinkage);
+  EXPECT_FALSE(verifyModule(*M, &dbgs()));
+}
+
 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
   SmallString<1024> Mem;
 
 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
   SmallString<1024> Mem;