authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-09-27 00:42:37+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-09-27 00:42:37+02:00
log3cb5bbb36d09baf4f08464c1d047607a1f09a967
tree3069bd3aeaba4a7be8445f2c473d9ce70caa41bd
parent9a810ff16e1969b7be4a3e0799741fda0077b2f7
parent476efc5b701c2a33cfd09b09989ccf400641a2ac

Merge pull request 'remove `internal` and `link_once` global linkages' (#36956) from alexrp/zig:remove-weird-linkages into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36956 Reviewed-by: mlugg <mlugg@mlugg.co.uk> Reviewed-by: Andrew Kelley <andrew@ziglang.org>

21 files changed, 42 insertions(+), 169 deletions(-)

lib/compiler/aro/aro/TypeStore.zig+1-2
...@@ -1201,9 +1201,8 @@ pub const QualType = packed struct(u32) {...@@ -1201,9 +1201,8 @@ pub const QualType = packed struct(u32) {
1201 }1201 }
12021202
1203 pub fn linkage(qt: QualType, comp: *const Compilation) std.builtin.GlobalLinkage {1203 pub fn linkage(qt: QualType, comp: *const Compilation) std.builtin.GlobalLinkage {
1204 if (qt.hasAttribute(comp, .internal_linkage)) return .internal;
1205 if (qt.hasAttribute(comp, .weak)) return .weak;1204 if (qt.hasAttribute(comp, .weak)) return .weak;
1206 if (qt.hasAttribute(comp, .selectany)) return .link_once;1205 if (qt.hasAttribute(comp, .selectany)) return .weak;
1207 return .strong;1206 return .strong;
1208 }1207 }
12091208
lib/compiler_rt.zig+7-19
...@@ -23,27 +23,15 @@ else...@@ -23,27 +23,15 @@ else
23 unreachable;23 unreachable;
2424
25pub inline fn symbol(comptime func: *const anyopaque, comptime name: []const u8) void {25pub inline fn symbol(comptime func: *const anyopaque, comptime name: []const u8) void {
26 @export(func, .{ .name = name, .linkage = linkage, .visibility = visibility });26 // The function shouldn't be exported at all when testing compiler_rt.
27 // Instead, we just need to reference the function so that it's compiled.
28 if (!builtin.is_test) @export(func, .{
29 .name = name,
30 .linkage = if (ofmt_c) .strong else .weak,
31 .visibility = .hidden,
32 });
27}33}
2834
29/// For now, we prefer weak linkage because some of the routines we implement here may also be
30/// provided by system/dynamic libc. Eventually we should be more disciplined about this on a
31/// per-symbol, per-target basis: https://github.com/ziglang/zig/issues/11883
32pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test)
33 .internal
34else if (ofmt_c)
35 .strong
36else
37 .weak;
38
39/// Determines the symbol's visibility to other objects.
40/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
41/// export it to the host runtime.
42pub const visibility: std.builtin.SymbolVisibility = if (linkage == .internal or builtin.link_mode == .dynamic)
43 .default
44else
45 .hidden;
46
47pub const test_safety = switch (builtin.zig_backend) {35pub const test_safety = switch (builtin.zig_backend) {
48 .stage2_aarch64 => false,36 .stage2_aarch64 => false,
49 else => builtin.is_test,37 else => builtin.is_test,
lib/compiler_rt/memcpy.zig+2-10
...@@ -1,20 +1,12 @@...@@ -1,20 +1,12 @@
1const std = @import("std");1const std = @import("std");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const compiler_rt = @import("../compiler_rt.zig");3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
4const builtin = @import("builtin");5const builtin = @import("builtin");
56
6comptime {7comptime {
7 if (builtin.object_format != .c) {8 if (builtin.object_format != .c) {
8 const export_options: std.builtin.ExportOptions = .{9 symbol(if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64) &memcpySmall else &memcpyFast, "memcpy");
9 .name = "memcpy",
10 .linkage = compiler_rt.linkage,
11 .visibility = compiler_rt.visibility,
12 };
13
14 if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64)
15 @export(&memcpySmall, export_options)
16 else
17 @export(&memcpyFast, export_options);
18 }10 }
19}11}
2012
lib/compiler_rt/memmove.zig+2-10
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const compiler_rt = @import("../compiler_rt.zig");2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
3const builtin = @import("builtin");4const builtin = @import("builtin");
4const assert = std.debug.assert;5const assert = std.debug.assert;
5const memcpy = @import("memcpy.zig");6const memcpy = @import("memcpy.zig");
...@@ -8,16 +9,7 @@ const Element = compiler_rt.PreferredLoadStoreElement;...@@ -8,16 +9,7 @@ const Element = compiler_rt.PreferredLoadStoreElement;
89
9comptime {10comptime {
10 if (builtin.object_format != .c) {11 if (builtin.object_format != .c) {
11 const export_options: std.builtin.ExportOptions = .{12 symbol(if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64) &memmoveSmall else &memmoveFast, "memmove");
12 .name = "memmove",
13 .linkage = compiler_rt.linkage,
14 .visibility = compiler_rt.visibility,
15 };
16
17 if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64)
18 @export(&memmoveSmall, export_options)
19 else
20 @export(&memmoveFast, export_options);
21 }13 }
22}14}
2315
lib/compiler_rt/ssp.zig+1-1
...@@ -22,7 +22,7 @@ extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) call...@@ -22,7 +22,7 @@ extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) call
22extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8;22extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8;
2323
24comptime {24comptime {
25 @export(&__stack_chk_fail, .{ .name = if (builtin.os.tag == .openbsd) "__stack_smash_handler" else "__stack_chk_fail", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });25 symbol(&__stack_chk_fail, if (builtin.os.tag == .openbsd) "__stack_smash_handler" else "__stack_chk_fail");
26 symbol(&__chk_fail, "__chk_fail");26 symbol(&__chk_fail, "__chk_fail");
27 symbol(&__stack_chk_guard, if (builtin.os.tag == .openbsd) "__guard_local" else "__stack_chk_guard");27 symbol(&__stack_chk_guard, if (builtin.os.tag == .openbsd) "__guard_local" else "__stack_chk_guard");
28 symbol(&__strcpy_chk, "__strcpy_chk");28 symbol(&__strcpy_chk, "__strcpy_chk");
lib/std/lang.zig+1-3
...@@ -15,11 +15,9 @@ pub const StackTrace = struct {...@@ -15,11 +15,9 @@ pub const StackTrace = struct {
1515
16/// This data structure is used by the Zig language code generation and16/// This data structure is used by the Zig language code generation and
17/// therefore must be kept in sync with the compiler implementation.17/// therefore must be kept in sync with the compiler implementation.
18pub const GlobalLinkage = enum(u2) {18pub const GlobalLinkage = enum(u1) {
19 internal,
20 strong,19 strong,
21 weak,20 weak,
22 link_once,
23};21};
2422
25/// This data structure is used by the Zig language code generation and23/// This data structure is used by the Zig language code generation and
src/InternPool.zig+1-1
...@@ -5433,7 +5433,7 @@ pub const Tag = enum(u8) {...@@ -5433,7 +5433,7 @@ pub const Tag = enum(u8) {
5433 relocation: std.lang.ExternOptions.Relocation,5433 relocation: std.lang.ExternOptions.Relocation,
5434 source: Source,5434 source: Source,
5435 decoration_type: DecorationType,5435 decoration_type: DecorationType,
5436 _: u23 = 0,5436 _: u24 = 0,
54375437
5438 pub const Source = enum(u1) { builtin, syntax };5438 pub const Source = enum(u1) { builtin, syntax };
5439 pub const DecorationType = enum(u2) { none, location, descriptor, flat };5439 pub const DecorationType = enum(u2) { none, location, descriptor, flat };
src/Sema.zig-13
...@@ -23107,12 +23107,6 @@ fn resolveExportOptions(...@@ -23107,12 +23107,6 @@ fn resolveExportOptions(
23107 return sema.fail(block, name_src, "exported symbol name cannot be empty", .{});23107 return sema.fail(block, name_src, "exported symbol name cannot be empty", .{});
23108 }23108 }
2310923109
23110 if (visibility != .default and linkage == .internal) {
23111 return sema.fail(block, visibility_src, "symbol '{s}' exported with internal linkage has non-default visibility {s}", .{
23112 name, @tagName(visibility),
23113 });
23114 }
23115
23116 return .{23110 return .{
23117 .name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls),23111 .name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls),
23118 .linkage = linkage,23112 .linkage = linkage,
...@@ -25290,13 +25284,6 @@ fn zirBuiltinExtern(...@@ -25290,13 +25284,6 @@ fn zirBuiltinExtern(
25290 }25284 }
2529125285
25292 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);25286 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
25293 switch (options.linkage) {
25294 .internal => if (options.visibility != .default) {
25295 return sema.fail(block, options_src, "internal symbol cannot have non-default visibility", .{});
25296 },
25297 .strong, .weak => {},
25298 .link_once => return sema.fail(block, options_src, "external symbol cannot have link once linkage", .{}),
25299 }
25300 switch (options.relocation) {25287 switch (options.relocation) {
25301 .any => {},25288 .any => {},
25302 .pcrel => if (options.visibility == .default) return sema.fail(block, options_src, "cannot require a pc-relative relocation to a symbol with default visibility", .{}),25289 .pcrel => if (options.visibility == .default) return sema.fail(block, options_src, "cannot require a pc-relative relocation to a symbol with default visibility", .{}),
src/Zcu/PerThread.zig+1-1
...@@ -3657,7 +3657,7 @@ pub fn processExports(pt: Zcu.PerThread) (Allocator.Error || Io.Cancelable)!void...@@ -3657,7 +3657,7 @@ pub fn processExports(pt: Zcu.PerThread) (Allocator.Error || Io.Cancelable)!void
3657 const exp = export_index.ptr(zcu);3657 const exp = export_index.ptr(zcu);
3658 switch (exp.opts.linkage) {3658 switch (exp.opts.linkage) {
3659 .strong => {},3659 .strong => {},
3660 .weak, .internal, .link_once => continue,3660 .weak => continue,
3661 }3661 }
3662 const gop = exports_by_name.getOrPutAssumeCapacity(exp.opts.name);3662 const gop = exports_by_name.getOrPutAssumeCapacity(exp.opts.name);
3663 if (gop.found_existing) {3663 if (gop.found_existing) {
src/codegen.zig+24-40
...@@ -830,53 +830,37 @@ pub fn genNavRef(...@@ -830,53 +830,37 @@ pub fn genNavRef(
830 log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)});830 log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)});
831831
832 const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded;832 const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded;
833 const lib_name, const linkage = if (nav.getExtern(ip)) |e|
834 .{ e.lib_name, e.linkage }
835 else
836 .{ .none, .internal };
837 if (lf.cast(.elf)) |elf_file| {833 if (lf.cast(.elf)) |elf_file| {
838 const zo = elf_file.zigObjectPtr().?;834 const zo = elf_file.zigObjectPtr().?;
839 switch (linkage) {835 if (nav.getExtern(ip)) |e| {
840 .internal => {836 const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));
841 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);837 switch (e.linkage) {
842 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;838 .strong => {},
843 return @fromBackingInt(@intCast(sym_index));839 .weak => zo.symbol(sym_index).flags.weak = true,
844 },840 }
845 .strong, .weak => {841 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
846 const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));842 return @fromBackingInt(@intCast(sym_index));
847 switch (linkage) {843 } else {
848 .internal => unreachable,844 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
849 .strong => {},845 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
850 .weak => zo.symbol(sym_index).flags.weak = true,846 return @fromBackingInt(@intCast(sym_index));
851 .link_once => unreachable,
852 }
853 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
854 return @fromBackingInt(@intCast(sym_index));
855 },
856 .link_once => unreachable,
857 }847 }
858 } else if (lf.cast(.elf2)) |elf| {848 } else if (lf.cast(.elf2)) |elf| {
859 return elf.navSymbol(nav_index);849 return elf.navSymbol(nav_index);
860 } else if (lf.cast(.macho)) |macho_file| {850 } else if (lf.cast(.macho)) |macho_file| {
861 const zo = macho_file.getZigObject().?;851 const zo = macho_file.getZigObject().?;
862 switch (linkage) {852 if (nav.getExtern(ip)) |e| {
863 .internal => {853 const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip));
864 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);854 switch (e.linkage) {
865 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;855 .strong => {},
866 return @fromBackingInt(@intCast(sym_index));856 .weak => zo.symbols.items[sym_index].flags.weak = true,
867 },857 }
868 .strong, .weak => {858 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
869 const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));859 return @fromBackingInt(@intCast(sym_index));
870 switch (linkage) {860 } else {
871 .internal => unreachable,861 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
872 .strong => {},862 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
873 .weak => zo.symbols.items[sym_index].flags.weak = true,863 return @fromBackingInt(@intCast(sym_index));
874 .link_once => unreachable,
875 }
876 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
877 return @fromBackingInt(@intCast(sym_index));
878 },
879 .link_once => unreachable,
880 }864 }
881 } else if (lf.cast(.coff2)) |coff| {865 } else if (lf.cast(.coff2)) |coff| {
882 return @fromBackingInt(@intCast(@backingInt(try coff.navSymbol(zcu, nav_index))));866 return @fromBackingInt(@intCast(@backingInt(try coff.navSymbol(zcu, nav_index))));
src/codegen/c.zig-2
...@@ -2515,10 +2515,8 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {...@@ -2515,10 +2515,8 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {
2515 },2515 },
2516 else => {2516 else => {
2517 switch (@"extern".linkage) {2517 switch (@"extern".linkage) {
2518 .internal => try w.writeAll("static "),
2519 .strong => try w.print("zig_extern zig_visibility({t}) ", .{@"extern".visibility}),2518 .strong => try w.print("zig_extern zig_visibility({t}) ", .{@"extern".visibility}),
2520 .weak => try w.print("zig_extern zig_weak_linkage zig_visibility({t}) ", .{@"extern".visibility}),2519 .weak => try w.print("zig_extern zig_weak_linkage zig_visibility({t}) ", .{@"extern".visibility}),
2521 .link_once => return dg.fail("TODO: CBE: implement linkonce linkage?", .{}),
2522 }2520 }
2523 if (nav.resolved.?.@"threadlocal" and !dg.mod.single_threaded) {2521 if (nav.resolved.?.@"threadlocal" and !dg.mod.single_threaded) {
2524 try w.writeAll("zig_threadlocal ");2522 try w.writeAll("zig_threadlocal ");
src/codegen/llvm.zig-4
...@@ -1077,10 +1077,8 @@ pub const Object = struct {...@@ -1077,10 +1077,8 @@ pub const Object = struct {
1077 false => .default,1077 false => .default,
1078 };1078 };
1079 llvm_global.ptr(&o.builder).linkage = switch (@"extern".linkage) {1079 llvm_global.ptr(&o.builder).linkage = switch (@"extern".linkage) {
1080 .internal => if (o.builder.strip and !workaroundPrivateSymbolBugs(zcu.getTarget(), &resolved)) .private else .internal,
1081 .strong => .external,1080 .strong => .external,
1082 .weak => .extern_weak,1081 .weak => .extern_weak,
1083 .link_once => unreachable,
1084 };1082 };
1085 llvm_global.ptr(&o.builder).visibility = .fromSymbolVisibility(@"extern".visibility);1083 llvm_global.ptr(&o.builder).visibility = .fromSymbolVisibility(@"extern".visibility);
1086 } else {1084 } else {
...@@ -1304,10 +1302,8 @@ pub const Object = struct {...@@ -1304,10 +1302,8 @@ pub const Object = struct {
1304 if (comp.config.dll_export_fns and exp.opts.visibility != .hidden)1302 if (comp.config.dll_export_fns and exp.opts.visibility != .hidden)
1305 alias_global.setDllStorageClass(.dllexport, &o.builder);1303 alias_global.setDllStorageClass(.dllexport, &o.builder);
1306 alias_global.setLinkage(switch (exp.opts.linkage) {1304 alias_global.setLinkage(switch (exp.opts.linkage) {
1307 .internal => if (o.builder.strip) .private else .internal, // we still did useful work in replacing an existing symbol if there was one
1308 .strong => .external,1305 .strong => .external,
1309 .weak => .weak_odr,1306 .weak => .weak_odr,
1310 .link_once => .linkonce_odr,
1311 }, &o.builder);1307 }, &o.builder);
1312 alias_global.setVisibility(switch (exp.opts.visibility) {1308 alias_global.setVisibility(switch (exp.opts.visibility) {
1313 .default => .default,1309 .default => .default,
src/link/Elf/ZigObject.zig-11
...@@ -1910,19 +1910,8 @@ pub fn updateExports(...@@ -1910,19 +1910,8 @@ pub fn updateExports(
1910 }1910 }
1911 }1911 }
1912 const stb_bits: u8 = switch (exp.opts.linkage) {1912 const stb_bits: u8 = switch (exp.opts.linkage) {
1913 .internal => elf.STB_LOCAL,
1914 .strong => elf.STB_GLOBAL,1913 .strong => elf.STB_GLOBAL,
1915 .weak => elf.STB_WEAK,1914 .weak => elf.STB_WEAK,
1916 .link_once => {
1917 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
1918 zcu.failed_exports.putAssumeCapacityNoClobber(export_index, try Zcu.ErrorMsg.create(
1919 gpa,
1920 exp.src,
1921 "Unimplemented: GlobalLinkage.LinkOnce",
1922 .{},
1923 ));
1924 continue;
1925 },
1926 };1915 };
1927 const stt_bits: u8 = @as(u4, @truncate(esym.st_info));1916 const stt_bits: u8 = @as(u4, @truncate(esym.st_info));
1928 const exp_name = exp.opts.name.toSlice(&zcu.intern_pool);1917 const exp_name = exp.opts.name.toSlice(&zcu.intern_pool);
src/link/Elf2.zig+1-5
...@@ -4245,8 +4245,6 @@ fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!Symbol.Id {...@@ -4245,8 +4245,6 @@ fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!Symbol.Id {
4245 .bind = switch (opts.linkage) {4245 .bind = switch (opts.linkage) {
4246 .strong => .strong,4246 .strong => .strong,
4247 .weak => .weak,4247 .weak => .weak,
4248 .internal => return elf.base.comp.link_diags.fail("TODO(Elf2): '.internal' linkage", .{}),
4249 .link_once => return elf.base.comp.link_diags.fail("TODO(Elf2): '.link_once' linkage", .{}),
4250 },4248 },
4251 .visibility = switch (opts.visibility) {4249 .visibility = switch (opts.visibility) {
4252 .default => .DEFAULT,4250 .default => .DEFAULT,
...@@ -7066,7 +7064,7 @@ fn uavMapIndex(...@@ -7066,7 +7064,7 @@ fn uavMapIndex(
7066 const abi_align = Value.fromInterned(uav_val).typeOf(zcu).abiAlignment(zcu);7064 const abi_align = Value.fromInterned(uav_val).typeOf(zcu).abiAlignment(zcu);
7067 const resolved_align: Alignment = switch (uav_align) {7065 const resolved_align: Alignment = switch (uav_align) {
7068 .none => .fromIp(abi_align),7066 .none => .fromIp(abi_align),
7069 else => |a| .fromIp(a.minStrict(abi_align)),7067 else => |a| .fromIp(a.maxStrict(abi_align)),
7070 };7068 };
70717069
7072 const uav_gop = elf.uavs.getOrPutAssumeCapacity(uav_val);7070 const uav_gop = elf.uavs.getOrPutAssumeCapacity(uav_val);
...@@ -12205,8 +12203,6 @@ fn updateExportInner(...@@ -12205,8 +12203,6 @@ fn updateExportInner(
12205 .bind = switch (@"export".opts.linkage) {12203 .bind = switch (@"export".opts.linkage) {
12206 .strong => .strong,12204 .strong => .strong,
12207 .weak => .weak,12205 .weak => .weak,
12208 .internal => return elf.base.comp.link_diags.fail("TODO(Elf2): '.internal' linkage", .{}),
12209 .link_once => return elf.base.comp.link_diags.fail("TODO(Elf2): '.link_once' linkage", .{}),
12210 },12206 },
12211 .visibility = switch (@"export".opts.visibility) {12207 .visibility = switch (@"export".opts.visibility) {
12212 .default => .DEFAULT,12208 .default => .DEFAULT,
src/link/MachO/ZigObject.zig-15
...@@ -1301,15 +1301,6 @@ pub fn updateExports(...@@ -1301,15 +1301,6 @@ pub fn updateExports(
1301 continue;1301 continue;
1302 }1302 }
1303 }1303 }
1304 if (exp.opts.linkage == .link_once) {
1305 try zcu.failed_exports.putNoClobber(zcu.gpa, export_index, try Zcu.ErrorMsg.create(
1306 gpa,
1307 exp.src,
1308 "Unimplemented: GlobalLinkage.link_once",
1309 .{},
1310 ));
1311 continue;
1312 }
13131304
1314 const exp_name = exp.opts.name.toSlice(&zcu.intern_pool);1305 const exp_name = exp.opts.name.toSlice(&zcu.intern_pool);
1315 const global_nlist_index = try self.getGlobalSymbol(macho_file, exp_name, null);1306 const global_nlist_index = try self.getGlobalSymbol(macho_file, exp_name, null);
...@@ -1326,11 +1317,6 @@ pub fn updateExports(...@@ -1326,11 +1317,6 @@ pub fn updateExports(
1326 global_sym.atom_ref = .{ .index = atom_index, .file = self.index };1317 global_sym.atom_ref = .{ .index = atom_index, .file = self.index };
13271318
1328 switch (exp.opts.linkage) {1319 switch (exp.opts.linkage) {
1329 .internal => {
1330 // Symbol should be hidden, or in MachO lingo, private extern.
1331 global_nlist.n_type.bits.pext = true;
1332 global_sym.visibility = .hidden;
1333 },
1334 .strong => {1320 .strong => {
1335 global_sym.visibility = .global;1321 global_sym.visibility = .global;
1336 },1322 },
...@@ -1341,7 +1327,6 @@ pub fn updateExports(...@@ -1341,7 +1327,6 @@ pub fn updateExports(
1341 global_sym.visibility = .global;1327 global_sym.visibility = .global;
1342 global_sym.flags.weak = true;1328 global_sym.flags.weak = true;
1343 },1329 },
1344 else => unreachable,
1345 }1330 }
1346 }1331 }
1347}1332}
src/link/Wasm.zig-6
...@@ -972,10 +972,8 @@ pub const ZcuFunc = union {...@@ -972,10 +972,8 @@ pub const ZcuFunc = union {
972 const name_string = wasm.getExistingString(name_slice).?;972 const name_string = wasm.getExistingString(name_slice).?;
973 return .{973 return .{
974 .binding = switch (ext.linkage) {974 .binding = switch (ext.linkage) {
975 .internal => .local,
976 .strong => .strong,975 .strong => .strong,
977 .weak => .weak,976 .weak => .weak,
978 .link_once => @panic("TODO: COMDAT"),
979 },977 },
980 .visibility_hidden = switch (ext.visibility) {978 .visibility_hidden = switch (ext.visibility) {
981 .default => false,979 .default => false,
...@@ -1952,10 +1950,8 @@ pub const ObjectDataImport = extern struct {...@@ -1952,10 +1950,8 @@ pub const ObjectDataImport = extern struct {
1952 const name_string = wasm.getExistingString(name_slice).?;1950 const name_string = wasm.getExistingString(name_slice).?;
1953 return .{1951 return .{
1954 .binding = switch (ext.linkage) {1952 .binding = switch (ext.linkage) {
1955 .internal => .local,
1956 .strong => .strong,1953 .strong => .strong,
1957 .weak => .weak,1954 .weak => .weak,
1958 .link_once => @panic("TODO: COMDAT"),
1959 },1955 },
1960 .visibility_hidden = switch (ext.visibility) {1956 .visibility_hidden = switch (ext.visibility) {
1961 .default => false,1957 .default => false,
...@@ -2591,10 +2587,8 @@ pub const ZcuImportIndex = enum(u32) {...@@ -2591,10 +2587,8 @@ pub const ZcuImportIndex = enum(u32) {
2591 const name_string = wasm.getExistingString(name_slice).?;2587 const name_string = wasm.getExistingString(name_slice).?;
2592 return .{2588 return .{
2593 .binding = switch (ext.linkage) {2589 .binding = switch (ext.linkage) {
2594 .internal => .local,
2595 .strong => .strong,2590 .strong => .strong,
2596 .weak => .weak,2591 .weak => .weak,
2597 .link_once => @panic("TODO: COMDAT"),
2598 },2592 },
2599 .visibility_hidden = switch (ext.visibility) {2593 .visibility_hidden = switch (ext.visibility) {
2600 .default => false,2594 .default => false,
src/link/Wasm/Flush.zig-6
...@@ -319,10 +319,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -319,10 +319,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
319 .function_index = function_index,319 .function_index = function_index,
320 .flags = .{320 .flags = .{
321 .binding = switch (opts.linkage) {321 .binding = switch (opts.linkage) {
322 .internal => .local,
323 .strong => .strong,322 .strong => .strong,
324 .weak => .weak,323 .weak => .weak,
325 .link_once => @panic("TODO: COMDAT"),
326 },324 },
327 .visibility_hidden = is_hidden,325 .visibility_hidden = is_hidden,
328 .exported = !is_hidden,326 .exported = !is_hidden,
...@@ -346,10 +344,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -346,10 +344,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
346 .resolution = .fromIpNav(wasm, nav_export.nav_index),344 .resolution = .fromIpNav(wasm, nav_export.nav_index),
347 .flags = if (is_obj) .{345 .flags = if (is_obj) .{
348 .binding = switch (opts.linkage) {346 .binding = switch (opts.linkage) {
349 .internal => .local,
350 .strong => .strong,347 .strong => .strong,
351 .weak => .weak,348 .weak => .weak,
352 .link_once => @panic("TODO: COMDAT"),
353 },349 },
354 .visibility_hidden = !explicit and switch (opts.visibility) {350 .visibility_hidden = !explicit and switch (opts.visibility) {
355 .default => false,351 .default => false,
...@@ -383,10 +379,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -383,10 +379,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
383 .resolution = .fromIpIndex(wasm, uav_export.uav_index),379 .resolution = .fromIpIndex(wasm, uav_export.uav_index),
384 .flags = if (is_obj) .{380 .flags = if (is_obj) .{
385 .binding = switch (opts.linkage) {381 .binding = switch (opts.linkage) {
386 .internal => .local,
387 .strong => .strong,382 .strong => .strong,
388 .weak => .weak,383 .weak => .weak,
389 .link_once => @panic("TODO: COMDAT"),
390 },384 },
391 .visibility_hidden = !explicit and switch (opts.visibility) {385 .visibility_hidden = !explicit and switch (opts.visibility) {
392 .default => false,386 .default => false,
test/behavior/export_builtin.zig+1-13
...@@ -16,18 +16,6 @@ test "exporting enum value" {...@@ -16,18 +16,6 @@ test "exporting enum value" {
16 try expect(S.e == .two);16 try expect(S.e == .two);
17}17}
1818
19test "exporting with internal linkage" {
20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
21
22 const S = struct {
23 fn foo() callconv(.c) void {}
24 comptime {
25 @export(&foo, .{ .name = "exporting_with_internal_linkage_foo", .linkage = .internal });
26 }
27 };
28 S.foo();
29}
30
31test "exporting using namespace access" {19test "exporting using namespace access" {
32 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
33 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;21 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -37,7 +25,7 @@ test "exporting using namespace access" {...@@ -37,7 +25,7 @@ test "exporting using namespace access" {
37 const x: u32 = 5;25 const x: u32 = 5;
38 };26 };
39 comptime {27 comptime {
40 @export(&Inner.x, .{ .name = "foo", .linkage = .internal });28 @export(&Inner.x, .{ .name = "foo", .linkage = .strong });
41 }29 }
42 };30 };
4331
test/standalone/global_linkage/obj1.zig-2
...@@ -1,7 +1,5 @@...@@ -1,7 +1,5 @@
1var internal_integer: usize = 1;
2var obj1_integer: usize = 421;1var obj1_integer: usize = 421;
32
4comptime {3comptime {
5 @export(&internal_integer, .{ .name = "internal_integer", .linkage = .internal });
6 @export(&obj1_integer, .{ .name = "obj1_integer", .linkage = .strong });4 @export(&obj1_integer, .{ .name = "obj1_integer", .linkage = .strong });
7}5}
test/standalone/global_linkage/obj2.zig-2
...@@ -1,7 +1,5 @@...@@ -1,7 +1,5 @@
1var internal_integer: usize = 2;
2var obj2_integer: usize = 422;1var obj2_integer: usize = 422;
32
4comptime {3comptime {
5 @export(&internal_integer, .{ .name = "internal_integer", .linkage = .internal });
6 @export(&obj2_integer, .{ .name = "obj2_integer", .linkage = .strong });4 @export(&obj2_integer, .{ .name = "obj2_integer", .linkage = .strong });
7}5}
test/tests.zig-3
...@@ -1294,7 +1294,6 @@ const module_test_targets = blk: {...@@ -1294,7 +1294,6 @@ const module_test_targets = blk: {
1294 .os_tag = .linux,1294 .os_tag = .linux,
1295 },1295 },
1296 .new_linker = true,1296 .new_linker = true,
1297 .skip_modules = &.{ "compiler-rt", "behavior" }, // '@export' with '.internal' linkage
1298 },1297 },
1299 .{1298 .{
1300 .target = .{1299 .target = .{
...@@ -1304,7 +1303,6 @@ const module_test_targets = blk: {...@@ -1304,7 +1303,6 @@ const module_test_targets = blk: {
1304 },1303 },
1305 .link_libc = true,1304 .link_libc = true,
1306 .new_linker = true,1305 .new_linker = true,
1307 .skip_modules = &.{ "compiler-rt", "behavior" }, // '@export' with '.internal' linkage
1308 },1306 },
1309 .{1307 .{
1310 .target = .{1308 .target = .{
...@@ -1314,7 +1312,6 @@ const module_test_targets = blk: {...@@ -1314,7 +1312,6 @@ const module_test_targets = blk: {
1314 },1312 },
1315 .link_libc = true,1313 .link_libc = true,
1316 .new_linker = true,1314 .new_linker = true,
1317 .skip_modules = &.{ "compiler-rt", "behavior" }, // '@export' with '.internal' linkage
1318 },1315 },
13191316
1320 // Darwin Targets1317 // Darwin Targets