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

switch on error doesn't validate operand type #18592

Closed
Techatrix opened this issue Jan 16, 2024 · 1 comment · Fixed by #18593
Closed

switch on error doesn't validate operand type #18592

Techatrix opened this issue Jan 16, 2024 · 1 comment · Fixed by #18593
Labels
bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness. regression It worked in a previous version of Zig, but stopped working.
Milestone

Comments

@Techatrix
Copy link
Contributor

Zig Version

0.12.0-dev.2255+50457482b

Steps to Reproduce and Observed Behavior

Run the following code with zig run file.zig:

pub fn main() !void {
    false catch |err| switch (err) {
        else => {},
    };
}

This produces the following crash:

Click Me
thread 430912 panic: access of union field 'error_union_type' while field 'simple_type' is active
Analyzing sample2.zig: sample2.zig:main
    %3 = dbg_block_begin()
    %4 = dbg_stmt(2, 5)
    %5 = dbg_stmt(2, 5)
  > %6 = switch_block_err_union(@bool_false,
      non_err => {
        %7 = dbg_block_begin()
        %8 = err_union_payload_unsafe(@bool_false) node_offset:2:5 to :2:16
        %9 = dbg_block_end()
        %10 = break(%6, %8)
      },
      else => {
        %12 = dbg_block_begin()
        %13 = block({
          %14 = restore_err_ret_index(%13.none)
          %15 = break(%13, @void_value)
        }) node_offset:3:17 to :3:19
        %16 = dbg_block_end()
        %17 = break(%6, @void_value)
      }) node_offset:2:23 to :2:29
    %18 = ensure_result_used(%6) node_offset:2:5 to :2:16
    %19 = dbg_block_end()
    %20 = restore_err_ret_index(%2.none)
    %21 = break(%2, @void_value)
  For full context, use the command
    zig ast-check -t sample2.zig

in sample2.zig: sample2.zig:main
  > %2 = block({%3..%21}) node_offset:1:21 to :1:21
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMain
  > %2851 = is_non_err(%2850) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMain
  > %2853 = block({%2847..%2852}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMain
  > %2844 = block({%2845..%2991}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMain
  > %2755 = switch_block(%2753,
      else => {%2994..%3000},
      %2756 => {%2757..%2769},
      %2770 => {%2771..%2789},
      by_val %2790 => {%2791..%2841},
      %2842 => {%2843..%2993}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMain
  > %2739 = block({%2740..%3004}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:initEventLoopAndCallMain
  > %2462 = builtin_call(%2460, %2461, @empty_struct) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:initEventLoopAndCallMain
  > %2307 = block({%2308..%2469}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMainWithArgs
  > %2084 = call(.auto, %2082, []) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:callMainWithArgs
  > %2047 = block({%2048..%2091}) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
  > %1873 = builtin_call(%1870, %1871, %1872) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
  > %1869 = field_call(nodiscard .auto, %1866, "exit", [
      {%1870..%1874},
    ]) 
in /home/techatrix/repos/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
  > %1478 = block({%1479..%1877}) 

/home/techatrix/repos/zig/src/InternPool.zig:7216:29: 0x1edfec2 in errorUnionSet (zig)
  return ip.indexToKey(ty).error_union_type.error_set_type;
                          ^
/home/techatrix/repos/zig/src/type.zig:1959:63: 0x1bcaa2b in errorUnionSet (zig)
      return Type.fromInterned(mod.intern_pool.errorUnionSet(ty.toIntern()));
                                                            ^
/home/techatrix/repos/zig/src/Sema.zig:11261:33: 0x220a072 in zirSwitchBlockErrUnion (zig)
      operand_ty.errorUnionSet(mod);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1100:77: 0x1e0364b in analyzeBodyInner (zig)
          .switch_block_err_union       => try sema.zirSwitchBlockErrUnion(block, inst),
                                                                          ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:921:30: 0x2106108 in analyzeBody (zig)
  _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                           ^
/home/techatrix/repos/zig/src/Module.zig:4575:21: 0x1ddee6c in analyzeFnBody (zig)
  sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                  ^
/home/techatrix/repos/zig/src/Module.zig:3272:40: 0x1b30ae4 in ensureFuncBodyAnalyzed (zig)
          var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                     ^
/home/techatrix/repos/zig/src/Sema.zig:32162:31: 0x2813c6d in ensureFuncBodyAnalyzed (zig)
  mod.ensureFuncBodyAnalyzed(func) catch |err| {
                            ^
/home/techatrix/repos/zig/src/Sema.zig:36109:40: 0x22cf29b in resolveInferredErrorSet (zig)
      try sema.ensureFuncBodyAnalyzed(func_index);
                                     ^
/home/techatrix/repos/zig/src/Sema.zig:32491:69: 0x22a10b6 in analyzeIsNonErrComptimeOnly (zig)
              const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
                                                                  ^
/home/techatrix/repos/zig/src/Sema.zig:32520:56: 0x2744059 in analyzeIsNonErr (zig)
  const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                     ^
/home/techatrix/repos/zig/src/Sema.zig:18755:32: 0x21f8e4e in zirIsNonErr (zig)
  return sema.analyzeIsNonErr(block, src, operand);
                             ^
/home/techatrix/repos/zig/src/Sema.zig:1075:66: 0x1e023d8 in analyzeBodyInner (zig)
          .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                               ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:10622:45: 0x2764550 in resolveProngComptime (zig)
              return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);
                                          ^
/home/techatrix/repos/zig/src/Sema.zig:12768:48: 0x2762ddf in resolveSwitchComptime (zig)
              return spa.resolveProngComptime(
                                             ^
/home/techatrix/repos/zig/src/Sema.zig:12009:37: 0x220846f in zirSwitchBlock (zig)
      return resolveSwitchComptime(
                                  ^
/home/techatrix/repos/zig/src/Sema.zig:1098:69: 0x1e034cd in analyzeBodyInner (zig)
          .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                  ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:921:30: 0x2106108 in analyzeBody (zig)
  _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                           ^
/home/techatrix/repos/zig/src/Sema.zig:7515:33: 0x2730012 in analyzeCall (zig)
              sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                              ^
/home/techatrix/repos/zig/src/Sema.zig:24369:28: 0x223e719 in zirBuiltinCall (zig)
  return sema.analyzeCall(
                         ^
/home/techatrix/repos/zig/src/Sema.zig:1151:69: 0x1e05be0 in analyzeBodyInner (zig)
          .builtin_call                 => try sema.zirBuiltinCall(block, inst),
                                                                  ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:921:30: 0x2106108 in analyzeBody (zig)
  _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                           ^
/home/techatrix/repos/zig/src/Sema.zig:7515:33: 0x2730012 in analyzeCall (zig)
              sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                              ^
/home/techatrix/repos/zig/src/Sema.zig:6725:43: 0x21e9d9c in zirCall__anon_98476 (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/techatrix/repos/zig/src/Sema.zig:1032:62: 0x1e003c6 in analyzeBodyInner (zig)
          .call                         => try sema.zirCall(block, inst, .direct),
                                                           ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:921:30: 0x2106108 in analyzeBody (zig)
  _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                           ^
/home/techatrix/repos/zig/src/Sema.zig:7515:33: 0x2730012 in analyzeCall (zig)
              sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                              ^
/home/techatrix/repos/zig/src/Sema.zig:24369:28: 0x223e719 in zirBuiltinCall (zig)
  return sema.analyzeCall(
                         ^
/home/techatrix/repos/zig/src/Sema.zig:1151:69: 0x1e05be0 in analyzeBodyInner (zig)
          .builtin_call                 => try sema.zirBuiltinCall(block, inst),
                                                                  ^
/home/techatrix/repos/zig/src/Sema.zig:938:45: 0x1b51cca in analyzeBodyBreak (zig)
  const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                          ^
/home/techatrix/repos/zig/src/Sema.zig:887:50: 0x2726703 in resolveBody (zig)
  const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                               ^
/home/techatrix/repos/zig/src/Sema.zig:7014:59: 0x2c78265 in analyzeArg (zig)
              const uncoerced_arg = try sema.resolveBody(block, arg_body, zir_call.call_inst);
                                                        ^
/home/techatrix/repos/zig/src/Sema.zig:7579:49: 0x2731073 in analyzeCall (zig)
          arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:6725:43: 0x21eaf1e in zirCall__anon_98477 (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/techatrix/repos/zig/src/Sema.zig:1033:62: 0x1e00482 in analyzeBodyInner (zig)
          .field_call                   => try sema.zirCall(block, inst, .field),
                                                           ^
/home/techatrix/repos/zig/src/Sema.zig:5887:34: 0x276da2d in resolveBlockBody (zig)
      if (sema.analyzeBodyInner(child_block, body)) |_| {
                               ^
/home/techatrix/repos/zig/src/Sema.zig:5870:33: 0x22a48ef in zirBlock (zig)
  return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                              ^
/home/techatrix/repos/zig/src/Sema.zig:1582:49: 0x1e10ce2 in analyzeBodyInner (zig)
                  break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
                                              ^
/home/techatrix/repos/zig/src/Sema.zig:921:30: 0x2106108 in analyzeBody (zig)
  _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                           ^
/home/techatrix/repos/zig/src/Module.zig:4575:21: 0x1ddee6c in analyzeFnBody (zig)
  sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                  ^
/home/techatrix/repos/zig/src/Module.zig:3272:40: 0x1b30ae4 in ensureFuncBodyAnalyzed (zig)
          var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                     ^
/home/techatrix/repos/zig/src/Compilation.zig:3539:42: 0x1b2ee4f in processOneJob (zig)
          module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                       ^
/home/techatrix/repos/zig/src/Compilation.zig:3476:30: 0x18f7ba0 in performAllTheWork (zig)
          try processOneJob(comp, work_item, main_progress_node);
                           ^
/home/techatrix/repos/zig/src/Compilation.zig:2186:31: 0x18f384e in update (zig)
  try comp.performAllTheWork(main_progress_node);
                            ^
/home/techatrix/repos/zig/src/main.zig:4478:24: 0x1922e3c in updateModule (zig)
      try comp.update(main_progress_node);
                     ^
/home/techatrix/repos/zig/src/main.zig:3342:17: 0x1941143 in buildOutputType (zig)
  updateModule(comp, color) catch |err| switch (err) {
              ^
/home/techatrix/repos/zig/src/main.zig:285:31: 0x1739cb7 in mainArgs (zig)
      return buildOutputType(gpa, arena, args, .run);
                            ^
/home/techatrix/repos/zig/src/main.zig:223:20: 0x1736cc5 in main (zig)
  return mainArgs(gpa, arena, args);
                 ^
/home/techatrix/repos/zig/build/stage3/lib/zig/std/start.zig:585:37: 0x1736746 in main (zig)
          const result = root.main() catch |err| {
                                  ^
???:?:?: 0x7fffeb23ffcd in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7fffeb23ffcd` was not available, trace may be incomplete

Aborted (core dumped)

Expected Behavior

file.zig:2:11: error: expected error union type, found 'bool'
    false catch |err| switch (err) {

The zirSwitchBlockErrUnion function doesn't properly check if the operand is a Error Union.

Probably caused by #18173.

@Techatrix Techatrix added the bug Observed behavior contradicts documented or intended behavior label Jan 16, 2024
@Vexu Vexu added frontend Tokenization, parsing, AstGen, Sema, and Liveness. regression It worked in a previous version of Zig, but stopped working. labels Jan 16, 2024
@Vexu Vexu added this to the 0.12.0 milestone Jan 16, 2024
@Rexicon226
Copy link
Contributor

Good catch! Fixed in #18593

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 frontend Tokenization, parsing, AstGen, Sema, and Liveness. regression It worked in a previous version of Zig, but stopped working.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants