ziglang / zig

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

codegen panic on `ir_assert(instruction->value->special != ConstValSpecialRuntime, instruction);` in `ir_llvm_value` #9217

Open gavinbeatty opened 3 years ago

gavinbeatty commented 3 years ago
const std = @import("std");
const Options = struct { tmp: std.fs.Dir };
pub fn main() anyerror!void {
    const o = std.process.args().nextPosix() orelse return error.NotEnoughArgs;
    const opt = if (std.mem.eql(u8, o, "--tmp")) Options{ .tmp = try openTempDir() } else Options{ .tmp = try (openTempDir() catch openTempDir()) };
    return error.Codegen;
}
fn openTempDir() !std.fs.Dir {
    return error.TmpDirNotFound;
}

results in:

when analyzing /home/gavinbeatty/work/codegen-panic-repro/src/main.zig:5:126 in compiler source at /home/andy/dev/bootstrap-zig/zig/src/stage1/codegen.cpp:1841: thread 19017 panic: assertion failed. This is a bug in the Zig compiler.
Unable to dump stack trace: debug info stripped
codegen-panic-repro...The following command terminated unexpectedly:
/home/gavinbeatty/.local/opt/zig-linux-x86_64-0.8.0/zig build-exe /home/gavinbeatty/work/codegen-panic-repro/src/main.zig --cache-dir /home/gavinbeatty/work/codegen-panic-repro/zig-cache --global-cache-dir /home/gavinbeatty/.cache/zig --name codegen-panic-repro --enable-cache
error: the following build command failed with exit code 6:
/home/gavinbeatty/work/codegen-panic-repro/zig-cache/o/8dbe7e429a67ec1a1aac2b41bd5e60f1/build /home/gavinbeatty/.local/opt/zig-linux-x86_64-0.8.0/zig /home/gavinbeatty/work/codegen-panic-repro /home/gavinbeatty/work/codegen-panic-repro/zig-cache /home/gavinbeatty/.cache/zig

Tried reducing the source further with the following, but the assert would no longer trigger:

Same assertion as #6302 but maybe not same trigger (I don't have a stack trace). Also occurs with zig-linux-x86_64-0.9.0-dev.256+0134cb021.

If there's a build of zig with debug info, I can re-run with that. I ran into issues last week when trying to build zig master from source via zig-bootstrap. I'll try build 0.8.0 in the near future.

nektro commented 3 years ago

I would suggest trying to build upstream ziglang/zig and not zig-bootstrap in order try and produce a stack trace.

As it appears you're on linux, these should work just fine https://github.com/ziglang/zig/wiki/Building-Zig-From-Source#instructions

g-w1 commented 3 years ago

Stacktrace:

when analyzing /tmp/test.zig:5:126 in compiler source at ../src/stage1/codegen.cpp:1843: thread 31883 panic: assertion failed. This is a bug in the Zig compiler.
/home/jacob/dev/zig/src/stage1.zig:175:5: 0x8a2387 in stage2_panic (zig1)
    @panic(ptr[0..len]);
    ^
../src/stage1/analyze.cpp:9850:17: 0x16b6f5b in src_assert_impl (../src/stage1/analyze.cpp)
../src/stage1/codegen.cpp:911:20: 0x15c20ac in ir_assert_impl (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:1843:9: 0x15c5815 in ir_llvm_value (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:5210:43: 0x15d3a58 in ir_render_phi (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:6891:33: 0x15da740 in ir_render_instruction (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:7037:60: 0x15dafa4 in ir_render (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:8469:18: 0x15e1410 in do_code_gen (../src/stage1/codegen.cpp)
../src/stage1/codegen.cpp:9651:16: 0x15e6097 in codegen_build_object (../src/stage1/codegen.cpp)
../src/stage1/stage1.cpp:129:25: 0x15ba70f in zig_stage1_build_object (../src/stage1/stage1.cpp)
/home/jacob/dev/zig/src/stage1.zig:146:32: 0xc6f914 in Module.build_object (zig1)
        zig_stage1_build_object(mod);
                               ^
/home/jacob/dev/zig/src/Compilation.zig:4121:31: 0xa35787 in Compilation.updateStage1Module (zig1)
        .enable_stack_report = comp.stack_report,
                              ^
/home/jacob/dev/zig/src/Compilation.zig:2307:36: 0xa0c623 in Compilation.performAllTheWork (zig1)
                ),
                                   ^
/home/jacob/dev/zig/src/Compilation.zig:1684:31: 0xa068c3 in Compilation.update (zig1)
    try self.performAllTheWork();
                              ^
/home/jacob/dev/zig/src/main.zig:2368:20: 0x99d59f in main.updateModule (zig1)
    try comp.update();
                   ^
/home/jacob/dev/zig/src/main.zig:2100:17: 0x8cbb83 in main.buildOutputType (zig1)
    updateModule(gpa, comp, hook) catch |err| switch (err) {
                ^
/home/jacob/dev/zig/src/main.zig:211:31: 0x8a0c8b in main.mainArgs (zig1)
        return buildOutputType(gpa, arena, args, .run);
                              ^
/home/jacob/dev/zig/src/stage1.zig:49:24: 0x8a0379 in main (zig1)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                       ^
Aborted (core dumped)
/tmp via ↯ v0.9.0-dev.453+7ef854682 took 4s
❯
rohlem commented 3 years ago

Here's a more minimal test case I reduced from my own code that hit the same assert:

//any slice value works that isn't comptime-known
//(the function boundary makes the caller treat the result as a runtime value)
fn makeRuntimeSliceZ() [:0]const u8 {return "asdf";}
fn stub(c: [*:0]const u8) void {_ = c;}
test "runtime slice slicing in function argument" {
 //any slicing operation in an argument position triggers the error, [2..] as well as no-op [0..]
 stub(makeRuntimeSliceZ()[0..]);
}

Tested on Windows 7 with ziglang.org-provided zig-windows-x86_64-0.9.0-dev.685+e5e6ceda6, hits the same assert (currently at codegen.cpp:1860). This is pretty far removed from what my code was doing though, and I don't see any apparent slicing in the original example provided here, so this may be a different underlying issue leading to the same assertion failure.

fogti commented 2 years ago

I managed to also trigger this by abusing async with zig 5cf918143c7c5857142ac12c3587928ed74b2052: Panics:

pub fn h_call(yieldref: *u32) void {
    suspend yieldref.* = 1;
}

test "simple" {
    var g = struct {
        f: ?@Frame(h_call) = null,
        yieldref_: u32 = undefined,
    }{};
    g.yieldref_ = undefined;
    g.f = async h_call(&g.yieldref_); // <-- assert hit here
}

Doesn't panic:

pub fn h_call(yieldref: *u32) void {
    suspend yieldref.* = 1;
}

test "simple" {
    var yieldref_: u32 = undefined;
    var f: @Frame(h_call) = async h_call(&yieldref_);
    resume f;
}