ziglang / zig

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

Union comptime var compiler crash #19720

Open jean-dao opened 7 months ago

jean-dao commented 7 months ago

Zig Version

0.12.0

Steps to Reproduce and Observed Behavior

// bug.zig
pub fn main() void {
    comptime var def: union(enum) { bar: []const u8, foo } = undefined;
    def = .{ .bar = "bar" };
}

With the zig binary from the release tarball:

$ zig build-exe bug.zig
Trace/breakpoint trap
With a debug 0.12.0 `zig`: ```sh $ ../zig/stage3/bin/zig build-exe bug.zig thread 22657 panic: reached unreachable code /home/jean/src/zig/lib/std/debug.zig:403:14: 0x9e657fc in assert (zig) if (!ok) unreachable; // assertion failure ^ /home/jean/src/zig/src/Module.zig:6145:11: 0xa2036ad in getUnionLayout (zig) assert(u.haveLayout(ip)); ^ /home/jean/src/zig/src/type.zig:2002:34: 0xa1fe01d in unionGetLayout (zig) return mod.getUnionLayout(union_obj); ^ /home/jean/src/zig/src/codegen/llvm.zig:9351:44: 0xa790198 in airSetUnionTag (zig) const layout = un_ty.unionGetLayout(mod); ^ /home/jean/src/zig/src/codegen/llvm.zig:4933:59: 0xa3e3a4d in genBody (zig) .set_union_tag => try self.airSetUnionTag(inst), ^ /home/jean/src/zig/src/codegen/llvm.zig:1709:19: 0xa3dc9c6 in updateFunc (zig) fg.genBody(air.getMainBody()) catch |err| switch (err) { ^ /home/jean/src/zig/src/link/Elf.zig:3029:70: 0xa720819 in updateFunc (zig) if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness); ^ /home/jean/src/zig/src/link.zig:420:82: 0xa3eb158 in updateFunc (zig) return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(module, func_index, air, liveness); ^ /home/jean/src/zig/src/Module.zig:3219:22: 0xa15dd37 in ensureFuncBodyAnalyzed (zig) lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) { ^ /home/jean/src/zig/src/Compilation.zig:3419:42: 0xa15ae62 in processOneJob (zig) module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { ^ /home/jean/src/zig/src/Compilation.zig:3359:30: 0x9f89f9a in performAllTheWork (zig) try processOneJob(comp, work_item, main_progress_node); ^ /home/jean/src/zig/src/Compilation.zig:2132:31: 0x9f854d2 in update (zig) try comp.performAllTheWork(main_progress_node); ^ /home/jean/src/zig/src/main.zig:4483:24: 0x9fb6c2f in updateModule (zig) try comp.update(main_progress_node); ^ /home/jean/src/zig/src/main.zig:3405:17: 0xa01f554 in buildOutputType (zig) updateModule(comp, color) catch |err| switch (err) { ^ /home/jean/src/zig/src/main.zig:260:31: 0x9e67a31 in mainArgs (zig) return buildOutputType(gpa, arena, args, .{ .build = .Exe }); ^ /home/jean/src/zig/src/main.zig:206:20: 0x9e649c5 in main (zig) return mainArgs(gpa, arena, args); ^ /home/jean/src/zig/lib/std/start.zig:511:37: 0x9e6445e in main (zig) const result = root.main() catch |err| { ^ ../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7f9e5c05ec4b in __libc_start_call_main (../sysdeps/x86/libc-start.c) ../csu/libc-start.c:360:3: 0x7f9e5c05ed04 in __libc_start_main_impl (../sysdeps/x86/libc-start.c) ../sysdeps/x86_64/start.S:115:0: 0x4f6eb60 in _start (../sysdeps/x86_64/start.S) ???:?:?: 0x0 in ??? (???) Aborted ```
AIR logs (crashes in `print_value.zig`) ``` # Begin Function AIR: start._start: # Total AIR+Liveness bytes: 394B # AIR Instructions: 10 (90B) # AIR Extra Data: 48 (192B) # Liveness tomb_bits: 8B # Liveness Extra Data: 0 (0B) # Liveness special table: 0 (0B) %0!= save_err_return_trace_index() %1!= dbg_stmt(17:5) %8!= assembly(void, volatile, [argc_argv_ptr] out =m = (<*[*]usize, start.argc_argv_ptr>), [posixCallMainAndExit] in X = (<*const fn () callconv(.C) noreturn, start.posixCallMainAndExit>), " xorl %%ebp, %%ebp movq %%rsp, %[argc_argv_ptr] andq $-16, %%rsp callq %[posixCallMainAndExit:P]") %9!= trap() # End Function AIR: start._start # Begin Function AIR: start.posixCallMainAndExit: # Total AIR+Liveness bytes: 4.8603515625KiB # AIR Instructions: 273 (2.3994140625KiB) # AIR Extra Data: 411 (1.60546875KiB) # Liveness tomb_bits: 144B # Liveness Extra Data: 95 (380B) # Liveness special table: 31 (248B) %0!= save_err_return_trace_index() %1!= dbg_stmt(2:5) %2 = load([*]usize, <*[*]usize, start.argc_argv_ptr>) %3!= dbg_stmt(2:31) %4 = ptr_elem_val(%2!, @Air.Inst.Ref.zero_usize) %5!= dbg_var_val(%4, "argc") %6!= dbg_stmt(3:5) %8 = load([*]usize, <*[*]usize, start.argc_argv_ptr>) %9!= dbg_stmt(3:57) %10 = ptr_add([*]usize, %8!, @Air.Inst.Ref.one_usize) %11!= dbg_stmt(3:34) %12 = bitcast([*][*:0]u8, %10!) %13!= dbg_var_val(%12, "argv") %14!= dbg_stmt(5:70) %16 = ptr_add([*][*:0]u8, %12, %4) %17!= dbg_stmt(5:77) %18 = ptr_add([*][*:0]u8, %16!, @Air.Inst.Ref.one_usize) %19!= dbg_stmt(5:45) %20 = bitcast([*:null]?[*:0]u8, %18!) %21!= dbg_var_val(%20, "envp_optional") %22!= dbg_stmt(6:5) %23 = alloc(*usize) %24!= store_safe(%23, @Air.Inst.Ref.zero_usize) %25!= dbg_var_ptr(%23, "envp_count") %26!= block(void, { %27!= loop(noreturn, { %28!= block(void, { %29!= dbg_stmt(7:12) %30 = load(usize, %23) %31!= dbg_stmt(7:25) %32 = ptr_elem_val(%20, %30!) %33 = is_non_null(%32!) %44!= cond_br(%33!, { %34!= optional_payload([*:0]u8, %32) %36!= dbg_stmt(7:46) %38 = load(usize, %23) %39!= dbg_stmt(7:57) %40 = add_safe(%38!, @Air.Inst.Ref.one_usize) %41!= store_safe(%23, %40!) %42!= br(%28, @Air.Inst.Ref.void_value) }, { %43!= br(%26, @Air.Inst.Ref.void_value) }) }) }) }) %45!= dbg_stmt(8:34) %47 = bitcast([*][*:0]u8, %20!) %48 = alloc(*[*][*:0]u8) %49!= store_safe(%48, %47!) %50 = bitcast(*const [*][*:0]u8, %48!) %51 = load(usize, %23) %52!= dbg_stmt(8:58) %53 = load([*][*:0]u8, %50!) %54 = ptr_add([*][*:0]u8, %53!, @Air.Inst.Ref.zero_usize) %55 = cmp_lte(@Air.Inst.Ref.zero_usize, %51) %58!= block(void, { %59!= cond_br(%55!, { %60!= br(%58, @Air.Inst.Ref.void_value) }, { %12! %4! %54! %23! %56!= call(, [@Air.Inst.Ref.zero_usize, %51!]) %57!= unreach() }) } %55!) %61 = cmp_lte(@Air.Inst.Ref.zero_usize, %51) %64!= block(void, { %65!= cond_br(%61!, { %66!= br(%64, @Air.Inst.Ref.void_value) }, { %12! %4! %54! %23! %62!= call(, [@Air.Inst.Ref.zero_usize, %51!]) %63!= unreach() }) } %61!) %67 = slice([][*:0]u8, %54!, %51!) %68!= dbg_var_val(%67, "envp") %69!= dbg_stmt(10:9) %70!= block(void, { %71!= dbg_stmt(12:59) %73 = slice_ptr([*][*:0]u8, %67) %74 = load(usize, %23!) %75!= dbg_stmt(12:64) %76 = ptr_add([*][*:0]u8, %73!, %74!) %77!= dbg_stmt(12:77) %78 = ptr_add([*][*:0]u8, %76!, @Air.Inst.Ref.one_usize) %79!= dbg_stmt(12:35) %80 = bitcast([*]elf.Elf64_auxv_t, %78!) %81!= dbg_var_val(%80, "auxv") %82!= dbg_stmt(13:21) %83 = bitcast(?[*]elf.Elf64_auxv_t, %80) %84!= store_safe(<*?[*]elf.Elf64_auxv_t, os.linux.elf_aux_maybe>, %83!) %85!= dbg_stmt(15:9) %86 = alloc(*usize) %87!= store_safe(%86, @Air.Inst.Ref.zero_usize) %88!= dbg_var_ptr(%86, "at_hwcap") %89!= dbg_stmt(16:9) %90 = block([]elf.Elf64_Phdr, { %91!= dbg_stmt(17:13) %92 = alloc(*usize) %93!= store_safe(%92, @Air.Inst.Ref.zero_usize) %94!= dbg_var_ptr(%92, "i") %95!= dbg_stmt(18:13) %96 = alloc(*usize) %97!= store_safe(%96, @Air.Inst.Ref.zero_usize) %98!= dbg_var_ptr(%96, "at_phdr") %99!= dbg_stmt(19:13) %100 = alloc(*usize) %101!= store_safe(%100, @Air.Inst.Ref.zero_usize) %102!= dbg_var_ptr(%100, "at_phnum") %103!= block(void, { %104!= loop(noreturn, { %105!= block(void, { %106!= dbg_stmt(20:20) %107 = load(usize, %92) %108!= dbg_stmt(20:24) %109 = ptr_elem_val(%80, %107!) %110!= dbg_stmt(20:27) %111 = struct_field_val(%109!, 0) %112!= dbg_stmt(20:41) %113 = cmp_neq(%111!, ) %169!= cond_br(%113!, { %114!= block(void, { %115!= dbg_stmt(21:17) %116 = load(usize, %92) %117!= dbg_stmt(21:29) %118 = ptr_elem_val(%80, %116!) %119!= dbg_stmt(21:32) %120 = struct_field_val(%118!, 0) %121!= dbg_stmt(21:25) %125!= block(void, { %160!= switch_br(%120!, [] => { %126!= dbg_stmt(22:37) %127 = load(usize, %92) %128!= dbg_stmt(22:52) %129 = ptr_elem_val(%80, %127!) %130!= dbg_stmt(22:55) %131 = struct_field_val(%129!, 1) %132!= dbg_stmt(22:60) %133 = struct_field_val(%131!, 0) %134 = bitcast(usize, %133!) %135!= store_safe(%100, %134!) %136!= br(%125, @Air.Inst.Ref.void_value) }, [] => { %137!= dbg_stmt(23:36) %138 = load(usize, %92) %139!= dbg_stmt(23:50) %140 = ptr_elem_val(%80, %138!) %141!= dbg_stmt(23:53) %142 = struct_field_val(%140!, 1) %143!= dbg_stmt(23:58) %144 = struct_field_val(%142!, 0) %145 = bitcast(usize, %144!) %146!= store_safe(%96, %145!) %147!= br(%125, @Air.Inst.Ref.void_value) }, [] => { %148!= dbg_stmt(24:37) %149 = load(usize, %92) %150!= dbg_stmt(24:52) %151 = ptr_elem_val(%80, %149!) %152!= dbg_stmt(24:55) %153 = struct_field_val(%151!, 1) %154!= dbg_stmt(24:60) %155 = struct_field_val(%153!, 0) %156 = bitcast(usize, %155!) %157!= store_safe(%86, %156!) %158!= br(%125, @Air.Inst.Ref.void_value) }, else => { %159!= br(%114, @Air.Inst.Ref.void_value) } ) } %120!) %161!= br(%114, @Air.Inst.Ref.void_value) }) %162!= dbg_stmt(20:54) %163 = load(usize, %92) %164!= dbg_stmt(20:56) %165 = add_safe(%163!, @Air.Inst.Ref.one_usize) %166!= store_safe(%92, %165!) %167!= br(%105, @Air.Inst.Ref.void_value) }, { %80! %92! %86! %168!= br(%103, @Air.Inst.Ref.void_value) }) }) }) } %80! %92! %86!) %170!= dbg_stmt(28:13) %172 = load(usize, %96!) %173!= dbg_stmt(28:42) %174 = cmp_neq(%172, @Air.Inst.Ref.zero_usize) %177!= block(void, { %178!= cond_br(%174!, { %179!= br(%177, @Air.Inst.Ref.void_value) }, { %172! %67! %12! %4! %100! %175!= call(, [<[]const u8, "cast causes pointer to be null"[0..30]>, , ]) %176!= unreach() }) } %174!) %180 = bit_and(%172, ) %181 = cmp_eq(%180!, @Air.Inst.Ref.zero_usize) %184!= block(void, { %185!= cond_br(%181!, { %186!= br(%184, @Air.Inst.Ref.void_value) }, { %172! %67! %12! %4! %100! %182!= call(, [<[]const u8, "incorrect alignment"[0..19]>, , ]) %183!= unreach() }) } %181!) %187 = bitcast([*]elf.Elf64_Phdr, %172!) %188 = alloc(*[*]elf.Elf64_Phdr) %189!= store_safe(%188, %187!) %190 = bitcast(*const [*]elf.Elf64_Phdr, %188!) %191 = load(usize, %100!) %192!= dbg_stmt(28:63) %193 = load([*]elf.Elf64_Phdr, %190!) %194 = ptr_add([*]elf.Elf64_Phdr, %193!, @Air.Inst.Ref.zero_usize) %195 = cmp_lte(@Air.Inst.Ref.zero_usize, %191) %198!= block(void, { %199!= cond_br(%195!, { %200!= br(%198, @Air.Inst.Ref.void_value) }, { %67! %12! %4! %194! %196!= call(, [@Air.Inst.Ref.zero_usize, %191!]) %197!= unreach() }) } %195!) %201 = cmp_lte(@Air.Inst.Ref.zero_usize, %191) %204!= block(void, { %205!= cond_br(%201!, { %206!= br(%204, @Air.Inst.Ref.void_value) }, { %67! %12! %4! %194! %202!= call(, [@Air.Inst.Ref.zero_usize, %191!]) %203!= unreach() }) } %201!) %207 = slice([]elf.Elf64_Phdr, %194!, %191!) %208!= br(%90, %207!) } %80! %86!) %209!= dbg_var_val(%90, "phdrs") %210!= dbg_stmt(33:13) %212!= dbg_stmt(37:13) %215!= dbg_stmt(51:43) %221!= call(, [%90]) %223!= dbg_stmt(58:24) %224!= call(, [%90!]) %225!= br(%70, @Air.Inst.Ref.void_value) } %23!) %226!= dbg_stmt(61:36) %227!= dbg_inline_block(void, , { %228!= dbg_var_val(%4, "argc") %229!= dbg_var_val(%12, "argv") %230!= dbg_var_val(%67, "envp") %231!= dbg_stmt(2:11) %232 = alloc(*[*][*:0]u8) %233!= store_safe(%232, %12!) %234 = bitcast(*const [*][*:0]u8, %232!) %235!= dbg_stmt(2:23) %236 = load([*][*:0]u8, %234!) %237 = ptr_add([*][*:0]u8, %236!, @Air.Inst.Ref.zero_usize) %238 = cmp_lte(@Air.Inst.Ref.zero_usize, %4) %241!= block(void, { %242!= cond_br(%238!, { %243!= br(%241, @Air.Inst.Ref.void_value) }, { %67! %237! %239!= call(, [@Air.Inst.Ref.zero_usize, %4!]) %240!= unreach() }) } %238!) %244 = cmp_lte(@Air.Inst.Ref.zero_usize, %4) %247!= block(void, { %248!= cond_br(%244!, { %249!= br(%247, @Air.Inst.Ref.void_value) }, { %67! %237! %245!= call(, [@Air.Inst.Ref.zero_usize, %4!]) %246!= unreach() }) } %244!) %250 = slice([][*:0]u8, %237!, %4!) %251!= store_safe(<*[][*:0]u8, os.argv>, %250!) %252!= dbg_stmt(3:11) %253!= store_safe(<*[][*:0]u8, os.environ>, %67!) %254!= dbg_stmt(5:41) %255!= call(, []) %256!= dbg_stmt(6:23) %257!= call(, []) %258!= dbg_stmt(8:20) %259!= dbg_inline_block(void, , { %260!= dbg_stmt(2:13) %264!= dbg_stmt(7:22) %265!= call(, []) %266!= dbg_stmt(8:13) %267!= br(%259, @Air.Inst.Ref.void_value) }) %268!= dbg_stmt(8:5) %269!= br(%227, @Air.Inst.Ref.void_value) } %67! %4! %12!) %270!= dbg_stmt(61:19) %271!= call(, [@Air.Inst.Ref.zero_u8]) %272!= unreach() # End Function AIR: start.posixCallMainAndExit # Begin Function AIR: builtin.default_panic: # Total AIR+Liveness bytes: 524B # AIR Instructions: 24 (216B) # AIR Extra Data: 35 (140B) # Liveness tomb_bits: 16B # Liveness Extra Data: 6 (24B) # Liveness special table: 3 (24B) %0 = arg([]const u8, 0) %1 = arg(?*builtin.StackTrace, 1) %2 = arg(?usize, 2) %3!= save_err_return_trace_index() %4!= dbg_stmt(6:9) %6!= dbg_stmt(19:13) %9!= dbg_stmt(86:13) %10 = block(usize, { %11 = is_non_null(%2) %16!= cond_br(%11!, { %12 = optional_payload(usize, %2!) %13!= br(%10, %12!) }, { %2! %14 = ret_addr() %15!= br(%10, %14!) }) } %2!) %17!= dbg_var_val(%10, "first_trace_addr") %18!= dbg_stmt(87:32) %19 = bitcast(?*const builtin.StackTrace, %1!) %20 = wrap_optional(?usize, %10!) %21!= dbg_stmt(87:32) %22!= call(, [%19!, %20!, %0!]) %23!= unreach() # End Function AIR: builtin.default_panic # Begin Function AIR: builtin.panicStartGreaterThanEnd: # Total AIR+Liveness bytes: 286B # AIR Instructions: 10 (90B) # AIR Extra Data: 18 (72B) # Liveness tomb_bits: 8B # Liveness Extra Data: 1 (4B) # Liveness special table: 1 (8B) %0 = arg(usize, 0) %1 = arg(usize, 1) %2!= save_err_return_trace_index() %3!= dbg_stmt(3:25) %4 = ret_addr() %5 = wrap_optional(?usize, %4!) %6 = aggregate_init(struct{usize, usize}, [%0!, %1!]) %7!= dbg_stmt(3:25) %8!= call(, [, %5!, %6!]) %9!= unreach() # End Function AIR: builtin.panicStartGreaterThanEnd # Begin Function AIR: builtin.panicOutOfBounds: # Total AIR+Liveness bytes: 286B # AIR Instructions: 10 (90B) # AIR Extra Data: 18 (72B) # Liveness tomb_bits: 8B # Liveness Extra Data: 1 (4B) # Liveness special table: 1 (8B) %0 = arg(usize, 0) %1 = arg(usize, 1) %2!= save_err_return_trace_index() %3!= dbg_stmt(3:25) %4 = ret_addr() %5 = wrap_optional(?usize, %4!) %6 = aggregate_init(struct{usize, usize}, [%0!, %1!]) %7!= dbg_stmt(3:25) %8!= call(, [, %5!, %6!]) %9!= unreach() # End Function AIR: builtin.panicOutOfBounds # Begin Function AIR: os.linux.tls.initStaticTLS: # Total AIR+Liveness bytes: 2.765625KiB # AIR Instructions: 144 (1.265625KiB) # AIR Extra Data: 250 (1000B) # Liveness tomb_bits: 72B # Liveness Extra Data: 50 (200B) # Liveness special table: 20 (160B) %0 = arg([]elf.Elf64_Phdr, 0) %136 = alloc(*[32]usize) %137 = alloc(*builtin.StackTrace) %138 = struct_field_ptr_index_1(*[]usize, %137) %139 = array_to_slice([]usize, %136!) %140!= store(%138!, %139!) %141 = struct_field_ptr_index_0(*usize, %137) %142!= store(%141!, @Air.Inst.Ref.zero_usize) %143!= set_err_return_trace(%137!) %1!= save_err_return_trace_index() %2!= dbg_stmt(2:12) %3!= call(, [%0!]) %4!= dbg_stmt(4:5) %5 = block([]u8, { %6!= dbg_stmt(7:13) %7!= block(void, { %8 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %9!= dbg_stmt(7:22) %10 = struct_field_val(%8!, 2) %11!= dbg_stmt(7:41) %12 = bitcast(u64, %10!) %13 = cmp_lte(%12!, ) %14 = block(bool, { %24!= cond_br(%13!, { %16 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %17!= dbg_stmt(8:22) %18 = struct_field_val(%16!, 1) %19!= load([8448]u8, <*align(4096) [8448]u8, os.linux.tls.main_thread_tls_buffer>) %20!= dbg_stmt(8:59) %21 = bitcast(u64, %18!) %22 = cmp_lte(%21!, ) %23!= br(%14, %22!) }, { %15!= br(%14, @Air.Inst.Ref.bool_false) }) } %13!) %51!= cond_br(%14!, { %25!= dbg_stmt(10:13) %26 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %27!= dbg_stmt(10:59) %28 = struct_field_val(%26!, 1) %29!= dbg_stmt(10:46) %30 = cmp_lte(@Air.Inst.Ref.zero_usize, %28) %33!= block(void, { %34!= cond_br(%30!, { %35!= br(%33, @Air.Inst.Ref.void_value) }, { %31!= call(, [@Air.Inst.Ref.zero_usize, %28!]) %32!= unreach() }) } %30!) %36 = cmp_lte(%28, ) %39!= block(void, { %40!= cond_br(%36!, { %41!= br(%39, @Air.Inst.Ref.void_value) }, { %37!= call(, [%28!, ]) %38!= unreach() }) } %36!) %42 = cmp_lte(@Air.Inst.Ref.zero_usize, %28) %45!= block(void, { %46!= cond_br(%42!, { %47!= br(%45, @Air.Inst.Ref.void_value) }, { %43!= call(, [@Air.Inst.Ref.zero_usize, %28!]) %44!= unreach() }) } %42!) %48 = slice([]align(4096) u8, <[*]align(4096) u8, @as([*]align(4096) u8, @ptrCast(os.linux.tls.main_thread_tls_buffer[0]))>, %28!) %49!= block(noreturn, { %127 = bitcast([]u8, %48!) %128!= br(%5, %127!) }) }, { %50!= br(%7, @Air.Inst.Ref.void_value) }) }) %52!= dbg_stmt(13:9) %53 = block([]align(4096) u8, { %54!= dbg_stmt(13:42) %55 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %56!= dbg_stmt(15:22) %57 = struct_field_val(%55!, 1) %58 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %59!= dbg_stmt(15:45) %60 = struct_field_val(%58!, 2) %61!= dbg_stmt(15:34) %62 = add_safe(%57!, %60!) %63!= dbg_stmt(15:58) %64 = sub_safe(%62!, @Air.Inst.Ref.one_usize) %65!= dbg_stmt(13:42) %66 = call(, [, %64!, , , , ]) %67 = is_non_err(%66) %75!= cond_br(%67!, { %68 = unwrap_errunion_payload([]align(4096) u8, %66!) %69!= br(%53, %68!) }, { %66! %70!= unwrap_errunion_err(error{MemoryMappingNotSupported,AccessDenied,PermissionDenied,LockedMemoryLimitExceeded,ProcessFdQuotaExceeded,SystemFdQuotaExceeded,OutOfMemory,Unexpected}, %66) %71!= save_err_return_trace_index() %72!= dbg_stmt(20:28) %73!= call(, []) %74!= unreach() }) }) %76 = alloc(*[]align(4096) u8) %77!= store_safe(%76, %53) %78 = bitcast(*const []align(4096) u8, %76!) %79!= dbg_var_val(%53, "alloc_tls_area") %80!= dbg_stmt(23:54) %81 = slice_ptr([*]align(4096) u8, %53!) %82!= dbg_stmt(23:28) %83 = int_from_ptr(%81!) %84!= dbg_var_val(%83, "begin_addr") %85!= dbg_stmt(24:52) %86 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %87!= dbg_stmt(24:81) %88 = struct_field_val(%86!, 2) %89!= dbg_stmt(24:52) %90 = call(, [%83, %88!]) %91!= dbg_var_val(%90, "begin_aligned_addr") %92!= dbg_stmt(25:42) %93 = sub_safe(%90!, %83!) %94!= dbg_var_val(%93, "start") %95!= dbg_stmt(26:9) %96 = load(os.linux.tls.TLSImage, <*os.linux.tls.TLSImage, os.linux.tls.tls_image>) %97!= dbg_stmt(26:61) %98 = struct_field_val(%96!, 1) %99!= dbg_stmt(26:50) %100 = add_safe(%93, %98!) %101!= dbg_stmt(26:34) %102 = load([]align(4096) u8, %78!) %103 = slice_ptr([*]align(4096) u8, %102) %104 = ptr_add([*]u8, %103!, %93) %105 = cmp_lte(%93, %100) %108!= block(void, { %109!= cond_br(%105!, { %110!= br(%108, @Air.Inst.Ref.void_value) }, { %102! %104! %106!= call(, [%93!, %100!]) %107!= unreach() }) } %105!) %111 = sub(%100, %93) %112 = slice_len(usize, %102!) %113 = cmp_lte(%100, %112) %116!= block(void, { %117!= cond_br(%113!, { %112! %118!= br(%116, @Air.Inst.Ref.void_value) }, { %93! %111! %104! %114!= call(, [%100!, %112!]) %115!= unreach() }) } %113! %112!) %119 = cmp_lte(%93, %100) %122!= block(void, { %123!= cond_br(%119!, { %93! %100! %124!= br(%122, @Air.Inst.Ref.void_value) }, { %111! %104! %120!= call(, [%93!, %100!]) %121!= unreach() }) } %93! %119! %100!) %125 = slice([]u8, %104!, %111!) %126!= br(%5, %125!) }) %129!= dbg_var_val(%5, "tls_area") %130!= dbg_stmt(29:32) %131 = call(, [%5!]) %132!= dbg_var_val(%131, "tp_value") %133!= dbg_stmt(30:21) %134!= call(, [%131!]) %135!= ret_safe(@Air.Inst.Ref.void_value) # End Function AIR: os.linux.tls.initStaticTLS # Begin Function AIR: start.expandStackSize: # Total AIR+Liveness bytes: 1.802734375KiB # AIR Instructions: 94 (846B) # AIR Extra Data: 145 (580B) # Liveness tomb_bits: 48B # Liveness Extra Data: 45 (180B) # Liveness special table: 11 (88B) %0 = arg([]elf.Elf64_Phdr, 0) %86 = alloc(*[32]usize) %87 = alloc(*builtin.StackTrace) %88 = struct_field_ptr_index_1(*[]usize, %87) %89 = array_to_slice([]usize, %86!) %90!= store(%88!, %89!) %91 = struct_field_ptr_index_0(*usize, %87) %92!= store(%91!, @Air.Inst.Ref.zero_usize) %93!= set_err_return_trace(%87!) %1 = save_err_return_trace_index() %2 = alloc(*usize) %3!= store_safe(%2, @Air.Inst.Ref.zero_usize) %4!= dbg_stmt(2:10) %5 = slice_len(usize, %0) %6!= block(void, { %7!= loop(noreturn, { %8 = load(usize, %2) %9!= block(void, { %10 = bitcast(u64, %8) %11 = bitcast(u64, %5) %12 = cmp_lt(%10!, %11!) %82!= cond_br(%12!, { %13 = slice_elem_ptr(*elf.Elf64_Phdr, %0, %8) %14!= dbg_var_val(%13, "phdr") %15!= dbg_stmt(3:21) %16 = struct_field_ptr_index_0(*align(8) u32, %13) %17 = load(u32, %16!) %18!= dbg_stmt(3:17) %20!= block(void, { %79!= switch_br(%17!, [] => { %5! %2! %0! %8! %21!= dbg_stmt(5:28) %22 = struct_field_ptr(%13, 6) %23 = load(u64, %22!) %24!= dbg_stmt(5:37) %25 = rem(%23!, ) %26 = cmp_eq(%25!, ) %27!= dbg_stmt(5:23) %28!= call(, [%26!]) %29!= dbg_stmt(8:17) %30 = block(os.linux.rlimit, { %31!= dbg_stmt(8:51) %32 = call(, []) %33 = is_non_err(%32) %42!= cond_br(%33!, { %34 = unwrap_errunion_payload(os.linux.rlimit, %32!) %35!= br(%30, %34!) }, { %13! %32! %36!= unwrap_errunion_err(error{Unexpected}, %32) %37!= save_err_return_trace_index() %38 = err_return_trace(*builtin.StackTrace) %39 = struct_field_ptr_index_0(*usize, %38!) %40!= store(%39!, %1!) %41!= br(%6, @Air.Inst.Ref.void_value) }) }) %43!= dbg_var_val(%30, "limits") %44!= dbg_stmt(11:52) %45 = struct_field_ptr(%13!, 6) %46 = load(u64, %45!) %47!= dbg_stmt(11:68) %48 = struct_field_val(%30, 1) %49 = min(%46!, %48!) %50!= dbg_var_val(%49, "wanted_stack_size") %51!= dbg_stmt(13:21) %52!= block(void, { %53!= dbg_stmt(13:47) %54 = struct_field_val(%30, 0) %55 = cmp_gt(%49, %54!) %75!= cond_br(%55!, { %56!= dbg_stmt(14:21) %57!= block(void, { %58!= dbg_stmt(16:38) %59 = struct_field_val(%30!, 1) %60 = aggregate_init(os.linux.rlimit, [%49!, %59!]) %61!= dbg_stmt(14:40) %62 = call(, [, %60!]) %63 = is_non_err(%62) %72!= cond_br(%63!, { %1! %64 = unwrap_errunion_payload(void, %62!) %65!= br(%57, %64!) }, { %62! %66!= unwrap_errunion_err(error{PermissionDenied,Unexpected,LimitTooBig}, %62) %67!= save_err_return_trace_index() %68 = err_return_trace(*builtin.StackTrace) %69 = struct_field_ptr_index_0(*usize, %68!) %70!= store(%69!, %1!) %71!= br(%57, @Air.Inst.Ref.void_value) }) } %30! %1! %49!) %73!= br(%52, @Air.Inst.Ref.void_value) }, { %30! %1! %49! %74!= br(%52, @Air.Inst.Ref.void_value) }) } %30! %1! %49!) %76!= dbg_stmt(28:17) %77!= br(%6, @Air.Inst.Ref.void_value) }, else => { %13! %78!= br(%20, @Air.Inst.Ref.void_value) } ) } %13! %17!) %80!= br(%9, @Air.Inst.Ref.void_value) }, { %5! %1! %2! %0! %8! %81!= br(%6, @Air.Inst.Ref.void_value) }) }) %83 = add(%8!, @Air.Inst.Ref.one_usize) %84!= store_safe(%2, %83!) }) } %5! %1! %2! %0!) %85!= ret_safe(@Air.Inst.Ref.void_value) # End Function AIR: start.expandStackSize # Begin Function AIR: debug.maybeEnableSegfaultHandler: # Total AIR+Liveness bytes: 207B # AIR Instructions: 7 (63B) # AIR Extra Data: 8 (32B) # Liveness tomb_bits: 8B # Liveness Extra Data: 0 (0B) # Liveness special table: 0 (0B) %0!= save_err_return_trace_index() %1!= dbg_stmt(2:9) %3!= dbg_stmt(3:40) %4!= call(, []) %6!= ret_safe(@Air.Inst.Ref.void_value) # End Function AIR: debug.maybeEnableSegfaultHandler # Begin Function AIR: start.maybeIgnoreSigpipe: # Total AIR+Liveness bytes: 865B # AIR Instructions: 49 (441B) # AIR Extra Data: 58 (232B) # Liveness tomb_bits: 32B # Liveness Extra Data: 6 (24B) # Liveness special table: 4 (32B) %41 = alloc(*[32]usize) %42 = alloc(*builtin.StackTrace) %43 = struct_field_ptr_index_1(*[]usize, %42) %44 = array_to_slice([]usize, %41!) %45!= store(%43!, %44!) %46 = struct_field_ptr_index_0(*usize, %42) %47!= store(%46!, @Air.Inst.Ref.zero_usize) %48!= set_err_return_trace(%42!) %0!= save_err_return_trace_index() %1!= dbg_stmt(2:42) %4!= dbg_var_val(@Air.Inst.Ref.bool_true, "have_sigpipe_support") %5!= dbg_stmt(20:9) %6!= block(void, { %7!= dbg_stmt(22:9) %9!= bitcast(u8, @Air.Inst.Ref.zero_u8) %15!= dbg_stmt(26:26) %19!= bitcast(u8, @Air.Inst.Ref.zero_u8) %20!= dbg_var_ptr(<*const os.linux.Sigaction, &.{ .handler = .{ .handler = start.noopSigHandler }, .mask = .{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .flags = 0, .restorer = null }>, "act") %21!= dbg_stmt(29:9) %22!= block(void, { %23!= dbg_stmt(29:24) %24 = call(, [, , ]) %25 = is_non_err(%24) %38!= cond_br(%25!, { %24! %26!= unwrap_errunion_payload(void, %24) %27!= br(%22, @Air.Inst.Ref.void_value) }, { %28!= unwrap_errunion_err(error{OperationNotSupported}, %24) %29!= save_err_return_trace_index() %30 = unwrap_errunion_err(error{OperationNotSupported}, %24!) %31!= dbg_stmt(30:74) %32 = bitcast(anyerror, %30!) %33 = error_name(%32!) %34 = aggregate_init(struct{[:0]const u8}, [%33!]) %35!= dbg_stmt(30:28) %36!= call(, [%34!]) %37!= unreach() }) }) %39!= br(%6, @Air.Inst.Ref.void_value) }) %40!= ret_safe(@Air.Inst.Ref.void_value) # End Function AIR: start.maybeIgnoreSigpipe # Begin Function AIR: bug.main: # Total AIR+Liveness bytes: 181B # AIR Instructions: 5 (45B) # AIR Extra Data: 6 (24B) # Liveness tomb_bits: 8B # Liveness Extra Data: 0 (0B) # Liveness special table: 0 (0B) %0!= save_err_return_trace_index() %1!= dbg_stmt(3:5) %3!= set_union_tag(<*bug.main__union_3385, thread 22952 panic: attempt to use null value /home/jean/src/zig/src/Value.zig:4051:35: 0xa8644a5 in pointerDerivationAdvanced (zig) const alloc = opt_sema.?.getComptimeAlloc(idx); ^ /home/jean/src/zig/src/print_value.zig:288:61: 0xc0505fd in printPtr__anon_131705 (zig) const derivation = try ptr_val.pointerDerivationAdvanced(arena.allocator(), zcu, opt_sema); ^ /home/jean/src/zig/src/print_value.zig:149:25: 0xbd78037 in print__anon_126848 (zig) try printPtr(val, writer, level, mod, opt_sema); ^ /home/jean/src/zig/src/print_value.zig:32:17: 0xbd75f4a in format__anon_126847 (zig) return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_sema) catch |err| switch (err) { ^ /home/jean/src/zig/lib/std/fmt.zig:1480:26: 0xb83a5c0 in format__anon_119005 (zig) try format_fn(self.data, fmt, options, writer); ^ /home/jean/src/zig/lib/std/fmt.zig:494:32: 0xb333582 in formatType__anon_110890 (zig) return try value.format(actual_fmt, options, writer); ^ /home/jean/src/zig/lib/std/fmt.zig:185:23: 0xc177662 in format__anon_133646 (zig) try formatType( ^ /home/jean/src/zig/lib/std/io/Writer.zig:23:26: 0xbf13aa0 in print__anon_129943 (zig) return std.fmt.format(self, format, args); ^ /home/jean/src/zig/lib/std/io.zig:324:47: 0xbadbcd1 in writeInstRef__anon_124212 (zig) return @errorCast(self.any().print(format, args)); ^ /home/jean/src/zig/src/print_air.zig:938:30: 0xbadad2e in writeOperand__anon_124201 (zig) return w.writeInstRef(s, operand, dies); ^ /home/jean/src/zig/src/print_air.zig:331:27: 0xb65f352 in writeBinOp__anon_116453 (zig) try w.writeOperand(s, inst, 0, bin_op.lhs); ^ /home/jean/src/zig/src/print_air.zig:165:32: 0xb175acb in writeInst__anon_103214 (zig) => try w.writeBinOp(s, inst), ^ /home/jean/src/zig/src/print_air.zig:91:28: 0xaccb217 in writeBody__anon_93228 (zig) try w.writeInst(s, inst); ^ /home/jean/src/zig/src/print_air.zig:52:21: 0xa70f501 in write__anon_79824 (zig) writer.writeBody(stream, air.getMainBody()) catch return; ^ /home/jean/src/zig/src/print_air.zig:74:10: 0xa3eab39 in dump (zig) write(std.io.getStdErr().writer(), module, air, liveness); ^ /home/jean/src/zig/src/Module.zig:3186:38: 0xa15d915 in ensureFuncBodyAnalyzed (zig) @import("print_air.zig").dump(zcu, air, liveness); ^ /home/jean/src/zig/src/Compilation.zig:3419:42: 0xa15ae62 in processOneJob (zig) module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { ^ /home/jean/src/zig/src/Compilation.zig:3359:30: 0x9f89f9a in performAllTheWork (zig) try processOneJob(comp, work_item, main_progress_node); ^ /home/jean/src/zig/src/Compilation.zig:2132:31: 0x9f854d2 in update (zig) try comp.performAllTheWork(main_progress_node); ^ /home/jean/src/zig/src/main.zig:4483:24: 0x9fb6c2f in updateModule (zig) try comp.update(main_progress_node); ^ /home/jean/src/zig/src/main.zig:3405:17: 0xa01f554 in buildOutputType (zig) updateModule(comp, color) catch |err| switch (err) { ^ /home/jean/src/zig/src/main.zig:260:31: 0x9e67a31 in mainArgs (zig) return buildOutputType(gpa, arena, args, .{ .build = .Exe }); ^ /home/jean/src/zig/src/main.zig:206:20: 0x9e649c5 in main (zig) return mainArgs(gpa, arena, args); ^ /home/jean/src/zig/lib/std/start.zig:511:37: 0x9e6445e in main (zig) const result = root.main() catch |err| { ^ ../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7fa526586c4b in __libc_start_call_main (../sysdeps/x86/libc-start.c) ../csu/libc-start.c:360:3: 0x7fa526586d04 in __libc_start_main_impl (../sysdeps/x86/libc-start.c) ../sysdeps/x86_64/start.S:115:0: 0x4f6eb60 in _start (../sysdeps/x86_64/start.S) ???:?:?: 0x0 in ??? (???) ```

Expected Behavior

Program compiles, or an error is printed.

jean-dao commented 7 months ago

I got the first one trying to reduce this one, I suppose they are related.

// bug.zig
pub fn main() void {
    comptime var defs: [5]union(enum) { bar: []const u8, foo } = undefined;
    inline for (&defs) |*def| {
        def.* = .{ .bar = "foo" };
    }
}
debug zig build-exe bug.zig output ```sh $ ../zig/stage3/bin/zig build-exe bug.zig thread 24618 panic: reached unreachable code /home/jean/src/zig/src/codegen/llvm.zig:4281:60: 0xa1fb5b7 in lowerPtr (zig) .arr_elem, .comptime_field, .comptime_alloc => unreachable, ^ /home/jean/src/zig/src/codegen/llvm.zig:3798:35: 0x9f40730 in lowerValue (zig) .ptr => try o.lowerPtr(arg_val, 0), ^ /home/jean/src/zig/src/codegen/llvm.zig:4736:42: 0xa734b37 in resolveValue (zig) const llvm_val = try o.lowerValue(val.toIntern()); ^ /home/jean/src/zig/src/codegen/llvm.zig:4727:47: 0xa7348d1 in resolveInst (zig) const llvm_val = try self.resolveValue((try self.air.value(inst, mod)).?); ^ /home/jean/src/zig/src/codegen/llvm.zig:9353:47: 0xa790205 in airSetUnionTag (zig) const union_ptr = try self.resolveInst(bin_op.lhs); ^ /home/jean/src/zig/src/codegen/llvm.zig:4933:59: 0xa3e3a4d in genBody (zig) .set_union_tag => try self.airSetUnionTag(inst), ^ /home/jean/src/zig/src/codegen/llvm.zig:1709:19: 0xa3dc9c6 in updateFunc (zig) fg.genBody(air.getMainBody()) catch |err| switch (err) { ^ /home/jean/src/zig/src/link/Elf.zig:3029:70: 0xa720819 in updateFunc (zig) if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness); ^ /home/jean/src/zig/src/link.zig:420:82: 0xa3eb158 in updateFunc (zig) return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(module, func_index, air, liveness); ^ /home/jean/src/zig/src/Module.zig:3219:22: 0xa15dd37 in ensureFuncBodyAnalyzed (zig) lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) { ^ /home/jean/src/zig/src/Compilation.zig:3419:42: 0xa15ae62 in processOneJob (zig) module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { ^ /home/jean/src/zig/src/Compilation.zig:3359:30: 0x9f89f9a in performAllTheWork (zig) try processOneJob(comp, work_item, main_progress_node); ^ /home/jean/src/zig/src/Compilation.zig:2132:31: 0x9f854d2 in update (zig) try comp.performAllTheWork(main_progress_node); ^ /home/jean/src/zig/src/main.zig:4483:24: 0x9fb6c2f in updateModule (zig) try comp.update(main_progress_node); ^ /home/jean/src/zig/src/main.zig:3405:17: 0xa01f554 in buildOutputType (zig) updateModule(comp, color) catch |err| switch (err) { ^ /home/jean/src/zig/src/main.zig:260:31: 0x9e67a31 in mainArgs (zig) return buildOutputType(gpa, arena, args, .{ .build = .Exe }); ^ /home/jean/src/zig/src/main.zig:206:20: 0x9e649c5 in main (zig) return mainArgs(gpa, arena, args); ^ /home/jean/src/zig/lib/std/start.zig:511:37: 0x9e6445e in main (zig) const result = root.main() catch |err| { ^ ../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7f998a35bc4b in __libc_start_call_main (../sysdeps/x86/libc-start.c) ../csu/libc-start.c:360:3: 0x7f998a35bd04 in __libc_start_main_impl (../sysdeps/x86/libc-start.c) ../sysdeps/x86_64/start.S:115:0: 0x4f6eb60 in _start (../sysdeps/x86_64/start.S) ???:?:?: 0x0 in ??? (???) Aborted ```

AIR logs are similar, it crashes when trying to print the value.

jean-dao commented 6 months ago

Note: works fine if value assigned is explicitly marked comptime:

pub fn main() void {
    comptime var def: union(enum) { bar: []const u8, foo } = undefined;
    def = comptime .{ .bar = "bar" };
}