diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 74f3bbb04598..ee7008074376 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -181,8 +181,20 @@ void CodeGenModule::applyReplacements() { llvm::GlobalValue *Entry = GetGlobalValue(MangledName); if (!Entry) continue; - Entry->replaceAllUsesWith(Replacement); - Entry->eraseFromParent(); + llvm::Function *OldF = cast(Entry); + llvm::Function *NewF = dyn_cast(Replacement); + if (!NewF) { + llvm::ConstantExpr *CE = cast(Replacement); + assert(CE->getOpcode() == llvm::Instruction::BitCast || + CE->getOpcode() == llvm::Instruction::GetElementPtr); + NewF = cast(CE->getOperand(0)); + } + + // Replace old with new, but keep the old order. + OldF->replaceAllUsesWith(Replacement); + NewF->removeFromParent(); + OldF->getParent()->getFunctionList().insertAfter(OldF, NewF); + OldF->eraseFromParent(); } } diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp index 5b29ce5de4b1..59c97b7dca91 100644 --- a/clang/test/CodeGenCXX/destructors.cpp +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -36,13 +36,13 @@ namespace PR7526 { struct allocator_derived : allocator { }; + // CHECK-LABEL: define void @_ZN6PR75263fooEv() + // CHECK: call void {{.*}} @_ZN6PR75269allocatorD2Ev + // CHECK-LABEL: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr // CHECK: call void @__cxa_call_unexpected allocator::~allocator() throw() { foo(); } - // CHECK-LABEL: define void @_ZN6PR75263fooEv() - // CHECK: call void {{.*}} @_ZN6PR75269allocatorD2Ev - void foo() { allocator_derived ad; } @@ -393,16 +393,16 @@ namespace test10 { // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev( // CHECK: ret void - // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::::C"* %this) unnamed_addr - // CHECK: invoke void @_ZN5test31BD2Ev( - // CHECK: call void @_ZN5test31AD2Ev( - // CHECK: ret void - // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 // CHECK: call void @_ZN5test312_GLOBAL__N_11CD2Ev( // CHECK: ret void + // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::::C"* %this) unnamed_addr + // CHECK: invoke void @_ZN5test31BD2Ev( + // CHECK: call void @_ZN5test31AD2Ev( + // CHECK: ret void + // CHECK: declare void @_ZN5test31BD2Ev( // CHECK: declare void @_ZN5test31AD2Ev(