zig icon indicating copy to clipboard operation
zig copied to clipboard

Sema unreachable on `runtime_store` at comptime

Open ssmid opened this issue 7 months ago • 0 comments

Edit: Shortened reproducer

Zig Version

0.14.0-dev.121+ab4c461b7

Steps to Reproduce and Observed Behavior

Compiler crashes when compiling this comptime code:

const std = @import("std");

pub fn main() !void {
    comptime {
        var fa_buffer: [10 * 1024]u8 = undefined;
        var fa = FixedBufferForwardAllocator.init(&fa_buffer);
        const allocator = fa.allocator();
        var list = std.ArrayList([*]const u8).init(allocator);
        const value = "test";
        try list.append(value.ptr);
    }
}

const FixedBufferForwardAllocator = struct {
    // no free, only allocations
    // this is a temporary workaround for https://github.com/ziglang/zig/issues/19153
    const Self = @This();

    buffer: []u8,
    free_index: usize = 0,

    fn init(buffer: []u8) Self {
        return .{ .buffer = buffer };
    }

    fn alloc(ctx: *anyopaque, n: usize, log2_ptr_align: u8, return_address: usize) ?[*]u8 {
        _ = return_address;
        const self: *Self = @ptrCast(@alignCast(ctx));
        const index = std.mem.alignForwardLog2(self.free_index, log2_ptr_align);
        const end = index + n;
        if (end <= self.buffer.len) {
            self.free_index = end;
            return self.buffer[index..end].ptr;
        }
        return null;
    }

    fn resize(
        ctx: *anyopaque,
        buf: []u8,
        log2_buf_align: u8,
        new_size: usize,
        return_address: usize,
    ) bool {
        _ = ctx;
        _ = buf;
        _ = log2_buf_align;
        _ = new_size;
        _ = return_address;
        return false;
    }

    fn free(
        ctx: *anyopaque,
        buf: []u8,
        log2_buf_align: u8,
        return_address: usize,
    ) void {
        _ = ctx;
        _ = buf;
        _ = log2_buf_align;
        _ = return_address;
    }

    fn allocator(self: *Self) std.mem.Allocator {
        return .{
            .ptr = self,
            .vtable = &.{
                .alloc = alloc,
                .resize = resize,
                .free = free,
            },
        };
    }
};
Trace/Breakpoint triggered (core dumped)

Error code: 133 / -5

Motivation for this is an xml parser for wayland.

Stack trace
thread 12731 panic: reached unreachable code
Analyzing lib/std/array_list.zig
      %985 = ret_type() 
      %986 = dbg_stmt(2, 34)
      %987 = ref(%977) 
      %988 = dbg_stmt(2, 49)
      %989 = field_call(.auto, %987, "addOne", []) 
      %990 = try(%989, {
        %991 = err_union_code(%989) 
        %992 = dbg_stmt(2, 34)
        %993 = ret_node(%991) 
      }) 
      %994 = dbg_var_val(%990, "new_item_ptr")
      %995 = save_err_ret_index(%990)
      %996 = dbg_stmt(3, 13)
      %997 = validate_deref(%990) 
    > %998 = store_node(%990, %980) 
      %999 = restore_err_ret_index_unconditional(.none) 
      %1000 = ret_implicit(@void_value) 
    For full context, use the command
      zig ast-check -t lib/std/array_list.zig

  in a.zig
    > %97 = field_call(.compile_time, %83, "append", [
        {%98, %99},
      ]) node_offset:23:13 to :23:35
  in a.zig
    > %65 = block_comptime({%66..%104}) node_offset:17:14 to :17:14
  in lib/std/start.zig
    > %1984 = is_non_err(%1983) 
  in lib/std/start.zig
    > %1986 = block({%1981..%1985}) 
  in lib/std/start.zig
    > %1948 = switch_block(%1944,
        else => {%1966..%2045},
        @void_type => {%1949..%1957},
        @noreturn_type, @u8_type => {%1958..%1965}) 
  in lib/std/start.zig
    > %1749 = call(.auto, %1747, []) 
  in lib/std/start.zig
    > %1586 = call(.auto, %1584, [
        {%1587},
        {%1588},
        {%1589},
      ]) 
  in lib/std/start.zig
    > %1583 = field_call(nodiscard .auto, %1581, "exit", [
        {%1584..%1590},
      ]) 

/home/vexu/Documents/zig/zig/src/Sema.zig:31214:27: 0xb25a940 in storePtrVal (zig)
        .runtime_store => unreachable, // use sites check this
                          ^it
/home/vexu/Documents/zig/zig/src/Sema.zig:31016:33: 0xb171570 in storePtr2 (zig)
            try sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty);
                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:5725:26: 0xaddf620 in zirStoreNode (zig)
    return sema.storePtr2(block, src, ptr, ptr_src, operand, operand_src, air_tag);
                         ^xit
/home/vexu/Documents/zig/zig/src/Sema.zig:1380:38: 0xa8cd429 in analyzeBodyInner (zig)
                try sema.zirStoreNode(block, inst);
                                     ^
/home/vexu/Documents/zig/zig/src/Sema.zig:914:26: 0xb16cd61 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^xit
/home/vexu/Documents/zig/zig/src/Sema.zig:7896:35: 0xae0f61e in analyzeCall (zig)
                sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                                  ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7101:43: 0xad3a2c5 in zirCall__anon_96666 (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/vexu/Documents/zig/zig/src/Sema.zig:1045:62: 0xa8c3e7d in analyzeBodyInner (zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:932:30: 0xa594527 in analyzeInlineBody (zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:958:39: 0xa32195e in resolveInlineBody (zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/vexu/Documents/zig/zig/src/Sema.zig:6158:38: 0xb21460b in resolveBlockBody (zig)
        return sema.resolveInlineBody(child_block, body, body_inst);
                                     ^
/home/vexu/Documents/zig/zig/src/Sema.zig:6140:33: 0xadf633d in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:1591:49: 0xa8d22a4 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);main
                                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:914:26: 0xb16cd61 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^xit
/home/vexu/Documents/zig/zig/src/Zcu/PerThread.zig:2192:23: 0xace153d in analyzeFnBody (zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^ndExit
/home/vexu/Documents/zig/zig/src/Zcu/PerThread.zig:718:31: 0xa89940b in ensureFuncBodyAnalyzed (zig)
    var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                              ^
/home/vexu/Documents/zig/zig/src/Sema.zig:32152:30: 0xae1cccd in ensureFuncBodyAnalyzed (zig)
    pt.ensureFuncBodyAnalyzed(func) catch |err| {
                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:35909:40: 0xa8f42c1 in resolveInferredErrorSet (zig)
        try sema.ensureFuncBodyAnalyzed(func_index);
                                       ^
/home/vexu/Documents/zig/zig/src/Sema.zig:32524:69: 0xadf33be in analyzeIsNonErrComptimeOnly (zig)
                const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
                                                                    ^
/home/vexu/Documents/zig/zig/src/Sema.zig:32553:56: 0xb1e9ba9 in analyzeIsNonErr (zig)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
/home/vexu/Documents/zig/zig/src/Sema.zig:19335:32: 0xad48365 in zirIsNonErr (zig)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
/home/vexu/Documents/zig/zig/src/Sema.zig:1086:66: 0xa8c5820 in analyzeBodyInner (zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/home/vexu/Documents/zig/zig/src/Sema.zig:6163:34: 0xb21475b in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/vexu/Documents/zig/zig/src/Sema.zig:6140:33: 0xadf633d in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:1591:49: 0xa8d22a4 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);art.posixCallMainAndExit
                                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:6163:34: 0xb21475b in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/vexu/Documents/zig/zig/src/Sema.zig:11029:45: 0xb20af30 in resolveProngComptime (zig)
                return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);AndExit
                                            ^
/home/vexu/Documents/zig/zig/src/Sema.zig:13301:36: 0xb20ab13 in resolveSwitchComptime (zig)
    return spa.resolveProngComptime(
                                   ^
/home/vexu/Documents/zig/zig/src/Sema.zig:12421:37: 0xad5917f in zirSwitchBlock (zig)
        return resolveSwitchComptime(
                                    ^
/home/vexu/Documents/zig/zig/src/Sema.zig:1109:69: 0xa8c664c in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                    ^
/home/vexu/Documents/zig/zig/src/Sema.zig:914:26: 0xb16cd61 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^xit
/home/vexu/Documents/zig/zig/src/Sema.zig:7896:35: 0xae0f61e in analyzeCall (zig)
                sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                                  ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7101:43: 0xad38fb4 in zirCall__anon_96665 (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/vexu/Documents/zig/zig/src/Sema.zig:1044:62: 0xa8c3de0 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:914:26: 0xb16cd61 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^xit
/home/vexu/Documents/zig/zig/src/Sema.zig:7896:35: 0xae0f61e in analyzeCall (zig)
                sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                                  ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7101:43: 0xad38fb4 in zirCall__anon_96665 (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/vexu/Documents/zig/zig/src/Sema.zig:1044:62: 0xa8c3de0 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:932:30: 0xa594527 in analyzeInlineBody (zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:958:39: 0xa32195e in resolveInlineBody (zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7392:65: 0xb2b95f5 in analyzeArg (zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7951:49: 0xae1042f in analyzeCall (zig)
            arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);
                                                ^
/home/vexu/Documents/zig/zig/src/Sema.zig:7101:43: 0xad3a2c5 in zirCall__anon_96666 (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/vexu/Documents/zig/zig/src/Sema.zig:1045:62: 0xa8c3e7d in analyzeBodyInner (zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/vexu/Documents/zig/zig/src/Sema.zig:914:26: 0xb16cd61 in analyzeFnBody (zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^

Expected Behavior

Compiler does not crash and provides a meaningful error message.

ssmid avatar Jul 23 '24 21:07 ssmid