authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:07:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 12:07:57-04:00
log0e9fef78dd7e55626ab659cd12ca5ea37d633ea7
treeda3b78b294e6d21271ae9095dffece83450cecdd
parent8c39cdc89f2ae7fc25c3856e7c4c6b4662ac8a80
parent1a5bd8888174ef2eb1881c1dd81d418b44625cc7

Merge branch 'isaachier-switch-enum-fix'


3 files changed, 46 insertions(+), 11 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-11
...@@ -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,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;
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
test/compile_errors.zig+18
...@@ -358,6 +358,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -358,6 +358,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
358 ".tmp_source.zig:3:14: note: other value is here",358 ".tmp_source.zig:3:14: note: other value is here",
359 );359 );
360360
361
362 cases.add(
363 "invalid cast from integral type to enum",
364 \\const E = enum(usize) { One, Two };
365 \\
366 \\export fn entry() void {
367 \\ foo(1);
368 \\}
369 \\
370 \\fn foo(x: usize) void {
371 \\ switch (x) {
372 \\ E.One => {},
373 \\ }
374 \\}
375 ,
376 ".tmp_source.zig:9:10: error: expected type 'usize', found 'E'"
377 );
378
361 cases.add(379 cases.add(
362 "range operator in switch used on error set",380 "range operator in switch used on error set",
363 \\export fn entry() void {381 \\export fn entry() void {