Skip to content
New issue

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

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

Already on GitHub? # to your account

Segmentation fault compiling inline call with comptime return value (-fstrip) #15469

Closed
amp-59 opened this issue Apr 26, 2023 · 2 comments · Fixed by #17972
Closed

Segmentation fault compiling inline call with comptime return value (-fstrip) #15469

amp-59 opened this issue Apr 26, 2023 · 2 comments · Fixed by #17972
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@amp-59
Copy link
Contributor

amp-59 commented Apr 26, 2023

Zig Version

0.11.0-dev.2685+fac120bc3

Steps to Reproduce and Observed Behavior

Compile test program with zig build-obj -fstrip ./inline_call_comptime_value_stripped.zig
./inline_call_comptime_value_stripped.zig:

fn Func(comptime Type: type) type {
    return struct { value: Type };
}
inline fn func(value: anytype) Func(@TypeOf(value)) {
    return .{ .value = value };
}
export fn entry() void {
    _ = func(type);
}

Expected Behavior

@amp-59 amp-59 added the bug Observed behavior contradicts documented or intended behavior label Apr 26, 2023
@nektro
Copy link
Contributor

nektro commented Apr 26, 2023

thread 218593 panic: integer overflow
Analyzing /run/media/meghan/dev/test.zig: test.zig:func
      %33 = dbg_block_begin()
      %34 = dbg_stmt(2, 5)
      %35 = ret_ptr()
      %36 = field_base_ptr(%35)
      %37 = field_ptr_init(%36, "value")
      %38 = store_node(%37, %24)
    > %39 = validate_struct_init({
        %37 = field_ptr_init(%36, "value")
      })
      %40 = restore_err_ret_index(@Zir.Inst.Ref.none, @Zir.Inst.Ref.none)
      %41 = dbg_stmt(2, 5)
      %42 = ret_load(%35)
      %43 = dbg_block_end()
      %44 = restore_err_ret_index(%32, @Zir.Inst.Ref.none)
      %45 = break(%32, @Zir.Inst.Ref.void_value)
    For full context, use the command
      zig ast-check -t /run/media/meghan/dev/test.zig

  in /run/media/meghan/dev/test.zig: test.zig:func
    > %32 = block({%33..%45})
  in /run/media/meghan/dev/test.zig: test.zig:_start
    > %56 = call(.auto, %54, [
        {%57},
      ])
  in /run/media/meghan/dev/test.zig: test.zig:_start
    > %51 = block({%52..%71})

/home/meghan/src/zig/src/Sema.zig:4428:60: 0x184939b in validateStructInit (zig)
            var block_index = block.instructions.items.len - 1;
                                                           ^
/home/meghan/src/zig/src/Sema.zig:4129:50: 0x1293a64 in zirValidateStructInit (zig)
        .Struct => return sema.validateStructInit(
                                                 ^
/home/meghan/src/zig/src/Sema.zig:1295:47: 0xf36469 in analyzeBodyInner (zig)
                try sema.zirValidateStructInit(block, inst);
                                              ^
/home/meghan/src/zig/src/Sema.zig:5446:34: 0x17f4ff9 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/meghan/src/zig/src/Sema.zig:5429:85: 0x12a495c in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/home/meghan/src/zig/src/Sema.zig:1459:67: 0xf3cafe in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                                  ^
/home/meghan/src/zig/src/Sema.zig:805:30: 0x1182b18 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/meghan/src/zig/src/Sema.zig:6847:55: 0x17b94ff in analyzeCall (zig)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                                      ^
/home/meghan/src/zig/src/Sema.zig:6362:32: 0x11dc0c8 in zirCall (zig)
        return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
                               ^
/home/meghan/src/zig/src/Sema.zig:924:62: 0xf28907 in analyzeBodyInner (zig)
            .call                         => try sema.zirCall(block, inst),
                                                             ^
/home/meghan/src/zig/src/Sema.zig:5446:34: 0x17f4ff9 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/meghan/src/zig/src/Sema.zig:5429:85: 0x12a495c in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                                                                    ^
/home/meghan/src/zig/src/Sema.zig:1459:67: 0xf3cafe in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                                  ^
/home/meghan/src/zig/src/Sema.zig:805:30: 0x1182b18 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/meghan/src/zig/src/Module.zig:5618:43: 0xf0eb6c in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                                          ^
/home/meghan/src/zig/src/Module.zig:4275:40: 0xd04001 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/home/meghan/src/zig/src/Compilation.zig:3127:42: 0xd020f3 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/meghan/src/zig/src/Compilation.zig:3064:30: 0xbb8efe in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/meghan/src/zig/src/Compilation.zig:2020:31: 0xbb566d in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/meghan/src/zig/src/main.zig:3820:24: 0xbe2c4a in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/meghan/src/zig/src/main.zig:3255:17: 0xa691fe in buildOutputType (zig)
    updateModule(comp) catch |err| switch (err) {
                ^
/home/meghan/src/zig/src/main.zig:269:31: 0xa3c932 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .{ .build = .Lib });
                              ^
/home/meghan/src/zig/src/main.zig:211:20: 0xa3beb5 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/meghan/src/zig/lib/std/start.zig:609:37: 0xa3e538 in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7fa05d35324d in ??? (???)
???:?:?: 0x7ffd2a1615a1 in ??? (???)
???:?:?: 0x6372732f6e616866 in ??? (???)

@Vexu Vexu added this to the 0.12.0 milestone Apr 26, 2023
@ianprime0509
Copy link
Contributor

This doesn't seem to be limited to inline calls, and also applies to tuple initialization. Here are two further related examples, with the debug output from zig test -fstrip $file included:

test {
    const S = struct { field: u32 };
    comptime var arr: [1]S = undefined;
    arr[0] = .{ .field = 0 };
}
thread 18819 panic: integer overflow
Analyzing test2.zig: test2.zig:test_0
      %3 = dbg_block_begin()
      %4 = dbg_stmt(2, 5)
      %5 = extended(struct_decl(known_non_opv, dbg_var, Auto, {}, {
        field: @InternPool.Index.u32_type,
      }) node_offset:2:15 to :2:36
      %6 = dbg_var_val(%5, "S")
      %7 = dbg_stmt(3, 5)
      %8 = block_comptime({
        %9 = array_type(@InternPool.Index.one, %5) node_offset:3:23 to :3:27
        %10 = break(%8, %9)
      }) node_offset:3:23 to :3:27
      %11 = alloc_comptime_mut(%8) node_offset:3:5 to :3:39
      %12 = store_node(%11, @InternPool.Index.undef) node_offset:3:30 to :3:39
      %13 = dbg_var_ptr(%11, "arr")
      %14 = dbg_stmt(4, 5)
      %15 = as_node(@InternPool.Index.usize_type, @InternPool.Index.zero) node_offset:4:9 to :4:10
      %16 = dbg_stmt(4, 8)
      %17 = elem_ptr_node(%11, %15) node_offset:4:5 to :4:11
      %18 = field_base_ptr(%17) node_offset:4:14 to :4:29
      %19 = field_ptr_init(%18, "field") node_offset:4:26 to :4:27
      %20 = store_node(%19, @InternPool.Index.zero) node_offset:4:26 to :4:27
    > %21 = validate_struct_init({
        %19 = field_ptr_init(%18, "field") node_offset:4:26 to :4:27
      }) node_offset:4:14 to :4:29
      %22 = dbg_block_end()
      %23 = restore_err_ret_index(%2, %4294967211)
      %24 = break(%2, @InternPool.Index.void_value)
    For full context, use the command
      zig ast-check -t test2.zig

  in test2.zig: test2.zig:test_0
    > %2 = block({%3..%24}) node_offset:1:6 to :1:7

/home/ian/src/zig/src/Sema.zig:4704:60: 0x661ac58 in validateStructInit (zig)
            var block_index = block.instructions.items.len - 1;
                                                           ^
/home/ian/src/zig/src/Sema.zig:4395:50: 0x6065d76 in zirValidateStructInit (zig)
        .Struct => return sema.validateStructInit(
                                                 ^
/home/ian/src/zig/src/Sema.zig:1371:47: 0x5cebc85 in analyzeBodyInner (zig)
                try sema.zirValidateStructInit(block, inst);
                                              ^
/home/ian/src/zig/src/Sema.zig:5727:34: 0x662929b in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/ian/src/zig/src/Sema.zig:5710:33: 0x607a153 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/ian/src/zig/src/Sema.zig:1545:49: 0x5cf169f in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/ian/src/zig/src/Sema.zig:883:30: 0x5f383c8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/ian/src/zig/src/Module.zig:5326:21: 0x5cbf143 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/ian/src/zig/src/Module.zig:3922:40: 0x5aad936 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                       ^
/home/ian/src/zig/src/Compilation.zig:3207:42: 0x5aab9f0 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/ian/src/zig/src/Compilation.zig:3144:30: 0x591a9dd in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/ian/src/zig/src/Compilation.zig:2067:31: 0x59164c1 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/ian/src/zig/src/main.zig:3864:24: 0x5944f60 in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/ian/src/zig/src/main.zig:3285:17: 0x5973fc5 in buildOutputType (zig)
    updateModule(comp) catch |err| switch (err) {
                ^
/home/ian/src/zig/src/main.zig:275:31: 0x57d8877 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/ian/src/zig/src/main.zig:213:20: 0x57d5975 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/ian/src/zig/lib/std/start.zig:588:37: 0x57d535e in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7fcaed6a084f in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7fcaed6a084f` was not available, trace may be incomplete

Aborted (core dumped)
Debug output
test {
    const S = struct { u32 };
    comptime var arr: [1]S = undefined;
    arr[0] = .{0};
}
thread 18995 panic: integer overflow
Analyzing test3.zig: test3.zig:test_0
      %3 = dbg_block_begin()
      %4 = dbg_stmt(2, 5)
      %5 = extended(struct_decl(known_non_opv, tuple, dbg_var, Auto, {}, {
        @"0": @InternPool.Index.u32_type,
      }) 
      %6 = dbg_var_val(%5, "S")
      %7 = dbg_stmt(3, 5)
      %8 = block_comptime({
        %9 = array_type(@InternPool.Index.one, %5) 
        %10 = break(%8, %9)
      }) 
      %11 = alloc_comptime_mut(%8) 
      %12 = store_node(%11, @InternPool.Index.undef) 
      %13 = dbg_var_ptr(%11, "arr")
      %14 = dbg_stmt(4, 5)
      %15 = as_node(@InternPool.Index.usize_type, @InternPool.Index.zero) 
      %16 = dbg_stmt(4, 8)
      %17 = elem_ptr_node(%11, %15) 
      %18 = array_base_ptr(%17) 
      %19 = elem_ptr_imm(%18, 0) 
      %20 = store_node(%19, @InternPool.Index.zero) 
    > %21 = validate_array_init({
        %19 = elem_ptr_imm(%18, 0) 
      }) 
      %22 = dbg_block_end()
      %23 = restore_err_ret_index(%2, %4294967211)
      %24 = break(%2, @InternPool.Index.void_value)
    For full context, use the command
      zig ast-check -t test3.zig

  in test3.zig: test3.zig:test_0
    > %2 = block({%3..%24}) 

/home/ian/src/zig/src/Sema.zig:4941:56: 0x6067240 in zirValidateArrayInit (zig)
        var block_index = block.instructions.items.len - 1;
                                                       ^
/home/ian/src/zig/src/Sema.zig:1376:46: 0x5cebd6c in analyzeBodyInner (zig)
                try sema.zirValidateArrayInit(block, inst);
                                             ^
/home/ian/src/zig/src/Sema.zig:5727:34: 0x662929b in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/ian/src/zig/src/Sema.zig:5710:33: 0x607a153 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/ian/src/zig/src/Sema.zig:1545:49: 0x5cf169f in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/ian/src/zig/src/Sema.zig:883:30: 0x5f383c8 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/ian/src/zig/src/Module.zig:5326:21: 0x5cbf143 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/ian/src/zig/src/Module.zig:3922:40: 0x5aad936 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                       ^
/home/ian/src/zig/src/Compilation.zig:3207:42: 0x5aab9f0 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/ian/src/zig/src/Compilation.zig:3144:30: 0x591a9dd in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/ian/src/zig/src/Compilation.zig:2067:31: 0x59164c1 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/ian/src/zig/src/main.zig:3864:24: 0x5944f60 in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/home/ian/src/zig/src/main.zig:3285:17: 0x5973fc5 in buildOutputType (zig)
    updateModule(comp) catch |err| switch (err) {
                ^
/home/ian/src/zig/src/main.zig:275:31: 0x57d8877 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .zig_test);
                              ^
/home/ian/src/zig/src/main.zig:213:20: 0x57d5975 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/ian/src/zig/lib/std/start.zig:588:37: 0x57d535e in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7f41ea48384f in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7f41ea48384f` was not available, trace may be incomplete

Aborted (core dumped)
Debug output

The crashes here are in two different functions, but the failing logic is the same: block.instructions.items.len - 1 when the len is 0.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants