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 {
21932193 size_t case_count;
21942194 IrInstructionSwitchBrCase *cases;
21952195 IrInstruction *is_comptime;
2196 IrInstruction *switch_prongs_void;
21962197};
21972198
21982199struct IrInstructionSwitchVar {
src/ir.cpp+27-11
......@@ -1719,7 +1719,8 @@ static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instr
17191719}
17201720
17211721static 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)
17231724{
17241725 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node);
17251726 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 *
17291730 instruction->case_count = case_count;
17301731 instruction->cases = cases;
17311732 instruction->is_comptime = is_comptime;
1733 instruction->switch_prongs_void = switch_prongs_void;
17321734
17331735 ir_ref_instruction(target_value, irb->current_basic_block);
17341736 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block);
17351737 ir_ref_bb(else_block);
1738 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block);
17361739
17371740 for (size_t i = 0; i < case_count; i += 1) {
17381741 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 *
17441747
17451748static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old_instruction,
17461749 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)
17481751{
17491752 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);
17511754 ir_link_new_instruction(new_instruction, old_instruction);
17521755 return new_instruction;
17531756}
......@@ -6035,13 +6038,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
60356038
60366039 }
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,
60396042 else_prong != nullptr);
60406043
60416044 if (cases.length == 0) {
60426045 ir_build_br(irb, scope, node, else_block, is_comptime);
60436046 } 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);
60456048 }
60466049
60476050 if (!else_prong) {
......@@ -6692,7 +6695,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *parent_scope, Ast
66926695 cases[1].value = ir_build_const_u8(irb, parent_scope, node, 1);
66936696 cases[1].block = cleanup_block;
66946697 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
66976700 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
66986701 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
67736776 cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1));
67746777 cases[1].block = cleanup_block;
67756778 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
67786781 ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
67796782 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
70787081 cases[0].block = invalid_resume_block;
70797082 cases[1].value = ir_build_const_u8(irb, scope, node, 1);
70807083 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
70837086 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block);
70847087 ir_build_coro_end(irb, scope, node);
......@@ -15297,6 +15300,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1529715300 if (type_is_invalid(target_value->value.type))
1529815301 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
1530015310 size_t case_count = switch_br_instruction->case_count;
1530115311
1530215312 bool is_comptime;
......@@ -15387,7 +15397,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1538715397
1538815398 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base);
1538915399 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);
1539115401 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
1539215402}
1539315403
......@@ -19136,16 +19146,22 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
1913619146 IrInstruction *start_value = range->start->other;
1913719147 if (type_is_invalid(start_value->value.type))
1913819148 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
1914019153 IrInstruction *end_value = range->end->other;
1914119154 if (type_is_invalid(end_value->value.type))
1914219155 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);
1914519161 if (!start_val)
1914619162 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);
1914919165 if (!end_val)
1915019166 return ira->codegen->builtin_types.entry_invalid;
1915119167
test/compile_errors.zig+18
......@@ -358,6 +358,24 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
358358 ".tmp_source.zig:3:14: note: other value is here",
359359 );
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
361379 cases.add(
362380 "range operator in switch used on error set",
363381 \\export fn entry() void {