| ... | @@ -1719,7 +1719,8 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr | ... | @@ -1719,7 +1719,8 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr |
| 1719 | } | 1719 | } |
| 1720 | | 1720 | |
| 1721 | static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, | 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 | IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); | 1725 | IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); |
| 1725 | instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; | 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,10 +1730,12 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * |
| 1729 | instruction->case_count = case_count; | 1730 | instruction->case_count = case_count; |
| 1730 | instruction->cases = cases; | 1731 | instruction->cases = cases; |
| 1731 | instruction->is_comptime = is_comptime; | 1732 | instruction->is_comptime = is_comptime; |
| | 1733 | instruction->switch_prongs_void = switch_prongs_void; |
| 1732 | | 1734 | |
| 1733 | ir_ref_instruction(target_value, irb->current_basic_block); | 1735 | ir_ref_instruction(target_value, irb->current_basic_block); |
| 1734 | if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); | 1736 | if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); |
| 1735 | ir_ref_bb(else_block); | 1737 | ir_ref_bb(else_block); |
| | 1738 | if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); |
| 1736 | | 1739 | |
| 1737 | for (size_t i = 0; i < case_count; i += 1) { | 1740 | for (size_t i = 0; i < case_count; i += 1) { |
| 1738 | ir_ref_instruction(cases[i].value, irb->current_basic_block); | 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,10 +1747,10 @@ static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode * |
| 1744 | | 1747 | |
| 1745 | static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction, | 1748 | static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 1746 | IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count, | 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 | IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->scope, old_instruction->source_node, | 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 | ir_link_new_instruction(new_instruction, old_instruction); | 1754 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1752 | return new_instruction; | 1755 | return new_instruction; |
| 1753 | } | 1756 | } |
| ... | @@ -6035,13 +6038,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -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 | else_prong != nullptr); | 6042 | else_prong != nullptr); |
| 6040 | | 6043 | |
| 6041 | if (cases.length == 0) { | 6044 | if (cases.length == 0) { |
| 6042 | ir_build_br(irb, scope, node, else_block, is_comptime); | 6045 | ir_build_br(irb, scope, node, else_block, is_comptime); |
| 6043 | } else { | 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 | if (!else_prong) { | 6050 | if (!else_prong) { |
| ... | @@ -6692,7 +6695,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast | ... | @@ -6692,7 +6695,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast |
| 6692 | cases[1].value = ir_build_const_u8(irb, parent_scope, node, 1); | 6695 | cases[1].value = ir_build_const_u8(irb, parent_scope, node, 1); |
| 6693 | cases[1].block = cleanup_block; | 6696 | cases[1].block = cleanup_block; |
| 6694 | ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, | 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 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); | 6700 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 6698 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); | 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,7 +6776,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod |
| 6773 | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); | 6776 | cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); |
| 6774 | cases[1].block = cleanup_block; | 6777 | cases[1].block = cleanup_block; |
| 6775 | ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, | 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 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); | 6781 | ir_set_cursor_at_end_and_append_block(irb, cleanup_block); |
| 6779 | ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); | 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,7 +7081,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 7078 | cases[0].block = invalid_resume_block; | 7081 | cases[0].block = invalid_resume_block; |
| 7079 | cases[1].value = ir_build_const_u8(irb, scope, node, 1); | 7082 | cases[1].value = ir_build_const_u8(irb, scope, node, 1); |
| 7080 | cases[1].block = irb->exec->coro_final_cleanup_block; | 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 | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); | 7086 | ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); |
| 7084 | ir_build_coro_end(irb, scope, node); | 7087 | ir_build_coro_end(irb, scope, node); |
| ... | @@ -15297,6 +15300,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, | ... | @@ -15297,6 +15300,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 15297 | if (type_is_invalid(target_value->value.type)) | 15300 | if (type_is_invalid(target_value->value.type)) |
| 15298 | return ir_unreach_error(ira); | 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 | size_t case_count = switch_br_instruction->case_count; | 15310 | size_t case_count = switch_br_instruction->case_count; |
| 15301 | | 15311 | |
| 15302 | bool is_comptime; | 15312 | bool is_comptime; |
| ... | @@ -15387,7 +15397,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, | ... | @@ -15387,7 +15397,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 15387 | | 15397 | |
| 15388 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); | 15398 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); |
| 15389 | ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, | 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 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 15401 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 15392 | } | 15402 | } |
| 15393 | | 15403 | |
| ... | @@ -19136,16 +19146,22 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira | ... | @@ -19136,16 +19146,22 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira |
| 19136 | IrInstruction *start_value = range->start->other; | 19146 | IrInstruction *start_value = range->start->other; |
| 19137 | if (type_is_invalid(start_value->value.type)) | 19147 | if (type_is_invalid(start_value->value.type)) |
| 19138 | return ira->codegen->builtin_types.entry_invalid; | 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 | IrInstruction *end_value = range->end->other; | 19153 | IrInstruction *end_value = range->end->other; |
| 19141 | if (type_is_invalid(end_value->value.type)) | 19154 | if (type_is_invalid(end_value->value.type)) |
| 19142 | return ira->codegen->builtin_types.entry_invalid; | 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 | if (!start_val) | 19161 | if (!start_val) |
| 19146 | return ira->codegen->builtin_types.entry_invalid; | 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 | if (!end_val) | 19165 | if (!end_val) |
| 19150 | return ira->codegen->builtin_types.entry_invalid; | 19166 | return ira->codegen->builtin_types.entry_invalid; |
| 19151 | | 19167 | |