| ... | ... | @@ -1719,7 +1719,8 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr |
| 1719 | 1719 | } |
| 1720 | 1720 | |
| 1721 | 1721 | static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, |
| 1722 | | IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime) |
| 1722 | IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, |
| 1723 | IrInstruction *switch_prongs_void) |
| 1723 | 1724 | { |
| 1724 | 1725 | IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); |
| 1725 | 1726 | instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| ... | ... | @@ -1729,10 +1730,12 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * |
| 1729 | 1730 | instruction->case_count = case_count; |
| 1730 | 1731 | instruction->cases = cases; |
| 1731 | 1732 | instruction->is_comptime = is_comptime; |
| 1733 | instruction->switch_prongs_void = switch_prongs_void; |
| 1732 | 1734 | |
| 1733 | 1735 | ir_ref_instruction(target_value, irb->current_basic_block); |
| 1734 | 1736 | if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 1735 | 1737 | ir_ref_bb(else_block); |
| 1738 | if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); |
| 1736 | 1739 | |
| 1737 | 1740 | for (size_t i = 0; i < case_count; i += 1) { |
| 1738 | 1741 | ir_ref_instruction(cases[i].value, irb->current_basic_block); |
| ... | ... | @@ -1744,10 +1747,10 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * |
| 1744 | 1747 | |
| 1745 | 1748 | static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 1746 | 1749 | IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count, |
| 1747 | | IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime) |
| 1750 | IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, IrInstruction *switch_prongs_void) |
| 1748 | 1751 | { |
| 1749 | 1752 | IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->scope, old_instruction->source_node, |
| 1750 | | target_value, else_block, case_count, cases, is_comptime); |
| 1753 | target_value, else_block, case_count, cases, is_comptime, switch_prongs_void); |
| 1751 | 1754 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1752 | 1755 | return new_instruction; |
| 1753 | 1756 | } |
| ... | ... | @@ -6035,13 +6038,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6035 | 6038 | |
| 6036 | 6039 | } |
| 6037 | 6040 | |
| 6038 | | ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, |
| 6041 | IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, |
| 6039 | 6042 | else_prong != nullptr); |
| 6040 | 6043 | |
| 6041 | 6044 | if (cases.length == 0) { |
| 6042 | 6045 | ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6043 | 6046 | } else { |
| 6044 | | ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime); |
| 6047 | ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); |
| 6045 | 6048 | } |
| 6046 | 6049 | |
| 6047 | 6050 | if (!else_prong) { |
| ... | ... | @@ -6692,7 +6695,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast |
| 6692 | 6695 | cases[1].value = ir_build_const_u8(irb, parent_scope, node, 1); |
| 6693 | 6696 | cases[1].block = cleanup_block; |
| 6694 | 6697 | ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, |
| 6695 | | 2, cases, const_bool_false); |
| 6698 | 2, cases, const_bool_false, nullptr); |
| 6696 | 6699 | |
| 6697 | 6700 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 6698 | 6701 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| ... | ... | @@ -6773,7 +6776,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 6773 | 6776 | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); |
| 6774 | 6777 | cases[1].block = cleanup_block; |
| 6775 | 6778 | ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, |
| 6776 | | 2, cases, const_bool_false)); |
| 6779 | 2, cases, const_bool_false, nullptr)); |
| 6777 | 6780 | |
| 6778 | 6781 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 6779 | 6782 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); |
| ... | ... | @@ -7078,7 +7081,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7078 | 7081 | cases[0].block = invalid_resume_block; |
| 7079 | 7082 | cases[1].value = ir_build_const_u8(irb, scope, node, 1); |
| 7080 | 7083 | cases[1].block = irb->exec->coro_final_cleanup_block; |
| 7081 | | ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false); |
| 7084 | ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); |
| 7082 | 7085 | |
| 7083 | 7086 | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); |
| 7084 | 7087 | ir_build_coro_end(irb, scope, node); |
| ... | ... | @@ -15297,6 +15300,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 15297 | 15300 | if (type_is_invalid(target_value->value.type)) |
| 15298 | 15301 | return ir_unreach_error(ira); |
| 15299 | 15302 | |
| 15303 | if (switch_br_instruction->switch_prongs_void != nullptr) { |
| 15304 | if (type_is_invalid(switch_br_instruction->switch_prongs_void->other->value.type)) { |
| 15305 | return ir_unreach_error(ira); |
| 15306 | } |
| 15307 | } |
| 15308 | |
| 15309 | |
| 15300 | 15310 | size_t case_count = switch_br_instruction->case_count; |
| 15301 | 15311 | |
| 15302 | 15312 | bool is_comptime; |
| ... | ... | @@ -15387,7 +15397,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 15387 | 15397 | |
| 15388 | 15398 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); |
| 15389 | 15399 | ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, |
| 15390 | | target_value, new_else_block, case_count, cases, nullptr); |
| 15400 | target_value, new_else_block, case_count, cases, nullptr, nullptr); |
| 15391 | 15401 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 15392 | 15402 | } |
| 15393 | 15403 | |
| ... | ... | @@ -19136,27 +19146,27 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira |
| 19136 | 19146 | IrInstruction *start_value = range->start->other; |
| 19137 | 19147 | if (type_is_invalid(start_value->value.type)) |
| 19138 | 19148 | return ira->codegen->builtin_types.entry_invalid; |
| 19149 | IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); |
| 19150 | if (type_is_invalid(casted_start_value->value.type)) |
| 19151 | return ira->codegen->builtin_types.entry_invalid; |
| 19139 | 19152 | |
| 19140 | 19153 | IrInstruction *end_value = range->end->other; |
| 19141 | 19154 | if (type_is_invalid(end_value->value.type)) |
| 19142 | 19155 | return ira->codegen->builtin_types.entry_invalid; |
| 19156 | IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); |
| 19157 | if (type_is_invalid(casted_end_value->value.type)) |
| 19158 | return ira->codegen->builtin_types.entry_invalid; |
| 19143 | 19159 | |
| 19144 | | ConstExprValue *start_val = ir_resolve_const(ira, start_value, UndefBad); |
| 19160 | ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); |
| 19145 | 19161 | if (!start_val) |
| 19146 | 19162 | return ira->codegen->builtin_types.entry_invalid; |
| 19147 | 19163 | |
| 19148 | | ConstExprValue *end_val = ir_resolve_const(ira, end_value, UndefBad); |
| 19164 | ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); |
| 19149 | 19165 | if (!end_val) |
| 19150 | 19166 | return ira->codegen->builtin_types.entry_invalid; |
| 19151 | 19167 | |
| 19152 | | if (start_val->type->id == TypeTableEntryIdEnum) |
| 19153 | | return ira->codegen->builtin_types.entry_invalid; |
| 19154 | 19168 | assert(start_val->type->id == TypeTableEntryIdInt || start_val->type->id == TypeTableEntryIdComptimeInt); |
| 19155 | | |
| 19156 | | if (end_val->type->id == TypeTableEntryIdEnum) |
| 19157 | | return ira->codegen->builtin_types.entry_invalid; |
| 19158 | 19169 | assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdComptimeInt); |
| 19159 | | |
| 19160 | 19170 | AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, |
| 19161 | 19171 | start_value->source_node); |
| 19162 | 19172 | if (prev_node != nullptr) { |