| ... | @@ -2328,6 +2328,7 @@ fn analyzeSwitch( | ... | @@ -2328,6 +2328,7 @@ fn analyzeSwitch( |
| 2328 | switch_inst: zir.Inst.Index, | 2328 | switch_inst: zir.Inst.Index, |
| 2329 | src_node_offset: i32, | 2329 | src_node_offset: i32, |
| 2330 | ) InnerError!*Inst { | 2330 | ) InnerError!*Inst { |
| | 2331 | const gpa = sema.gpa; |
| 2331 | const special: struct { body: []const zir.Inst.Index, end: usize } = switch (special_prong) { | 2332 | const special: struct { body: []const zir.Inst.Index, end: usize } = switch (special_prong) { |
| 2332 | .none => .{ .body = &.{}, .end = extra_end }, | 2333 | .none => .{ .body = &.{}, .end = extra_end }, |
| 2333 | .under, .@"else" => blk: { | 2334 | .under, .@"else" => blk: { |
| ... | @@ -2353,7 +2354,7 @@ fn analyzeSwitch( | ... | @@ -2353,7 +2354,7 @@ fn analyzeSwitch( |
| 2353 | "'_' prong only allowed when switching on non-exhaustive enums", | 2354 | "'_' prong only allowed when switching on non-exhaustive enums", |
| 2354 | .{}, | 2355 | .{}, |
| 2355 | ); | 2356 | ); |
| 2356 | errdefer msg.destroy(sema.gpa); | 2357 | errdefer msg.destroy(gpa); |
| 2357 | try sema.mod.errNote( | 2358 | try sema.mod.errNote( |
| 2358 | &block.base, | 2359 | &block.base, |
| 2359 | special_prong_src, | 2360 | special_prong_src, |
| ... | @@ -2372,7 +2373,7 @@ fn analyzeSwitch( | ... | @@ -2372,7 +2373,7 @@ fn analyzeSwitch( |
| 2372 | .ErrorSet => return sema.mod.fail(&block.base, src, "TODO validate switch .ErrorSet", .{}), | 2373 | .ErrorSet => return sema.mod.fail(&block.base, src, "TODO validate switch .ErrorSet", .{}), |
| 2373 | .Union => return sema.mod.fail(&block.base, src, "TODO validate switch .Union", .{}), | 2374 | .Union => return sema.mod.fail(&block.base, src, "TODO validate switch .Union", .{}), |
| 2374 | .Int, .ComptimeInt => { | 2375 | .Int, .ComptimeInt => { |
| 2375 | var range_set = RangeSet.init(sema.gpa); | 2376 | var range_set = RangeSet.init(gpa); |
| 2376 | defer range_set.deinit(); | 2377 | defer range_set.deinit(); |
| 2377 | | 2378 | |
| 2378 | var extra_index: usize = special.end; | 2379 | var extra_index: usize = special.end; |
| ... | @@ -2440,7 +2441,7 @@ fn analyzeSwitch( | ... | @@ -2440,7 +2441,7 @@ fn analyzeSwitch( |
| 2440 | | 2441 | |
| 2441 | check_range: { | 2442 | check_range: { |
| 2442 | if (operand.ty.zigTypeTag() == .Int) { | 2443 | if (operand.ty.zigTypeTag() == .Int) { |
| 2443 | var arena = std.heap.ArenaAllocator.init(sema.gpa); | 2444 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 2444 | defer arena.deinit(); | 2445 | defer arena.deinit(); |
| 2445 | | 2446 | |
| 2446 | const min_int = try operand.ty.minInt(&arena, sema.mod.getTarget()); | 2447 | const min_int = try operand.ty.minInt(&arena, sema.mod.getTarget()); |
| ... | @@ -2549,7 +2550,7 @@ fn analyzeSwitch( | ... | @@ -2549,7 +2550,7 @@ fn analyzeSwitch( |
| 2549 | ); | 2550 | ); |
| 2550 | } | 2551 | } |
| 2551 | | 2552 | |
| 2552 | var seen_values = ValueSrcMap.init(sema.gpa); | 2553 | var seen_values = ValueSrcMap.init(gpa); |
| 2553 | defer seen_values.deinit(); | 2554 | defer seen_values.deinit(); |
| 2554 | | 2555 | |
| 2555 | var extra_index: usize = special.end; | 2556 | var extra_index: usize = special.end; |
| ... | @@ -2712,16 +2713,16 @@ fn analyzeSwitch( | ... | @@ -2712,16 +2713,16 @@ fn analyzeSwitch( |
| 2712 | .is_comptime = block.is_comptime, | 2713 | .is_comptime = block.is_comptime, |
| 2713 | }; | 2714 | }; |
| 2714 | const merges = &child_block.label.?.merges; | 2715 | const merges = &child_block.label.?.merges; |
| 2715 | defer child_block.instructions.deinit(sema.gpa); | 2716 | defer child_block.instructions.deinit(gpa); |
| 2716 | defer merges.results.deinit(sema.gpa); | 2717 | defer merges.results.deinit(gpa); |
| 2717 | defer merges.br_list.deinit(sema.gpa); | 2718 | defer merges.br_list.deinit(gpa); |
| 2718 | | 2719 | |
| 2719 | // TODO when reworking TZIR memory layout make multi cases get generated as cases, | 2720 | // TODO when reworking TZIR memory layout make multi cases get generated as cases, |
| 2720 | // not as part of the "else" block. | 2721 | // not as part of the "else" block. |
| 2721 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); | 2722 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); |
| 2722 | | 2723 | |
| 2723 | var case_block = child_block.makeSubBlock(); | 2724 | var case_block = child_block.makeSubBlock(); |
| 2724 | defer case_block.instructions.deinit(sema.gpa); | 2725 | defer case_block.instructions.deinit(gpa); |
| 2725 | | 2726 | |
| 2726 | var extra_index: usize = special.end; | 2727 | var extra_index: usize = special.end; |
| 2727 | | 2728 | |
| ... | @@ -2747,7 +2748,7 @@ fn analyzeSwitch( | ... | @@ -2747,7 +2748,7 @@ fn analyzeSwitch( |
| 2747 | }; | 2748 | }; |
| 2748 | } | 2749 | } |
| 2749 | | 2750 | |
| 2750 | var first_condbr: *Inst.CondBr = undefined; | 2751 | var first_else_body: Body = undefined; |
| 2751 | var prev_condbr: ?*Inst.CondBr = null; | 2752 | var prev_condbr: ?*Inst.CondBr = null; |
| 2752 | | 2753 | |
| 2753 | var multi_i: usize = 0; | 2754 | var multi_i: usize = 0; |
| ... | @@ -2822,12 +2823,6 @@ fn analyzeSwitch( | ... | @@ -2822,12 +2823,6 @@ fn analyzeSwitch( |
| 2822 | } | 2823 | } |
| 2823 | } | 2824 | } |
| 2824 | | 2825 | |
| 2825 | const body = sema.code.extra[extra_index..][0..body_len]; | | |
| 2826 | extra_index += body_len; | | |
| 2827 | _ = try sema.analyzeBody(&case_block, body); | | |
| 2828 | const then_body: Body = .{ | | |
| 2829 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), | | |
| 2830 | }; | | |
| 2831 | const new_condbr = try sema.arena.create(Inst.CondBr); | 2826 | const new_condbr = try sema.arena.create(Inst.CondBr); |
| 2832 | new_condbr.* = .{ | 2827 | new_condbr.* = .{ |
| 2833 | .base = .{ | 2828 | .base = .{ |
| ... | @@ -2836,15 +2831,26 @@ fn analyzeSwitch( | ... | @@ -2836,15 +2831,26 @@ fn analyzeSwitch( |
| 2836 | .src = src, | 2831 | .src = src, |
| 2837 | }, | 2832 | }, |
| 2838 | .condition = any_ok.?, | 2833 | .condition = any_ok.?, |
| 2839 | .then_body = then_body, | 2834 | .then_body = undefined, |
| 2840 | .else_body = undefined, | 2835 | .else_body = undefined, |
| 2841 | }; | 2836 | }; |
| | 2837 | try case_block.instructions.append(gpa, &new_condbr.base); |
| | 2838 | |
| | 2839 | const cond_body: Body = .{ |
| | 2840 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), |
| | 2841 | }; |
| | 2842 | |
| | 2843 | case_block.instructions.shrinkRetainingCapacity(0); |
| | 2844 | const body = sema.code.extra[extra_index..][0..body_len]; |
| | 2845 | extra_index += body_len; |
| | 2846 | _ = try sema.analyzeBody(&case_block, body); |
| | 2847 | new_condbr.then_body = .{ |
| | 2848 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), |
| | 2849 | }; |
| 2842 | if (prev_condbr) |condbr| { | 2850 | if (prev_condbr) |condbr| { |
| 2843 | condbr.else_body = .{ | 2851 | condbr.else_body = cond_body; |
| 2844 | .instructions = try sema.arena.dupe(*Inst, &[1]*Inst{&new_condbr.base}), | | |
| 2845 | }; | | |
| 2846 | } else { | 2852 | } else { |
| 2847 | first_condbr = new_condbr; | 2853 | first_else_body = cond_body; |
| 2848 | } | 2854 | } |
| 2849 | prev_condbr = new_condbr; | 2855 | prev_condbr = new_condbr; |
| 2850 | } | 2856 | } |
| ... | @@ -2856,11 +2862,9 @@ fn analyzeSwitch( | ... | @@ -2856,11 +2862,9 @@ fn analyzeSwitch( |
| 2856 | const else_body: Body = .{ | 2862 | const else_body: Body = .{ |
| 2857 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), | 2863 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), |
| 2858 | }; | 2864 | }; |
| 2859 | if (prev_condbr != null) { | 2865 | if (prev_condbr) |condbr| { |
| 2860 | first_condbr.else_body = else_body; | 2866 | condbr.else_body = else_body; |
| 2861 | break :blk .{ | 2867 | break :blk first_else_body; |
| 2862 | .instructions = try sema.arena.dupe(*Inst, &[1]*Inst{&first_condbr.base}), | | |
| 2863 | }; | | |
| 2864 | } else { | 2868 | } else { |
| 2865 | break :blk else_body; | 2869 | break :blk else_body; |
| 2866 | } | 2870 | } |