[Cloning] Teach CloneModule about personality functions
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 30 Jun 2015 22:14:01 +0000 (22:14 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 30 Jun 2015 22:14:01 +0000 (22:14 +0000)
CloneModule didn't take into account that it needed to remap the value
using values in the module.

This fixes PR23992.

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

lib/Transforms/Utils/CloneModule.cpp
unittests/Transforms/Utils/Cloning.cpp

index 269332206daa284f63f65d472cd9d5c6c1a0c9d8..61f1811e7b4ad73ad2cfadcb927a0260b31e3a6a 100644 (file)
@@ -99,7 +99,11 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
 
       SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
       CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns);
+
     }
+
+    if (I->hasPersonalityFn())
+      F->setPersonalityFn(MapValue(I->getPersonalityFn(), VMap));
   }
 
   // And aliases
index 18d3ca626753593cc225c74d6624c4cefed617b4..e2671499e812aa433c9ed75a2741b92ddd7f8f16 100644 (file)
@@ -415,4 +415,39 @@ TEST_F(CloneFunc, DebugIntrinsics) {
   }
 }
 
+class CloneModule : public ::testing::Test {
+protected:
+  void SetUp() override {
+    SetupModule();
+    CreateOldModule();
+    CreateNewModule();
+  }
+
+  void SetupModule() { OldM = new Module("", C); }
+
+  void CreateOldModule() {
+    IRBuilder<> IBuilder(C);
+
+    auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
+    auto *PersFn = Function::Create(FuncType, GlobalValue::ExternalLinkage,
+                                    "persfn", OldM);
+    auto *F =
+        Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
+    F->setPersonalityFn(PersFn);
+    auto *Entry = BasicBlock::Create(C, "", F);
+    IBuilder.SetInsertPoint(Entry);
+    IBuilder.CreateRetVoid();
+  }
+
+  void CreateNewModule() { NewM = llvm::CloneModule(OldM); }
+
+  LLVMContext C;
+  Module *OldM;
+  Module *NewM;
+};
+
+TEST_F(CloneModule, Verify) {
+  EXPECT_FALSE(verifyModule(*NewM));
+}
+
 }