Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stage2: unreachable in checkComptimeVarStore #12787

Closed
mitchellh opened this issue Sep 8, 2022 · 4 comments
Closed

stage2: unreachable in checkComptimeVarStore #12787

mitchellh opened this issue Sep 8, 2022 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@mitchellh
Copy link
Sponsor Contributor

mitchellh commented Sep 8, 2022

Zig Version

0.10.0-dev.3900+ab4b26d8a

Steps to Reproduce

const std = @import("std");

test {
    const Widget = union(enum) { a: u0 };

    const block: Widget = block: {
        const info = @typeInfo(Widget).Union;
        inline for (info.fields) |field| {
            if (std.mem.eql(u8, "anything", field.name)) {
                switch (field.field_type) {
                    u0 => break :block @unionInit(Widget, field.name, 0),
                    else => unreachable,
                }
            }
        }

        unreachable;
    };

    _ = block;
}

zig test repro.zig -- fails
zig test repro.zig -fstage1 -- passes

Note: the u0 can be any type it appears...

Further, if you reduce it further and remove the switch, you actually get a "store to comptime variable depends on runtime condition" rather than a crash on unreachable. So there are perhaps two bugs here, with one masking the other.

Expected Behavior

Tests pass (to match stage1)

Actual Behavior

thread 2093712 panic: reached unreachable code
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:18378:9: 0x1966903 in checkComptimeVarStore (zig)
        unreachable;
        ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:24313:35: 0x196168b in storePtrVal (zig)
    try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);
                                  ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:24238:33: 0x171b4b7 in storePtr2 (zig)
            try sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty);
                                ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:24164:26: 0x1b77683 in storePtr (zig)
    return sema.storePtr2(block, src, ptr, src, uncasted_operand, src, .store);
                         ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:4444:25: 0x194b45b in zirStore (zig)
    return sema.storePtr(block, sema.src, ptr, value);
                        ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:1044:34: 0x171115f in analyzeBodyInner (zig)
                try sema.zirStore(block, inst);
                                 ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:626:45: 0x157d1ff in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:1280:65: 0x171436b in analyzeBodyInner (zig)
                const opt_break_data = try sema.analyzeBodyBreak(block, inline_body);
                                                                ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:4850:34: 0x1b6d627 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:4833:33: 0x1956327 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:1239:69: 0x1713b17 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirBlock(block, inst);
                                                                    ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:609:30: 0x170376b in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Module.zig:5570:21: 0x15687d7 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Module.zig:4271:40: 0x1394863 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:25967:36: 0x1c35b73 in ensureFuncBodyAnalyzed (zig)
    sema.mod.ensureFuncBodyAnalyzed(func) catch |err| {
                                   ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:28086:40: 0x1a077cb in resolveInferredErrorSet (zig)
        try sema.ensureFuncBodyAnalyzed(ies.func);
                                       ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:26246:49: 0x1959ae3 in analyzeIsNonErrComptimeOnly (zig)
                try sema.resolveInferredErrorSet(block, src, ies);
                                                ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:15135:60: 0x1958d43 in zirTry (zig)
    const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
                                                           ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:1365:67: 0x1715b47 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
                                                                  ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:626:45: 0x157d1ff in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:591:50: 0x1b3bf97 in resolveBody (zig)
    const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                                 ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:5588:46: 0x18c38b3 in zirCall (zig)
        const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);
                                             ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:725:62: 0x1704fe7 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst),
                                                             ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Sema.zig:609:30: 0x170376b in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Module.zig:5570:21: 0x15687d7 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Module.zig:4271:40: 0x1394863 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Compilation.zig:2976:42: 0x1392fdf in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Compilation.zig:2914:30: 0x12b43ff in performAllTheWork (zig)
            try processOneJob(comp, work_item);
                             ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/Compilation.zig:2254:31: 0x12b1333 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/main.zig:3348:20: 0x12d715f in updateModule (zig)
    try comp.update();
                   ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/main.zig:3022:17: 0x109f577 in buildOutputType (zig)
    updateModule(gpa, comp, hook) catch |err| switch (err) {
                ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/main.zig:236:31: 0x102df6f in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/mitchellh/code/go/src/github.com/ziglang/zig/src/stage1.zig:48:24: 0x102d423 in main (zig)
        stage2.mainArgs(gpa, arena, args) catch unreachable;
                       ^
???:?:?: 0xffff74bf73f3 in ??? (???)
???:?:?: 0xffff74bf74cf in ??? (???)
../sysdeps/aarch64/start.S:81:0: 0x7ba3af in ??? (../sysdeps/aarch64/start.S)
@mitchellh mitchellh added the bug Observed behavior contradicts documented or intended behavior label Sep 8, 2022
@mitchellh mitchellh changed the title unreachable in checkComptimeVarStore stage2: unreachable in checkComptimeVarStore Sep 8, 2022
@Vexu
Copy link
Member

Vexu commented Sep 8, 2022

Here's a small patch that should turn that crash into a (likely invalid) compile error:

diff --git a/src/Sema.zig b/src/Sema.zig
index 15e891ef8..737f572e2 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -5218,6 +5218,10 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
                 if (block.runtime_cond == null and block.runtime_loop == null) {
                     block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;
                     block.runtime_loop = start_block.runtime_loop;
+                    if (block.runtime_cond == null and block.runtime_loop == null) {
+                        const block_data = sema.code.instructions.items(.data)[zir_block].pl_node;
+                        block.runtime_cond = block_data.src();
+                    }
                 }
                 return inst;
             }

Maybe it'll help in finding out what is causing the crash?

@Vexu Vexu added the stage1 The process of building from source via WebAssembly and the C backend. label Sep 8, 2022
@Vexu Vexu added this to the 0.10.0 milestone Sep 8, 2022
@mitchellh
Copy link
Sponsor Contributor Author

mitchellh commented Sep 8, 2022

Thanks. I’ll give it a shot. Note you labeled this stage1 but this passes with stage1 and fails with stage2 so this should be labeled stage2.

@Vexu Vexu added frontend Tokenization, parsing, AstGen, Sema, and Liveness. and removed stage1 The process of building from source via WebAssembly and the C backend. labels Sep 8, 2022
@mitchellh
Copy link
Sponsor Contributor Author

Thanks @Vexu I've minimized it.

const std = @import("std");

test {
    const Widget = union(enum) { a: u0 };

    const block: Widget = block: {
        const info = @typeInfo(Widget).Union;
        inline for (info.fields) |field| {
            if (std.mem.eql(u8, "anything", field.name)) {
                switch (field.field_type) {
                    u0 => break :block @unionInit(Widget, field.name, 0),
                    else => unreachable,
                }
            }
        }

        unreachable;
    };

    _ = block;
}

@mitchellh
Copy link
Sponsor Contributor Author

mitchellh commented Sep 8, 2022

Note: the u0 can be any type it appears...

Further, if you reduce it further and remove the switch, you actually get a "store to comptime variable depends on runtime condition" rather than a crash on unreachable. So there are perhaps two bugs here, with one masking the other.

Vexu added a commit to Vexu/zig that referenced this issue Sep 9, 2022
Vexu added a commit to Vexu/zig that referenced this issue Sep 9, 2022
@Vexu Vexu closed this as completed in bf4a3df Sep 16, 2022
Vexu added a commit to Vexu/zig that referenced this issue Oct 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

No branches or pull requests

2 participants