authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:03:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:03:07-04:00
log1a5bd8888174ef2eb1881c1dd81d418b44625cc7
treeda3b78b294e6d21271ae9095dffece83450cecdd
parent9cff23dbf9ff3da716a1c4397f9411eba09f6cac

alternate implementation of previous commit

This strategy adds another field to the SwitchBr instruction, which is the result of the CheckSwitchProngs instruction. The type of the result is void, and is unused, except that the SwitchBr instruction will not perform analysis if the CheckSwitchProngs instruction did not pass analysis. This allows the CheckSwitchProngs instruction to do implicit casting for its type checking, while preventing duplicate compile error messages.

2 files changed, 28 insertions(+), 17 deletions(-)

src/all_types.hpp+1
...@@ -2193,6 +2193,7 @@ struct IrInstructionSwitchBr {...@@ -2193,6 +2193,7 @@ struct IrInstructionSwitchBr {
2193 size_t case_count;2193 size_t case_count;
2194 IrInstructionSwitchBrCase *cases;2194 IrInstructionSwitchBrCase *cases;
2195 IrInstruction *is_comptime;2195 IrInstruction *is_comptime;
2196 IrInstruction *switch_prongs_void;
2196};2197};
21972198
2198struct IrInstructionSwitchVar {2199struct IrInstructionSwitchVar {
src/ir.cpp+27-17
...@@ -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}
17201720
1721static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value,1721static 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;
17321734
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);
17361739
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 *
17441747
1745static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction,1748static 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 *
60356038
6036 }6039 }
60376040
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);
60406043
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 }
60466049
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);
66966699
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));
67776780
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);
70827085
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);
1529915302
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;
1530115311
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,
1538715397
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}
1539315403
...@@ -19136,27 +19146,27 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira...@@ -19136,27 +19146,27 @@ 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;
1913919152
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;
1914319159
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;
1914719163
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;
1915119167
19152 if (start_val->type->id == TypeTableEntryIdEnum)
19153 return ira->codegen->builtin_types.entry_invalid;
19154 assert(start_val->type->id == TypeTableEntryIdInt || start_val->type->id == TypeTableEntryIdComptimeInt);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 assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdComptimeInt);19169 assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdComptimeInt);
19159
19160 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,19170 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,
19161 start_value->source_node);19171 start_value->source_node);
19162 if (prev_node != nullptr) {19172 if (prev_node != nullptr) {