Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -961,7 +961,8 @@ new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(), DstGV->getLinkage(), /*init*/nullptr, /*name*/"", DstGV, DstGV->getThreadLocalMode(), - DstGV->getType()->getAddressSpace()); + DstGV->getType()->getAddressSpace(), + DstGV->isExternallyInitialized()); // Propagate alignment, visibility and section info. copyGVAttributes(NG, DstGV); @@ -1100,7 +1101,8 @@ *DstM, TypeMap.get(SGVar->getType()->getElementType()), SGVar->isConstant(), SGVar->getLinkage(), /*init*/ nullptr, SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), - SGVar->getType()->getAddressSpace()); + SGVar->getType()->getAddressSpace(), + SGVar->isExternallyInitialized()); if (Alignment) NewDGV->setAlignment(Alignment); Index: test/LTO/obj-c-global-var-selectors.ll =================================================================== --- /dev/null +++ test/LTO/obj-c-global-var-selectors.ll @@ -0,0 +1,68 @@ +; RUN: llvm-as < %s >%t1 +; RUN: llvm-lto -exported-symbol=_main %t1 -o %t2 +; RUN: llvm-objdump -t %t2 | FileCheck %s + +; Validate that the OBJC_SELECTOR_REFERENCES aren't pre-evaluated and burned directly into the image +; Selectors are potentially modified at load time by the ObjectiveC runtime, if they conflict with a +; another selector in a different .dylib + +; CHECK: SYMBOL TABLE: +; CHECK: {{.*}}bss{{.*}}ZL5MySel +; CHECK: {{.*}}_GLOBAL__sub_I_test.mm + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +@_ZL5MySel = internal unnamed_addr global i8* null, align 8 +@"\01L_OBJC_METH_VAR_NAME_" = private global [7 x i8] c"length\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +@"\01L_OBJC_SELECTOR_REFERENCES_" = private externally_initialized global i8* getelementptr inbounds ([7 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_test.mm, i8* null }] +@llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([7 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*)], section "llvm.metadata" +@str = private unnamed_addr constant [5 x i8] c"BUG!\00" + +; Function Attrs: nounwind ssp uwtable +define i32 @main(i32 %argc, i8** nocapture readnone %argv) #0 { +entry: + %0 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !5 + %1 = load i8** @_ZL5MySel, align 8, !tbaa !6 + %cmp = icmp eq i8* %0, %1 + br i1 %cmp, label %return, label %if.then + +if.then: ; preds = %entry + %puts = tail call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @str, i64 0, i64 0)) + br label %return + +return: ; preds = %if.then, %entry + %retval.0 = phi i32 [ -1, %if.then ], [ 0, %entry ] + ret i32 %retval.0 +} + +; This function CANNOT be pre-evaluated, because the load i8** is of an externally_initialized structure. + +; Function Attrs: nounwind +define internal void @_GLOBAL__sub_I_test.mm() #1 section "__TEXT,__StaticInit,regular,pure_instructions" { +entry: + %0 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !5 + store i8* %0, i8** @_ZL5MySel, align 8, !tbaa !6 + ret void +} + +; Function Attrs: nounwind +declare i32 @puts(i8* nocapture readonly) #1 + +attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3} +!llvm.ident = !{!4} + +!0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2} +!1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0} +!2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"} +!3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0} +!4 = metadata !{metadata !"clang version 3.6.0 (ssh://git.vip.facebook.com/data/gitrepos/llvm/clang.git 1183ce584f8d2883adc1cfe48a357cce21edd4dd) (llvm/llvm.git ee129ed18ddc77b3bd12567987af302ec0e25c3a)"} +!5 = metadata !{} +!6 = metadata !{metadata !7, metadata !7, i64 0} +!7 = metadata !{metadata !"any pointer", metadata !8, i64 0} +!8 = metadata !{metadata !"omnipotent char", metadata !9, i64 0} +!9 = metadata !{metadata !"Simple C/C++ TBAA"}