Commit 717e2a365d

Vexu <git@vexu.eu>
2020-08-20 13:19:11
correct llvm linkage conversion
when weakly exporting external declaration we need to pass LLVMExternalWeakLinkage
1 parent d25674a
Changed files (2)
lib
src
lib/std/c/darwin.zig
@@ -41,10 +41,11 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;
 /// on this operating system. However when building object files or libraries,
 /// the system libc won't be linked until the final executable. So we
 /// export a weak symbol here, to be overridden by the real one.
-pub extern "c" var _mh_execute_header: mach_hdr;
+var dummy_execute_header: mach_hdr = undefined;
+pub extern var _mh_execute_header: mach_hdr;
 comptime {
     if (std.Target.current.isDarwin()) {
-        @export(_mh_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak });
+        @export(dummy_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak });
     }
 }
 
src/codegen.cpp
@@ -292,13 +292,14 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
     }
 }
 
-static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
+static LLVMLinkage to_llvm_linkage(GlobalLinkageId id, bool is_extern) {
     switch (id) {
         case GlobalLinkageIdInternal:
             return LLVMInternalLinkage;
         case GlobalLinkageIdStrong:
             return LLVMExternalLinkage;
         case GlobalLinkageIdWeak:
+            if (is_extern) return LLVMExternalWeakLinkage;
             return LLVMWeakODRLinkage;
         case GlobalLinkageIdLinkOnce:
             return LLVMLinkOnceODRLinkage;
@@ -521,7 +522,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
     }
 
 
-    LLVMSetLinkage(llvm_fn, to_llvm_linkage(linkage));
+    LLVMSetLinkage(llvm_fn, to_llvm_linkage(linkage, fn->body_node == nullptr));
 
     if (linkage == GlobalLinkageIdInternal) {
         LLVMSetUnnamedAddr(llvm_fn, true);
@@ -7962,7 +7963,7 @@ static void do_code_gen(CodeGen *g) {
                 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name);
                 // TODO debug info for the extern variable
 
-                LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
+                LLVMSetLinkage(global_value, to_llvm_linkage(linkage, true));
                 maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
                 LLVMSetAlignment(global_value, var->align_bytes);
                 LLVMSetGlobalConstant(global_value, var->gen_is_const);
@@ -7975,7 +7976,7 @@ static void do_code_gen(CodeGen *g) {
             global_value = var->const_value->llvm_global;
 
             if (exported) {
-                LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
+                LLVMSetLinkage(global_value, to_llvm_linkage(linkage, false));
                 maybe_export_dll(g, global_value, GlobalLinkageIdStrong);
             }
             if (var->section_name) {