Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Compiler crash (SIGSEGV) with messed up @as() and @splat() #22321

Open
pfgithub opened this issue Dec 26, 2024 · 1 comment
Open

Compiler crash (SIGSEGV) with messed up @as() and @splat() #22321

pfgithub opened this issue Dec 26, 2024 · 1 comment
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@pfgithub
Copy link
Contributor

Zig Version

0.14.0-dev.2563+af5e73172

Steps to Reproduce and Observed Behavior

// a.zig
const std = @import("std");

pub fn main() !void {
    _ = @as(@Vector(2, f32){1.0, 1.0}, @splat(25.0));
}
$> zig build-exe a.zig
fish: Job 1, 'zig run src/main.zig' terminated by signal SIGSEGV (Address boundary error)
Exited with code [SIGSEGV]

Expected Behavior

An error message, like: expected type, found @Vector(2, f32).

Interestingly, when the crash is averted, the error shows up in the wrong place:

a.zig:4:40: error: expected type 'type', found '@Vector(2, f32)'
    _ = @as(@Vector(2, f32){1.0, 1.0}, 25.0);// @splat(25.0));
                                       ^~~~
@pfgithub pfgithub added the bug Observed behavior contradicts documented or intended behavior label Dec 26, 2024
@gabeuehlein
Copy link
Contributor

Stack trace of debug compiler:

Output:

thread 14647 panic: reached unreachable code
Analyzing a.zig
      %5 = ret_type() node_offset:3:1 to :3:7
      %6 = dbg_stmt(2, 5)
      %7 = block_comptime({
        %8 = int(2)
        %9 = vector_type(%8, @f32_type) node_offset:4:13 to :4:28
        %10 = validate_array_init_ty(%9, 2) node_offset:4:13 to :4:40
        %11 = array_init_elem_type(%9, 0)
        %12 = float(1)
        %13 = array_init_elem_type(%9, 1)
        %14 = float(1)
        %15 = array_init(%9{%12, %14}) node_offset:4:13 to :4:40
        %16 = break(%7, %15)
      }) node_offset:4:13 to :4:40
    > %17 = vec_arr_elem_type(%7) node_offset:4:42 to :4:54
      %18 = float(25)
      %19 = as_node(%17, %18) node_offset:4:49 to :4:53
      %20 = splat(%7, %19) node_offset:4:42 to :4:54
      %21 = as_node(%7, %20) node_offset:4:42 to :4:54
      %22 = ensure_result_non_error(%21) node_offset:4:9 to :4:55
      %23 = restore_err_ret_index_unconditional(.none) node_offset:3:1 to :3:7
      %24 = ret_implicit(@void_value) token_offset:5:1 to :5:1
    For full context, use the command
      zig ast-check -t a.zig

  in lib/std/start.zig
    > %2049 = is_non_err(%2048) 
  in lib/std/start.zig
    > %2051 = block({%2046..%2050}) 
  in lib/std/start.zig
    > %2013 = switch_block(%2009,
        else => {%2031..%2134},
        @void_type => {%2014..%2022},
        @noreturn_type, @u8_type => {%2023..%2030}) 
  in lib/std/start.zig
    > %1808 = call(.auto, %1806, []) 
  in lib/std/start.zig
    > %1631 = call(.auto, %1629, [
        {%1632},
        {%1633},
        {%1634},
      ]) 
  in lib/std/start.zig
    > %1628 = field_call(nodiscard .auto, %1626, "exit", [
        {%1629..%1635},
      ]) 

Unwind error at address `exe:0x24097c1` (error.AddressOutOfRange), trace may be incomplete

/home/gabeu/devel/zig/lib/std/debug.zig:405:14: 0x14a48c7 in assert (std.zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/gabeu/devel/zig/src/Sema.zig:2490:11: 0x2b0415c in errMsg__anon_361739 (main.zig)
    assert(src.offset != .unneeded);
          ^
/home/gabeu/devel/zig/src/Sema.zig:30542:36: 0x255e0c3 in coerceExtra (main.zig)
        const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
                                   ^
/home/gabeu/devel/zig/src/Sema.zig:29891:28: 0x1fac7c6 in coerce (main.zig)
    return sema.coerceExtra(block, dest_ty_unresolved, inst, inst_src, .{}) catch |err| switch (err) {
                           ^
/home/gabeu/devel/zig/src/Sema.zig:2066:41: 0x252b87c in analyzeAsType (main.zig)
    const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
                                        ^
/home/gabeu/devel/zig/src/Sema.zig:1927:38: 0x252bb78 in resolveType (main.zig)
    const ty = try sema.analyzeAsType(block, src, air_inst);
                                     ^
/home/gabeu/devel/zig/src/Sema.zig:8617:36: 0x32be4c8 in zirVecArrElemType (main.zig)
    const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
                                   ^
/home/gabeu/devel/zig/src/Sema.zig:1103:72: 0x2ad12ee in analyzeBodyInner (main.zig)
            .vec_arr_elem_type            => try sema.zirVecArrElemType(block, inst),
                                                                       ^
/home/gabeu/devel/zig/src/Sema.zig:947:26: 0x2a5fba9 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:2259:23: 0x2a635d8 in analyzeFnBody (main.zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:874:35: 0x24ef821 in ensureFuncBodyAnalyzedInner (main.zig)
    var air = try pt.analyzeFnBody(func_index);
                                  ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:776:81: 0x1f79e12 in ensureFuncBodyAnalyzed (main.zig)
    const ies_outdated, const analysis_fail = if (pt.ensureFuncBodyAnalyzedInner(func_index, func_outdated)) |result|
                                                                                ^
/home/gabeu/devel/zig/src/Sema.zig:36495:38: 0x2b075c9 in resolveInferredErrorSet (main.zig)
        try pt.ensureFuncBodyAnalyzed(func_index);
                                     ^
/home/gabeu/devel/zig/src/Sema.zig:33248:69: 0x33fa6c6 in analyzeIsNonErrComptimeOnly (main.zig)
                const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
                                                                    ^
/home/gabeu/devel/zig/src/Sema.zig:33277:56: 0x398c710 in analyzeIsNonErr (main.zig)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
/home/gabeu/devel/zig/src/Sema.zig:19744:32: 0x32cdbd5 in zirIsNonErr (main.zig)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
/home/gabeu/devel/zig/src/Sema.zig:1129:66: 0x2ad258f in analyzeBodyInner (main.zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/home/gabeu/devel/zig/src/Sema.zig:6166:34: 0x39c2962 in resolveBlockBody (main.zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/gabeu/devel/zig/src/Sema.zig:6143:33: 0x33efc8b in zirBlock (main.zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/gabeu/devel/zig/src/Sema.zig:1615:37: 0x2addf55 in analyzeBodyInner (main.zig)
            } else try sema.zirBlock(block, inst, false),
                                    ^
/home/gabeu/devel/zig/src/Sema.zig:6166:34: 0x39c2962 in resolveBlockBody (main.zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/gabeu/devel/zig/src/Sema.zig:11269:45: 0x39b31fe in resolveProngComptime (main.zig)
                return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);
                                            ^
/home/gabeu/devel/zig/src/Sema.zig:13770:36: 0x39c583a in resolveSwitchComptime (main.zig)
    return spa.resolveProngComptime(
                                   ^
/home/gabeu/devel/zig/src/Sema.zig:13595:34: 0x39b22a1 in resolveSwitchComptimeLoop (main.zig)
        if (resolveSwitchComptime(
                                 ^
/home/gabeu/devel/zig/src/Sema.zig:12799:49: 0x32ee1d3 in zirSwitchBlock (main.zig)
                return resolveSwitchComptimeLoop(
                                                ^
/home/gabeu/devel/zig/src/Sema.zig:1152:69: 0x2ad3611 in analyzeBodyInner (main.zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                    ^
/home/gabeu/devel/zig/src/Sema.zig:947:26: 0x2a5fba9 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/gabeu/devel/zig/src/Sema.zig:7963:31: 0x3419a70 in analyzeCall (main.zig)
            sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                              ^
/home/gabeu/devel/zig/src/Sema.zig:7139:43: 0x32b4dd7 in zirCall__anon_459523 (main.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/gabeu/devel/zig/src/Sema.zig:1085:62: 0x2ad051a in analyzeBodyInner (main.zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/gabeu/devel/zig/src/Sema.zig:947:26: 0x2a5fba9 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/gabeu/devel/zig/src/Sema.zig:7963:31: 0x3419a70 in analyzeCall (main.zig)
            sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
                              ^
/home/gabeu/devel/zig/src/Sema.zig:7139:43: 0x32b4dd7 in zirCall__anon_459523 (main.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/gabeu/devel/zig/src/Sema.zig:1085:62: 0x2ad051a in analyzeBodyInner (main.zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/gabeu/devel/zig/src/Sema.zig:965:30: 0x2537876 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/gabeu/devel/zig/src/Sema.zig:998:39: 0x1fa9f9c in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/gabeu/devel/zig/src/Sema.zig:7431:65: 0x3a889bf in analyzeArg (main.zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/gabeu/devel/zig/src/Sema.zig:8016:49: 0x341b14b in analyzeCall (main.zig)
            arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);
                                                ^
/home/gabeu/devel/zig/src/Sema.zig:7139:43: 0x32b6ac6 in zirCall__anon_459525 (main.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/gabeu/devel/zig/src/Sema.zig:1086:62: 0x2ad05d1 in analyzeBodyInner (main.zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/gabeu/devel/zig/src/Sema.zig:947:26: 0x2a5fba9 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:2259:23: 0x2a635d8 in analyzeFnBody (main.zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:874:35: 0x24ef821 in ensureFuncBodyAnalyzedInner (main.zig)
    var air = try pt.analyzeFnBody(func_index);
                                  ^
/home/gabeu/devel/zig/src/Zcu/PerThread.zig:776:81: 0x1f79e12 in ensureFuncBodyAnalyzed (main.zig)
    const ies_outdated, const analysis_fail = if (pt.ensureFuncBodyAnalyzedInner(func_index, func_outdated)) |result|
                                                                                ^
/home/gabeu/devel/zig/src/Compilation.zig:3691:38: 0x1b06aad in processOneJob (main.zig)
            pt.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                     ^
/home/gabeu/devel/zig/src/Compilation.zig:3637:30: 0x1848198 in performAllTheWorkInner (main.zig)
            try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job, main_progress_node);
                             ^
/home/gabeu/devel/zig/src/Compilation.zig:3496:36: 0x1653ad2 in performAllTheWork (main.zig)
    try comp.performAllTheWorkInner(main_progress_node);
                                   ^
/home/gabeu/devel/zig/src/Compilation.zig:2252:31: 0x1516d38 in update (main.zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/gabeu/devel/zig/src/main.zig:4453:20: 0x154870c in updateModule (main.zig)
    try comp.update(prog_node);
                   ^
/home/gabeu/devel/zig/src/main.zig:3643:21: 0x1577547 in buildOutputType (main.zig)
        updateModule(comp, color, root_prog_node) catch |err| switch (err) {
                    ^
/home/gabeu/devel/zig/src/main.zig:270:31: 0x15bd2f4 in mainArgs (main.zig)
        return buildOutputType(gpa, arena, args, .{ .build = .Obj });
                              ^
/home/gabeu/devel/zig/src/main.zig:205:20: 0x14a39de in main (main.zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/gabeu/devel/zig/lib/std/start.zig:656:37: 0x14a15a9 in posixCallMainAndExit (std.zig)
            const result = root.main() catch |err| {
                                    ^
/home/gabeu/devel/zig/lib/std/start.zig:271:5: 0x14a1016 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^

Fixing the crash seems easy enough:

--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -8614,7 +8614,8 @@ fn zirVecArrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
     const pt = sema.pt;
     const zcu = pt.zcu;
     const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
-    const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
+    const src = block.nodeOffset(un_node.src_node);
+    const vec_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) {
         // Since this is a ZIR instruction that returns a type, encountering
         // generic poison should not result in a failed compilation, but the
         // generic poison type. This prevents unnecessary failures when

But this will result in the error pointing to the operand of the @as instead of the type to coerce the operand into. It looks like making the error point to the correct source location will need more work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants