From 1ac21cdec5747e2c7788c566a2998b2bee54eb47 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 27 Apr 2022 18:14:44 -0700 Subject: [PATCH] compiler-rt: avoid symbol conflicts Weak aliases don't work on Windows, so we avoid exporting the `l` alias on this platform for functions we know will collide. --- lib/std/special/compiler_rt.zig | 54 ++++++++++++++++++--------------- src/stage1/codegen.cpp | 47 ++++++++++++---------------- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index dccb9264bd..f0b0c49152 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -723,25 +723,25 @@ comptime { @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); } - mathExport("ceil", @import("./compiler_rt/ceil.zig")); - mathExport("cos", @import("./compiler_rt/cos.zig")); - mathExport("exp", @import("./compiler_rt/exp.zig")); - mathExport("exp2", @import("./compiler_rt/exp2.zig")); - mathExport("fabs", @import("./compiler_rt/fabs.zig")); - mathExport("floor", @import("./compiler_rt/floor.zig")); - mathExport("fma", @import("./compiler_rt/fma.zig")); - mathExport("fmax", @import("./compiler_rt/fmax.zig")); - mathExport("fmin", @import("./compiler_rt/fmin.zig")); - mathExport("fmod", @import("./compiler_rt/fmod.zig")); - mathExport("log", @import("./compiler_rt/log.zig")); - mathExport("log10", @import("./compiler_rt/log10.zig")); - mathExport("log2", @import("./compiler_rt/log2.zig")); - mathExport("round", @import("./compiler_rt/round.zig")); - mathExport("sin", @import("./compiler_rt/sin.zig")); - mathExport("sincos", @import("./compiler_rt/sincos.zig")); - mathExport("sqrt", @import("./compiler_rt/sqrt.zig")); - mathExport("tan", @import("./compiler_rt/tan.zig")); - mathExport("trunc", @import("./compiler_rt/trunc.zig")); + mathExport("ceil", @import("./compiler_rt/ceil.zig"), true); + mathExport("cos", @import("./compiler_rt/cos.zig"), true); + mathExport("exp", @import("./compiler_rt/exp.zig"), true); + mathExport("exp2", @import("./compiler_rt/exp2.zig"), true); + mathExport("fabs", @import("./compiler_rt/fabs.zig"), true); + mathExport("floor", @import("./compiler_rt/floor.zig"), true); + mathExport("fma", @import("./compiler_rt/fma.zig"), true); + mathExport("fmax", @import("./compiler_rt/fmax.zig"), true); + mathExport("fmin", @import("./compiler_rt/fmin.zig"), true); + mathExport("fmod", @import("./compiler_rt/fmod.zig"), true); + mathExport("log", @import("./compiler_rt/log.zig"), true); + mathExport("log10", @import("./compiler_rt/log10.zig"), true); + mathExport("log2", @import("./compiler_rt/log2.zig"), true); + mathExport("round", @import("./compiler_rt/round.zig"), true); + mathExport("sin", @import("./compiler_rt/sin.zig"), true); + mathExport("sincos", @import("./compiler_rt/sincos.zig"), true); + mathExport("sqrt", @import("./compiler_rt/sqrt.zig"), true); + mathExport("tan", @import("./compiler_rt/tan.zig"), false); + mathExport("trunc", @import("./compiler_rt/trunc.zig"), true); if (arch.isSPARC()) { // SPARC systems use a different naming scheme @@ -827,7 +827,7 @@ comptime { } } -inline fn mathExport(double_name: []const u8, comptime import: type) void { +inline fn mathExport(double_name: []const u8, comptime import: type, is_standard: bool) void { const half_name = "__" ++ double_name ++ "h"; const half_fn = @field(import, half_name); const float_name = double_name ++ "f"; @@ -853,11 +853,15 @@ inline fn mathExport(double_name: []const u8, comptime import: type) void { .{ f128, quad_fn }, }; - inline for (pairs) |pair| { - const F = pair[0]; - const func = pair[1]; - if (builtin.target.longDoubleIs(F)) { - @export(func, .{ .name = long_double_name, .linkage = linkage }); + // Weak aliases don't work on Windows, so we avoid exporting the `l` alias + // on this platform for functions we know will collide. + if (builtin.os.tag != .windows or !builtin.link_libc or !is_standard) { + inline for (pairs) |pair| { + const F = pair[0]; + const func = pair[1]; + if (builtin.target.longDoubleIs(F)) { + @export(func, .{ .name = long_double_name, .linkage = linkage }); + } } } } diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 34ae82eb82..c575aff53d 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -1630,37 +1630,28 @@ static const char *get_compiler_rt_type_abbrev(ZigType *type) { } static const char *libc_float_prefix(CodeGen *g, ZigType *float_type) { - if (float_type == g->builtin_types.entry_f16) - return "__"; - else if (float_type == g->builtin_types.entry_f32) - return ""; - else if (float_type == g->builtin_types.entry_f64) - return ""; - else if (float_type == g->builtin_types.entry_f80) - return "__"; - else if (float_type == g->builtin_types.entry_c_longdouble) - return "l"; - else if (float_type == g->builtin_types.entry_f128) - return ""; - else - zig_unreachable(); + switch (float_type->data.floating.bit_count) { + case 16: + case 80: + return "__"; + case 32: + case 64: + case 128: + return ""; + default: + zig_unreachable(); + } } static const char *libc_float_suffix(CodeGen *g, ZigType *float_type) { - if (float_type == g->builtin_types.entry_f16) - return "h"; // Non-standard - else if (float_type == g->builtin_types.entry_f32) - return "f"; - else if (float_type == g->builtin_types.entry_f64) - return ""; - else if (float_type == g->builtin_types.entry_f80) - return "x"; // Non-standard - else if (float_type == g->builtin_types.entry_c_longdouble) - return "l"; - else if (float_type == g->builtin_types.entry_f128) - return "q"; // Non-standard - else - zig_unreachable(); + switch (float_type->size_in_bits) { + case 16: return "h"; // Non-standard + case 32: return "f"; + case 64: return ""; + case 80: return "x"; // Non-standard + case 128: return "q"; // Non-standard + default: zig_unreachable(); + } } static LLVMValueRef gen_soft_float_widen_or_shorten(CodeGen *g, ZigType *actual_type,