zig icon indicating copy to clipboard operation
zig copied to clipboard

Segfault with comptime functions

Open tiawl opened this issue 1 year ago • 3 comments

Zig Version

0.12.0-dev.1830+779b8e259

Steps to Reproduce and Observed Behavior

The file:

const std = @import ("std");

const e = enum (u9)
{
  // From my understanding those 2 lines are the same but the second one does not work:
  // const U: u9 = 255;
  const U: @typeInfo (@This ()).Enum.tag_type = std.math.maxInt (@Type (.{ .Int = .{ .signedness = .unsigned, .bits = @typeInfo (@typeInfo (@This ()).Enum.tag_type).Int.bits - 1 }}));

  a = U + 1,
};

test "test"
{
  std.debug.print ("{}\n", .{ @intFromEnum (e.a) });
}

The output:

$ zig test test.zig
Segmentation fault (core dumped)

Expected Behavior

$ zig test test.zig
Test [1/1] test.test... 256
All 1 tests passed.

Am I missing something ? Thank you.

tiawl avatar Dec 22 '23 14:12 tiawl

Crashing instead of producing an error is a compiler bug, but note that @typeInfo(@This()) contains the values of all of the enum tags, which requires resolving the value of U first, which requires resolving the value of @typeInfo(@This()) before that, so it's not clear how this would be implemented otherwise.

jacobly0 avatar Dec 22 '23 15:12 jacobly0

Putting the U declaration outside the enum and changing @typeInfo(@This()) into @typeInfo(e) triggers an error: dependency loop detected. So that is right, the "Expected Behavior" section in my first message should contain this error message.

tiawl avatar Dec 22 '23 18:12 tiawl

debug trace on 0.12.0-dev.1839+461f9c283:

thread 916074 panic: reached unreachable code
Analyzing empty.zig: empty.zig:e.U
      %9 = extended(this()) 
    > %10 = type_info(%9) 
      %11 = field_val(%10, "Enum") 
      %12 = field_val(%11, "tag_type") 
      %13 = as_node(@type_type, %12) 
      %14 = decl_ref("std") 
      %15 = field_ptr(%14, "math") 
      %16 = dbg_stmt(1, 64)
      %17 = field_call(.compile_time, %15, "maxInt", [
        {
          %18 = validate_struct_init_result_ty(@type_info_type) 
          %19 = struct_init_field_type(@type_info_type, Int) 
          %20 = validate_struct_init_result_ty(%19) 
          %21 = struct_init_field_type(%19, signedness) 
          %22 = enum_literal("unsigned") 
          %23 = struct_init_field_type(%19, bits) 
          %24 = extended(this()) 
          %25 = type_info(%24) 
          %26 = field_val(%25, "Enum") 
          %27 = field_val(%26, "tag_type") 
          %28 = type_info(%27) 
          %29 = field_val(%28, "Int") 
          %30 = field_val(%29, "bits") 
          %31 = sub(%30, @one) 
          %32 = struct_init([%21, %22], [%23, %31]) 
          %33 = struct_init([%19, %32]) 
          %34 = extended(reify(%33)) 
          %35 = break_inline(%17, %34)
        },
      ]) 
      %36 = as_node(%13, %17) 
      %37 = break_inline(%8, %36)
    For full context, use the command
      zig ast-check -t empty.zig

  in empty.zig: empty.zig:e
    > %38 = decl_val("U") 
  in empty.zig: empty.zig:e
    > %5 = extended(enum_decl(parent, {
        [95] U line(3) hash(85c87214a7ed3acf0990f64ed2321976): %8 = ...
      }, %7, {%6..%41}, {
        a = %40,
      }) 
  in empty.zig: empty.zig:test.test
    > %57 = decl_val("e") 
  in empty.zig: empty.zig:test.test
    > %52 = field_call(nodiscard .auto, %49, "print", [
        {%53, %54},
        {%55..%62},
      ]) 
  in empty.zig: empty.zig:test.test
    > %44 = block({%45..%65}) 

/home/dr/zig/lib/std/debug.zig:342:14: 0x610760c in assert (zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/dr/zig/src/InternPool.zig:3715:11: 0x6180dbd in indexToKey (zig)
    assert(index != .none);
          ^
/home/dr/zig/src/Sema.zig:17359:51: 0x6b278b6 in zirTypeInfo (zig)
                        mod.intern_pool.indexToKey(enum_type.values.get(ip)[i]).int,
                                                  ^
/home/dr/zig/src/Sema.zig:1096:66: 0x678824c in analyzeBodyInner (zig)
            .type_info                    => try sema.zirTypeInfo(block, inst),
                                                                 ^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/home/dr/zig/src/Module.zig:3681:50: 0x64fb4ac in semaDecl (zig)
    const result_ref = (try sema.analyzeBodyBreak(&block_scope, @ptrCast(body))).?.operand;
                                                 ^
/home/dr/zig/src/Module.zig:3255:32: 0x62655fd in ensureDeclAnalyzed (zig)
        break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
                               ^
/home/dr/zig/src/Sema.zig:31666:27: 0x70e8f39 in ensureDeclAnalyzed (zig)
    mod.ensureDeclAnalyzed(decl_index) catch |err| {
                          ^
/home/dr/zig/src/Sema.zig:31711:32: 0x71814ca in analyzeDeclRefInner (zig)
    try sema.ensureDeclAnalyzed(decl_index);
                               ^
/home/dr/zig/src/Sema.zig:31626:50: 0x70acf35 in analyzeDeclVal (zig)
    const decl_ref = try sema.analyzeDeclRefInner(decl_index, false);
                                                 ^
/home/dr/zig/src/Sema.zig:6380:31: 0x6af78ed in zirDeclVal (zig)
    return sema.analyzeDeclVal(block, src, decl);
                              ^
/home/dr/zig/src/Sema.zig:1038:65: 0x678579c in analyzeBodyInner (zig)
            .decl_val                     => try sema.zirDeclVal(block, inst),
                                                                ^
/home/dr/zig/src/Sema.zig:916:30: 0x6a85cf8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/dr/zig/src/Sema.zig:3005:33: 0x6b76274 in zirEnumDecl (zig)
            try sema.analyzeBody(&enum_block, body);
                                ^
/home/dr/zig/src/Sema.zig:1227:64: 0x678d271 in analyzeBodyInner (zig)
                    .enum_decl          => try sema.zirEnumDecl(          block, extended, inst),
                                                               ^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/home/dr/zig/src/Module.zig:3681:50: 0x64fb4ac in semaDecl (zig)
    const result_ref = (try sema.analyzeBodyBreak(&block_scope, @ptrCast(body))).?.operand;
                                                 ^
/home/dr/zig/src/Module.zig:3255:32: 0x62655fd in ensureDeclAnalyzed (zig)
        break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
                               ^
/home/dr/zig/src/Sema.zig:31666:27: 0x70e8f39 in ensureDeclAnalyzed (zig)
    mod.ensureDeclAnalyzed(decl_index) catch |err| {
                          ^
/home/dr/zig/src/Sema.zig:31711:32: 0x71814ca in analyzeDeclRefInner (zig)
    try sema.ensureDeclAnalyzed(decl_index);
                               ^
/home/dr/zig/src/Sema.zig:31626:50: 0x70acf35 in analyzeDeclVal (zig)
    const decl_ref = try sema.analyzeDeclRefInner(decl_index, false);
                                                 ^
/home/dr/zig/src/Sema.zig:6380:31: 0x6af78ed in zirDeclVal (zig)
    return sema.analyzeDeclVal(block, src, decl);
                              ^
/home/dr/zig/src/Sema.zig:1038:65: 0x678579c in analyzeBodyInner (zig)
            .decl_val                     => try sema.zirDeclVal(block, inst),
                                                                ^
/home/dr/zig/src/Sema.zig:933:45: 0x64fdf64 in analyzeBodyBreak (zig)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
/home/dr/zig/src/Sema.zig:882:50: 0x70a8a53 in resolveBody (zig)
    const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                                 ^
/home/dr/zig/src/Sema.zig:6981:59: 0x75d7c65 in analyzeArg (zig)
                const uncoerced_arg = try sema.resolveBody(block, arg_body, zir_call.call_inst);
                                                          ^
/home/dr/zig/src/Sema.zig:7904:49: 0x75daa59 in instantiateGenericCall (zig)
        const arg_ref = try args_info.analyzeArg(sema, block, arg_index, param_ty, generic_owner_ty_info, func);
                                                ^
/home/dr/zig/src/Sema.zig:7212:40: 0x70af7e8 in analyzeCall (zig)
        if (sema.instantiateGenericCall(
                                       ^
/home/dr/zig/src/Sema.zig:6692:43: 0x6af42c0 in zirCall__anon_95837 (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/dr/zig/src/Sema.zig:1029:62: 0x6785083 in analyzeBodyInner (zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/dr/zig/src/Sema.zig:5853:34: 0x7166ee7 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/dr/zig/src/Sema.zig:5836:33: 0x6bb79af in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/dr/zig/src/Sema.zig:1577:49: 0x6795897 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                                ^
/home/dr/zig/src/Sema.zig:916:30: 0x6a85cf8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/dr/zig/src/Module.zig:4616:21: 0x6761480 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/dr/zig/src/Module.zig:3324:40: 0x64e147d in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                       ^
/home/dr/zig/src/Compilation.zig:3761:42: 0x64df84d in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/dr/zig/src/Compilation.zig:3698:30: 0x62b1738 in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/dr/zig/src/Compilation.zig:2505:31: 0x62acf92 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/dr/zig/src/main.zig:4283:24: 0x62dd6a2 in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/dr/zig/src/main.zig:3684:17: 0x6300262 in buildOutputType (zig)
    updateModule(comp) catch |err| switch (err) {
                ^
/home/dr/zig/src/main.zig:284:31: 0x6109ad7 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/dr/zig/src/main.zig:222:20: 0x6106ad5 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/dr/zig/lib/std/start.zig:585:37: 0x6106556 in main (zig)
            const result = root.main() catch |err| {
                                    ^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7f318cf5f0cf in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:360:3: 0x7f318cf5f188 in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x61061a4 in ??? (???)
???:?:?: 0x0 in ??? (???)

Rexicon226 avatar Dec 22 '23 22:12 Rexicon226