zig icon indicating copy to clipboard operation
zig copied to clipboard

Runtime safety check added in comptime block

Open xhook opened this issue 9 months ago • 2 comments

Zig Version

0.13.0-dev.266+0b0625ccf

Steps to Reproduce and Observed Behavior

I am learning Zig by experimenting with writing a simple neural network code and experience a compiler crash. I tried to distill the code to the very minimum, that causes the crash. This code is not entirely correct, and being frank, I don't even know if it should compile at all. But certainly it should not crash.

const std = @import("std");

pub fn Layer(comptime M: usize, comptime N: usize) type {
    return struct {
        const Self = @This();
        neurons: [N*M]f32,
    };
}

fn MLP(comptime N: usize, comptime nin: usize, comptime nouts: [N]usize) type {
    const sz = [_]usize{nin} ++ nouts;
    return struct {
        const Self = @This();

        layers: [N]*anyopaque,

        pub fn init() !Self {
            var layers = [_]*anyopaque{undefined} ** N;
            for (0..N) |i| {
                const layer_type = Layer(sz[i], sz[i + 1]);
                layers[i] = try std.heap.page_allocator.create(layer_type);
            }
            return Self{ .layers = layers };
        }
    };
}

pub fn main() !void {
    const mlp = MLP(3, 2, [_]usize{ 16, 16, 1 }).init();
    std.debug.print("mlp.layers.len {}\n", .{mlp.layers.len});
}

By running the above code I get the following error:

user@xi:~/Projects/zigrad$ ~/Projects/zig/build_master/stage3/bin/zig run src/zig_crash.zig
thread 81111 panic: reached unreachable code
Analyzing src/zig_crash.zig: zig_crash.zig:MLP(3,2,.{ 16, 16, 1 }).init
      %82 = extended(closure_get(1)) 
      %83 = dbg_stmt(4, 44)
    > %84 = elem_val_node(%82, %73) 
      %85 = break_inline(%81, %84)
    For full context, use the command
      zig ast-check -t src/zig_crash.zig

  in src/zig_crash.zig: zig_crash.zig:MLP(3,2,.{ 16, 16, 1 }).init
    > %81 = call(.auto, %79, [
        {%82..%85},
        {%86..%91},
      ]) 
  in src/zig_crash.zig: zig_crash.zig:MLP(3,2,.{ 16, 16, 1 }).init
    > %75 = condbr(%74, {%77..%110}, {%111}) 
  in src/zig_crash.zig: zig_crash.zig:MLP(3,2,.{ 16, 16, 1 }).init
    > %76 = block({%74, %75}) 
  in src/zig_crash.zig: zig_crash.zig:MLP(3,2,.{ 16, 16, 1 }).init
    > %72 = loop({%73..%114}) 

/home/user/Projects/zig/lib/std/debug.zig:403:14: 0x18182cc in assert (zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/user/Projects/zig/src/Sema.zig:27184:11: 0x2743f45 in panicIndexOutOfBounds (zig)
    assert(!parent_block.is_comptime);
          ^
/home/user/Projects/zig/src/Sema.zig:28786:43: 0x21d99a7 in elemValArray (zig)
            try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
                                          ^
/home/user/Projects/zig/src/Sema.zig:28583:43: 0x2a81b4e in elemVal (zig)
        .Array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
                                          ^
/home/user/Projects/zig/src/Sema.zig:10848:24: 0x25c724a in zirElemValNode (zig)
    return sema.elemVal(block, src, array, elem_index, elem_index_src, true);
                       ^
/home/user/Projects/zig/src/Sema.zig:1028:69: 0x20b196a in analyzeBodyInner (zig)
            .elem_val_node                => try sema.zirElemValNode(block, inst),
                                                                    ^
/home/user/Projects/zig/src/Sema.zig:910:30: 0x1de0187 in analyzeInlineBody (zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/user/Projects/zig/src/Sema.zig:936:39: 0x1b396ae in resolveInlineBody (zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/user/Projects/zig/src/Sema.zig:7426:65: 0x2cae5b4 in analyzeArg (zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/user/Projects/zig/src/Sema.zig:8116:56: 0x2cac915 in analyzeInlineCallArg (zig)
            const casted_arg = try args_info.analyzeArg(ics.caller(), arg_block, arg_i.*, Type.fromInterned(param_ty), func_ty_info, func_inst);
                                                       ^
/home/user/Projects/zig/src/Sema.zig:7827:62: 0x27313e2 in analyzeCall (zig)
            const opt_noreturn_ref = try analyzeInlineCallArg(
                                                             ^
/home/user/Projects/zig/src/Sema.zig:7136:43: 0x25c22ee in zirCall__anon_93341 (zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/user/Projects/zig/src/Sema.zig:1014:62: 0x20b1057 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/user/Projects/zig/src/Sema.zig:874:26: 0x2acc31f in analyzeBodyRuntimeBreak (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/user/Projects/zig/src/Sema.zig:19287:37: 0x2677c67 in zirCondbr (zig)
    try sema.analyzeBodyRuntimeBreak(&sub_block, then_body);
                                    ^
/home/user/Projects/zig/src/Sema.zig:1693:39: 0x20bd47a in analyzeBodyInner (zig)
                    try sema.zirCondbr(block, inst);
                                      ^
/home/user/Projects/zig/src/Sema.zig:6176:34: 0x2acc9cb in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/user/Projects/zig/src/Sema.zig:6153:33: 0x267cfae in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/user/Projects/zig/src/Sema.zig:1559:49: 0x20bf4d0 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                                ^
/home/user/Projects/zig/src/Sema.zig:5968:30: 0x267427f in zirLoop (zig)
    try sema.analyzeBodyInner(&loop_block, body);
                             ^
/home/user/Projects/zig/src/Sema.zig:1534:68: 0x20bc316 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirLoop(block, inst);
                                                                   ^
/home/user/Projects/zig/src/Sema.zig:892:26: 0x20afc91 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/user/Projects/zig/src/Module.zig:4633:23: 0x1d9dc5f in analyzeFnBody (zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/user/Projects/zig/src/Module.zig:3143:32: 0x1b07fc8 in ensureFuncBodyAnalyzed (zig)
    var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                               ^
/home/user/Projects/zig/src/Compilation.zig:3414:42: 0x1b05ae2 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/user/Projects/zig/src/Compilation.zig:3354:30: 0x193ac7f in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/user/Projects/zig/src/Compilation.zig:2132:31: 0x1936683 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/user/Projects/zig/src/main.zig:4489:24: 0x19678af in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/user/Projects/zig/src/main.zig:3411:17: 0x19d0352 in buildOutputType (zig)
    updateModule(comp, color) catch |err| switch (err) {
                ^
/home/user/Projects/zig/src/main.zig:270:31: 0x181a7f9 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .run);
                              ^
/home/user/Projects/zig/src/main.zig:208:20: 0x1817495 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/user/Projects/zig/lib/std/start.zig:524:37: 0x1816f2e in main (zig)
            const result = root.main() catch |err| {
                                    ^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x75ea25429d8f in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:392:3: 0x75ea25429e3f in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x1816b74 in ??? (???)
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)

Tried also running it on v0.12.0 as well as 0.12.x branch. The result is the same.

Expected Behavior

The compiler should give a compilation error or compile the code.

xhook avatar May 25 '24 08:05 xhook