Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -762,8 +762,10 @@ // It would be incorrect to import an appending linkage variable, // since it would cause global constructors/destructors to be // executed multiple times. This should have already been handled - // by linkGlobalValueProto. - llvm_unreachable("Cannot import appending linkage variable"); + // by linkIfNeeded, and we will assert in shouldLinkFromSource + // if we try to import, so we simply return AppendingLinkage here + // as this helper is called more widely in getLinkedToGlobal. + return GlobalValue::AppendingLinkage; case GlobalValue::InternalLinkage: case GlobalValue::PrivateLinkage: @@ -1067,8 +1069,7 @@ // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { - // Caller should have already determined that we can't link from source - // when importing (see comments in linkGlobalValueProto). + // Should have prevented importing for appending linkage in linkIfNeeded. assert(!isPerformingImport()); LinkFromSrc = true; return false; @@ -1396,17 +1397,12 @@ // Handle the ultra special appending linkage case first. assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); - if (SGV->hasAppendingLinkage() && isPerformingImport()) { - // Don't want to append to global_ctors list, for example, when we - // are importing for ThinLTO, otherwise the global ctors and dtors - // get executed multiple times for local variables (the latter causing - // double frees). - DoNotLinkFromSource.insert(SGV); - return false; - } - if (SGV->hasAppendingLinkage()) + if (SGV->hasAppendingLinkage()) { + // Should have prevented importing for appending linkage in linkIfNeeded. + assert(!isPerformingImport()); return linkAppendingVarProto(cast_or_null(DGV), cast(SGV)); + } bool LinkFromSrc = true; Comdat *C = nullptr; @@ -1864,6 +1860,12 @@ GV.hasAvailableExternallyLinkage())) { return false; } + // Don't want to append to global_ctors list, for example, when we + // are importing for ThinLTO, otherwise the global ctors and dtors + // get executed multiple times for local variables (the latter causing + // double frees). + if (GV.hasAppendingLinkage() && isPerformingImport()) + return false; MapValue(&GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); return HasError; } Index: test/Linker/Inputs/funcimport_appending_global.ll =================================================================== --- /dev/null +++ test/Linker/Inputs/funcimport_appending_global.ll @@ -0,0 +1,6 @@ +@v = weak global i8 1 +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}] + +define void @foo() { + ret void +} Index: test/Linker/funcimport_appending_global.ll =================================================================== --- /dev/null +++ test/Linker/funcimport_appending_global.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as -function-summary %s -o %t.bc +; RUN: llvm-as -function-summary %p/Inputs/funcimport_appending_global.ll -o %t2.bc +; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc + +; Do the import now +; RUN: llvm-link %t.bc -functionindex=%t3.thinlto.bc -import=foo:%t2.bc -S | FileCheck %s + +; Ensure that global constructor (appending linkage) is not imported +; CHECK-NOT: @llvm.global_ctors = {{.*}}@foo + +declare void @f() +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null}] + +define i32 @main() { +entry: + call void @foo() + ret i32 0 +} + +declare void @foo()