authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-29 19:08:15+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-29 16:05:14-05:00
log59bc1d272120bd860cc3cd1f894a2a4e08fc1f3f
tree0b7eb6fd36762579a141d152b10e0d60b540b217
parent4fad16284ec30962689723c7eaca05a77df14673

Fix edge case in switch with single else

ir_gen_switch_expr doesn't set the switch_br field at all if there are zero cases, detect this situation and handle it gracefully. Closes #4322

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

src/ir.cpp+3-1
...@@ -22768,7 +22768,9 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira,...@@ -22768,7 +22768,9 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira,
22768 }22768 }
22769 // Make note of the errors handled by other cases22769 // Make note of the errors handled by other cases
22770 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);22770 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length);
22771 for (size_t case_i = 0; case_i < instruction->switch_br->case_count; case_i += 1) {22771 // We may not have any case in the switch if this is a lone else
22772 const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0;
22773 for (size_t case_i = 0; case_i < switch_cases; case_i += 1) {
22772 IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i];22774 IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i];
22773 IrInstGen *case_expr = br_case->value->child;22775 IrInstGen *case_expr = br_case->value->child;
22774 if (case_expr->value->type->id == ZigTypeIdErrorSet) {22776 if (case_expr->value->type->id == ZigTypeIdErrorSet) {
test/stage1/behavior/switch.zig+14
...@@ -479,3 +479,17 @@ test "switch on pointer type" {...@@ -479,3 +479,17 @@ test "switch on pointer type" {
479 comptime expect(2 == S.doTheTest(S.P2));479 comptime expect(2 == S.doTheTest(S.P2));
480 comptime expect(3 == S.doTheTest(S.P3));480 comptime expect(3 == S.doTheTest(S.P3));
481}481}
482
483test "switch on error set with single else" {
484 const S = struct {
485 fn doTheTest() void {
486 var some: error{Foo} = error.Foo;
487 expect(switch (some) {
488 else => |a| true,
489 });
490 }
491 };
492
493 S.doTheTest();
494 comptime S.doTheTest();
495}