| author | |
| committer | |
| log | 62f13ef4efe5aab5030ea56442b552ad0c5fec42 |
| tree | fcdd607d4f2f01deb47c15c24df72b4a27ea13cd |
| parent | f94185e67749c9cfcf21be5cf9c03baf8d2ac025 |
Our "multiple definitions" check in the frontend was a little
overzealous! The only case which should actually be an error is when
there are multiple *strong* definitions.
In the future we will eliminate this frontend check entirely, because
it's redundant with the check the linker will perform---but for now it's
worth keeping since our linkers do not yet print useful source location
information for Zig exports.
Resolves: https://codeberg.org/ziglang/zig/issues/366782 files changed, 20 insertions(+), 0 deletions(-)
src/Zcu/PerThread.zig+4| ... | ... | @@ -3655,6 +3655,10 @@ pub fn processExports(pt: Zcu.PerThread) (Allocator.Error || Io.Cancelable)!void |
| 3655 | 3655 | |
| 3656 | 3656 | for (alive_exports.items) |export_index| { |
| 3657 | 3657 | const exp = export_index.ptr(zcu); |
| 3658 | switch (exp.opts.linkage) { | |
| 3659 | .strong => {}, | |
| 3660 | .weak, .internal, .link_once => continue, | |
| 3661 | } | |
| 3658 | 3662 | const gop = exports_by_name.getOrPutAssumeCapacity(exp.opts.name); |
| 3659 | 3663 | if (gop.found_existing) { |
| 3660 | 3664 | const existing_exp = gop.value_ptr.*.ptr(zcu); |
test/cases/export_override_libc.zig created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | /// This implementation is intentionally incorrect so we can check that it is | |
| 2 | /// called instead of the libc symbol. | |
| 3 | export fn isdigit(c: c_int) c_int { | |
| 4 | return @intFromBool(c == '0'); | |
| 5 | } | |
| 6 | ||
| 7 | pub fn main() void { | |
| 8 | const static = struct { | |
| 9 | extern fn isdigit(c_int) c_int; | |
| 10 | }; | |
| 11 | if (static.isdigit('0') == 0) @panic("override failed: isdigit('0') == 0"); | |
| 12 | if (static.isdigit('1') != 0) @panic("override failed: isdigit('1') != 0"); | |
| 13 | } | |
| 14 | ||
| 15 | // run | |
| 16 | // link_libc=true |