ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.26k stars 2.5k forks source link

many std.json test failures on powerpc #12086

Closed andrewrk closed 2 years ago

andrewrk commented 2 years ago

A lot of tests are failing, but if we just look at one:

test "n_object_bracket_key" {
    try err(
        \\{[: "x"}
    );
}
[nix-shell:~/Downloads/zig/build-release]$ stage2/bin/zig test ../lib/std/std.zig -target powerpc-linux-none --test-cmd qemu-ppc --test-cmd-bin --test-filter 'n_object_bracket_key'
114/230 test.n_object_bracket_key... error: the following test command crashed:
qemu-ppc ../lib/std/zig-cache/o/57c79ddf3440ff907412143c7c741c18/test /home/andy/Downloads/zig/build-release/stage2/bin/zig
Program received signal SIGSEGV, Segmentation fault.
0x100de088 in json.test.err () at /home/andy/Downloads/zig/lib/std/json/test.zig:45
45      try testing.expect(std.meta.isError(testNonStreaming(s)));
(gdb) 
(gdb) disas /s
44  
45      try testing.expect(std.meta.isError(testNonStreaming(s)));
   0x100de070 <+140>:   lwz     r3,36(r31)
   0x100de074 <+144>:   lwz     r5,28(r31)
   0x100de078 <+148>:   lwz     r4,32(r31)
   0x100de07c <+152>:   bl      0x100de284 <json.test.testNonStreaming>
   0x100de080 <+156>:   bl      0x100de394 <meta.isError__anon_36012>
   0x100de084 <+160>:   mr      r4,r3
=> 0x100de088 <+164>:   lwz     r3,36(r31)
   0x100de08c <+168>:   bl      0x100d1784 <testing.expect>
End of assembler dump.
(gdb) 

I looked into this for a bit and it is some kind of low level code-generation problem. The segfault is happening apparently when accessing the return value (of type !void) of a function call.

The next step here is to create a reduction, perhaps at the LLVM IR level, and investigate whether this is a Zig bug or an LLVM bug.

topolarity commented 2 years ago

Minimal repro:

const Value = union(enum) {
    foo: u64,
    bar: u128,
};

fn foo() !Value {
    return error.InvalidLiteral;
}

pub fn main() void {
    _ = foo() catch {};
}