Revert "Merge pull request #17824 from kcbanner/fixup_msvc_fmax"

This reverts commit 7161ed79c4, reversing
changes made to 3f2a65594e.

Unfortunately, this sat in the PR queue too long and the merge broke the
zig1.wasm bootstrap process.
This commit is contained in:
Andrew Kelley 2024-01-01 17:48:40 -07:00
parent e426ae43ae
commit 2b58978360
7 changed files with 92 additions and 185 deletions

View File

@ -96,8 +96,9 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
CheckLastExitCode
Write-Output "Build and run behavior tests with msvc..."
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
CheckLastExitCode
& .\test-x86_64-windows-msvc.exe
CheckLastExitCode
Write-Output "Skipped due to https://github.com/ziglang/zig/issues/17817"
#& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
#CheckLastExitCode
#
#& .\test-x86_64-windows-msvc.exe
#CheckLastExitCode

View File

@ -95,8 +95,9 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
CheckLastExitCode
Write-Output "Build and run behavior tests with msvc..."
& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
CheckLastExitCode
& .\test-x86_64-windows-msvc.exe
CheckLastExitCode
Write-Output "Skipped due to https://github.com/ziglang/zig/issues/17817"
#& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
#CheckLastExitCode
#
#& .\test-x86_64-windows-msvc.exe
#CheckLastExitCode

View File

@ -1266,7 +1266,6 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
}
test "lerp" {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;

102
lib/zig.h
View File

@ -112,7 +112,7 @@ typedef char bool;
#define zig_never_tail zig_never_tail_unavailable
#endif
#if zig_has_attribute(musttail)
#if zig_has_attribute(always_inline)
#define zig_always_tail __attribute__((musttail))
#else
#define zig_always_tail zig_always_tail_unavailable
@ -180,56 +180,20 @@ typedef char bool;
#define zig_extern extern
#endif
#if _MSC_VER
#define zig_extern_mangled zig_extern
#else
#if zig_has_attribute(visibility)
#define zig_extern_mangled zig_extern __attribute__((visibility("hidden")))
#else
#define zig_extern_mangled zig_extern
#endif
#endif
#if _MSC_VER
#if zig_has_attribute(alias)
#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))
#elif _MSC_VER
#if _M_X64
#define zig_export(sig, symbol, name) zig_extern sig;\
__pragma(comment(linker, "/alternatename:" name "=" #symbol ))
#define zig_export(sig, symbol, name) sig;\
__pragma(comment(linker, "/alternatename:" name "=" symbol ))
#else /*_M_X64 */
#define zig_export(sig, symbol, name) zig_extern sig;\
__pragma(comment(linker, "/alternatename:" name "=" #symbol ))
#define zig_export(sig, symbol, name) sig;\
__pragma(comment(linker, "/alternatename:_" name "=_" symbol ))
#endif /*_M_X64 */
#else /* _MSC_VER */
#if __APPLE__
#define zig_export(sig, symbol, name) zig_extern sig;\
__asm("_" name " = _" #symbol)
#else /* __APPLE__ */
#define zig_export(sig, symbol, name) zig_extern sig;\
__asm(name " = " #symbol)
#endif /* __APPLE__ */
#endif /* _MSC_VER */
#if _MSC_VER
#if _M_X64
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args;\
__pragma(comment(linker, "/alternatename:" #fn_name "=" #libc_name ));
#else /*_M_X64 */
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args;\
__pragma(comment(linker, "/alternatename:_" #fn_name "=_" #libc_name ));
#endif /*_M_X64 */
#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, sig_args, call_args)
#else /* _MSC_VER */
#if __APPLE__
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args __asm("_" #libc_name);
#else /* __APPLE__ */
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args __asm(#libc_name);
#endif /* __APPLE__ */
#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type libc_name sig_args; \
static inline Type fn_name sig_args { return libc_name call_args; }
#else
#define zig_export(sig, symbol, name) __asm(name " = " symbol)
#endif
#define zig_expand_import_0(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
#define zig_expand_import_1(Type, fn_name, libc_name, sig_args, call_args) zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args)
#if zig_has_attribute(weak) || defined(zig_gnuc)
#define zig_weak_linkage __attribute__((weak))
#define zig_weak_linkage_fn __attribute__((weak))
@ -3129,7 +3093,6 @@ ypedef uint32_t zig_f32;
#define zig_has_f64 1
#define zig_libc_name_f64(name) name
#if _MSC_VER
#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
#else
@ -3355,7 +3318,6 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
return lhs operator rhs; \
}
#define zig_expand_has_builtin(b) zig_has_builtin(b)
#define zig_common_float_builtins(w) \
zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \
zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \
@ -3374,31 +3336,31 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \
zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \
zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sqrt)))(zig_f##w, zig_float_fn_f##w##_sqrt, zig_libc_name_f##w(sqrt), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sin)))(zig_f##w, zig_float_fn_f##w##_sin, zig_libc_name_f##w(sin), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(cos)))(zig_f##w, zig_float_fn_f##w##_cos, zig_libc_name_f##w(cos), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(tan)))(zig_f##w, zig_float_fn_f##w##_tan, zig_libc_name_f##w(tan), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp)))(zig_f##w, zig_float_fn_f##w##_exp, zig_libc_name_f##w(exp), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp2)))(zig_f##w, zig_float_fn_f##w##_exp2, zig_libc_name_f##w(exp2), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log)))(zig_f##w, zig_float_fn_f##w##_log, zig_libc_name_f##w(log), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log2)))(zig_f##w, zig_float_fn_f##w##_log2, zig_libc_name_f##w(log2), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log10)))(zig_f##w, zig_float_fn_f##w##_log10, zig_libc_name_f##w(log10), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fabs)))(zig_f##w, zig_float_fn_f##w##_fabs, zig_libc_name_f##w(fabs), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(floor)))(zig_f##w, zig_float_fn_f##w##_floor, zig_libc_name_f##w(floor), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(ceil)))(zig_f##w, zig_float_fn_f##w##_ceil, zig_libc_name_f##w(ceil), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(round)))(zig_f##w, zig_float_fn_f##w##_round, zig_libc_name_f##w(round), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(trunc)))(zig_f##w, zig_float_fn_f##w##_trunc, zig_libc_name_f##w(trunc), (zig_f##w x), (x)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmod)))(zig_f##w, zig_float_fn_f##w##_fmod, zig_libc_name_f##w(fmod), (zig_f##w x, zig_f##w y), (x, y)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmin)))(zig_f##w, zig_float_fn_f##w##_fmin, zig_libc_name_f##w(fmin), (zig_f##w x, zig_f##w y), (x, y)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_float_fn_f##w##_fmax, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_float_fn_f##w##_fma, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
zig_extern zig_f##w zig_libc_name_f##w(sqrt)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(sin)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(cos)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(tan)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(exp)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(exp2)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(log)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(log2)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(log10)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(fabs)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(floor)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(ceil)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(round)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(trunc)(zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(fmod)(zig_f##w, zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(fmin)(zig_f##w, zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(fmax)(zig_f##w, zig_f##w); \
zig_extern zig_f##w zig_libc_name_f##w(fma)(zig_f##w, zig_f##w, zig_f##w); \
\
static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
return zig_float_fn_f##w##_trunc(zig_div_f##w(lhs, rhs)); \
return zig_libc_name_f##w(trunc)(zig_div_f##w(lhs, rhs)); \
} \
\
static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \
return zig_float_fn_f##w##_floor(zig_div_f##w(lhs, rhs)); \
return zig_libc_name_f##w(floor)(zig_div_f##w(lhs, rhs)); \
} \
\
static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
@ -3502,7 +3464,7 @@ zig_float_builtins(64)
zig_##Type zig_atomicrmw_desired; \
zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
do { \
zig_atomicrmw_desired = zig_float_fn_##Type##_fmin(zig_atomicrmw_expected, arg); \
zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \
} while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
res = zig_atomicrmw_expected; \
} while (0)
@ -3511,7 +3473,7 @@ zig_float_builtins(64)
zig_##Type zig_atomicrmw_desired; \
zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
do { \
zig_atomicrmw_desired = zig_float_fn_##Type##_fmax(zig_atomicrmw_expected, arg); \
zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \
} while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
res = zig_atomicrmw_expected; \
} while (0)

View File

@ -258,42 +258,6 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
return .{ .data = ident };
}
// Returns true if `formatIdent` would make any edits to ident.
// This must be kept in sync with `formatIdent`.
pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
if (solo and isReservedIdent(ident)) return true;
for (ident, 0..) |c, i| {
switch (c) {
'a'...'z', 'A'...'Z', '_' => {},
'0'...'9' => if (i == 0) return true,
else => return true,
}
}
return false;
}
const DeclVisibility = enum {
global,
global_mangled,
local,
fn renderFwd(visibility: DeclVisibility, w: anytype) !void {
try w.writeAll(switch (visibility) {
.global => "zig_extern ",
// MSVC doesn't support exporting `static` functions, so they need special treatment
.global_mangled => "zig_extern_mangled ",
.local => "static ",
});
}
fn renderDef(visibility: DeclVisibility, w: anytype) !void {
return switch (visibility) {
.global => {},
else => visibility.renderFwd(w),
};
}
};
/// This data is available when outputting .c code for a `InternPool.Index`
/// that corresponds to `func`.
/// It is not available when generating .h file.
@ -566,7 +530,6 @@ pub const DeclGen = struct {
is_naked_fn: bool,
/// This is a borrowed reference from `link.C`.
fwd_decl: std.ArrayList(u8),
error_msg: ?*Module.ErrorMsg,
ctypes: CType.Store,
/// Keeps track of anonymous decls that need to be rendered before this
@ -1668,7 +1631,7 @@ pub const DeclGen = struct {
switch (name) {
.export_index => |export_index| try dg.renderDeclName(w, fn_decl_index, export_index),
.string => |string| try w.print("{ }", .{fmtIdent(string)}),
.string => |string| try w.writeAll(string),
}
try renderTypeSuffix(
@ -1880,26 +1843,12 @@ pub const DeclGen = struct {
try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
}
fn declVisibility(dg: *DeclGen, tv: TypedValue) DeclVisibility {
fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
const mod = dg.module;
return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
.variable => |variable| {
if (mod.decl_exports.get(variable.decl)) |exports| {
return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true))
.global_mangled
else
.global;
} else return .local;
},
.extern_func => .global,
.func => |func| {
if (mod.decl_exports.get(func.owner_decl)) |exports| {
return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true))
.global_mangled
else
.global;
} else return .local;
},
.variable => |variable| mod.decl_exports.contains(variable.decl),
.extern_func => true,
.func => |func| mod.decl_exports.contains(func.owner_decl),
else => unreachable,
};
}
@ -1984,8 +1933,8 @@ pub const DeclGen = struct {
fn renderFwdDecl(dg: *DeclGen, decl_index: InternPool.DeclIndex, variable: InternPool.Key.Variable) !void {
const decl = dg.module.declPtr(decl_index);
const fwd = dg.fwd_decl.writer();
const visibility = if (variable.is_extern) .global else dg.declVisibility(.{ .ty = decl.ty, .val = decl.val });
try visibility.renderFwd(fwd);
const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern;
try fwd.writeAll(if (is_global) "zig_extern " else "static ");
const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports|
exports.items[0].opts.linkage == .Weak
else
@ -2009,7 +1958,7 @@ pub const DeclGen = struct {
try mod.markDeclAlive(decl);
if (mod.decl_exports.get(decl_index)) |exports| {
try writer.print("{ }", .{fmtIdent(mod.intern_pool.stringToSlice(exports.items[export_index].opts.name))});
try writer.print("{}", .{exports.items[export_index].opts.name.fmt(&mod.intern_pool)});
} else if (decl.getExternDecl(mod).unwrap()) |extern_decl_index| {
try writer.print("{}", .{mod.declPtr(extern_decl_index).name.fmt(&mod.intern_pool)});
} else {
@ -2649,19 +2598,16 @@ fn genExports(o: *Object) !void {
const fwd = o.dg.fwd_decl.writer();
const exports = mod.decl_exports.get(decl_index) orelse return;
const is_mangled = isMangledIdent(ip.stringToSlice(exports.items[0].opts.name), true);
if (exports.items.len < 2 and !is_mangled) return;
if (exports.items.len < 2) return;
switch (ip.indexToKey(tv.val.toIntern())) {
.func => {
const start_i = 1 - @intFromBool(is_mangled);
for (exports.items[start_i..], start_i..) |@"export", i| {
for (exports.items[1..], 1..) |@"export", i| {
try fwd.writeAll("zig_export(");
if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");
try o.dg.renderFunctionSignature(fwd, decl_index, .forward, .{ .export_index = @as(u32, @intCast(i)) });
try fwd.print(", { }, {s});\n", .{
fmtIdent(ip.stringToSlice(exports.items[0].opts.name)),
try fwd.print(", {s}, {s});\n", .{
fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),
});
}
@ -2671,8 +2617,7 @@ fn genExports(o: *Object) !void {
unreachable;
},
.variable => |variable| {
const start_i = 1 - @intFromBool(is_mangled);
for (exports.items[start_i..], start_i..) |@"export", i| {
for (exports.items[1..], 1..) |@"export", i| {
try fwd.writeAll("zig_export(");
if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");
const alias = ip.stringToSlice(@"export".opts.name);
@ -2684,8 +2629,8 @@ fn genExports(o: *Object) !void {
decl.alignment,
.complete,
);
try fwd.print(", { }, {s});\n", .{
fmtIdent(ip.stringToSlice(exports.items[0].opts.name)),
try fwd.print(", {s}, {s});\n", .{
fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
fmtStringLiteral(alias, null),
});
}
@ -2797,10 +2742,9 @@ pub fn genFunc(f: *Function) !void {
o.code_header = std.ArrayList(u8).init(gpa);
defer o.code_header.deinit();
const visibility = o.dg.declVisibility(tv);
const is_global = o.dg.declIsGlobal(tv);
const fwd_decl_writer = o.dg.fwd_decl.writer();
try visibility.renderFwd(fwd_decl_writer);
try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
if (mod.decl_exports.get(decl_index)) |exports|
if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");
try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
@ -2808,7 +2752,7 @@ pub fn genFunc(f: *Function) !void {
try genExports(o);
try o.indent_writer.insertNewline();
try visibility.renderDef(o.writer());
if (!is_global) try o.writer().writeAll("static ");
try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 });
try o.writer().writeByte(' ');
@ -2892,9 +2836,9 @@ pub fn genDecl(o: *Object) !void {
if (variable.is_extern) return;
const visibility = if (variable.is_extern) .global else o.dg.declVisibility(tv);
const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;
const w = o.writer();
try visibility.renderDef(w);
if (!is_global) try w.writeAll("static ");
if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
@ -2907,21 +2851,16 @@ pub fn genDecl(o: *Object) !void {
try w.writeByte(';');
try o.indent_writer.insertNewline();
} else {
const visibility: DeclVisibility = if (o.dg.module.decl_exports.get(decl_index)) |exports| b: {
break :b if (isMangledIdent(o.dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true))
.global_mangled
else
.global;
} else .local;
const is_global = o.dg.module.decl_exports.contains(decl_index);
const decl_c_value = .{ .decl = decl_index };
return genDeclValue(o, tv, visibility, decl_c_value, decl.alignment, decl.@"linksection");
return genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection");
}
}
pub fn genDeclValue(
o: *Object,
tv: TypedValue,
visibility: DeclVisibility,
is_global: bool,
decl_c_value: CValue,
alignment: Alignment,
link_section: InternPool.OptionalNullTerminatedString,
@ -2929,13 +2868,12 @@ pub fn genDeclValue(
const mod = o.dg.module;
const fwd_decl_writer = o.dg.fwd_decl.writer();
try visibility.renderFwd(fwd_decl_writer);
try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
try fwd_decl_writer.writeAll(";\n");
const w = o.writer();
try visibility.renderDef(w);
if (!is_global) try w.writeAll("static ");
if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
try w.print("zig_linksection(\"{s}\", ", .{s});
try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete);
@ -2960,14 +2898,11 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
switch (tv.ty.zigTypeTag(mod)) {
.Fn => {
const visibility = dg.declVisibility(tv);
switch (visibility) {
.global, .global_mangled => {
try visibility.renderFwd(writer);
try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
try dg.fwd_decl.appendSlice(";\n");
},
.local => {},
const is_global = dg.declIsGlobal(tv);
if (is_global) {
try writer.writeAll("zig_extern ");
try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
try dg.fwd_decl.appendSlice(";\n");
}
},
else => {},
@ -6960,9 +6895,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, accum, .Other);
switch (op) {
.float_op => |func| {
try writer.writeAll(" = zig_float_fn_");
try writer.writeAll(" = zig_libc_name_");
try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
try writer.print("_{s}(", .{func.operation});
try writer.print("({s})(", .{func.operation});
try f.writeCValue(writer, accum, .FunctionArgument);
try writer.writeAll(", ");
try f.writeCValue(writer, operand, .Other);
@ -7294,9 +7229,11 @@ fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, oper
const v = try Vectorize.start(f, inst, writer, ty);
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
try writer.writeAll(" = zig_float_fn_");
try writer.writeAll(" = zig_libc_name_");
try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
try writer.print("_{s}(", .{operation});
try writer.writeByte('(');
try writer.writeAll(operation);
try writer.writeAll(")(");
try f.writeCValue(writer, operand, .FunctionArgument);
try v.elem(f, writer);
try writer.writeAll(");\n");
@ -7331,9 +7268,11 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
const v = try Vectorize.start(f, inst, writer, inst_ty);
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
try writer.writeAll(" = zig_float_fn_");
try writer.writeAll(" = zig_libc_name_");
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
try writer.print("_{s}(", .{operation});
try writer.writeByte('(');
try writer.writeAll(operation);
try writer.writeAll(")(");
try f.writeCValue(writer, lhs, .FunctionArgument);
try v.elem(f, writer);
try writer.writeAll(", ");
@ -7363,9 +7302,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
const v = try Vectorize.start(f, inst, writer, inst_ty);
try f.writeCValue(writer, local, .Other);
try v.elem(f, writer);
try writer.writeAll(" = zig_float_fn_");
try writer.writeAll(" = zig_libc_name_");
try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
try writer.writeAll("_fma(");
try writer.writeAll("(fma)(");
try f.writeCValue(writer, mulend1, .FunctionArgument);
try v.elem(f, writer);
try writer.writeAll(", ");

View File

@ -262,7 +262,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
};
const c_value: codegen.CValue = .{ .constant = anon_decl };
const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
codegen.genDeclValue(&object, tv, .local, c_value, alignment, .none) catch |err| switch (err) {
codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) {
error.AnalysisFail => {
@panic("TODO: C backend AnalysisFail on anonymous decl");
//try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);

View File

@ -12,6 +12,11 @@ test "export a function twice" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
// TODO: test.c: error: aliases are not supported on darwin
return error.SkipZigTest;
}
// If it exports the function correctly, `test_func` and `testFunc` will points to the same address.
try expectEqual(test_func(), other_file.testFunc());
}