| author | |
| committer | |
| log | 707131e37b2ee384d46c26ada83f3c83edf7278d |
| tree | 9be432cadba02d1814997072029dd16705a5c740 |
| parent | 7eb6af1d3e92510cb558d43ac80c45964f183bb7 |
see #442 files changed, 24 insertions(+), 0 deletions(-)
src/codegen.cpp+6| ... | ... | @@ -2724,6 +2724,12 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2724 | 2724 | static LLVMValueRef gen_goto(CodeGen *g, AstNode *node) { |
| 2725 | 2725 | assert(node->type == NodeTypeGoto); |
| 2726 | 2726 | |
| 2727 | // generate defers for blocks that we exit | |
| 2728 | LabelTableEntry *label = node->data.goto_expr.label_entry; | |
| 2729 | BlockContext *this_context = node->block_context; | |
| 2730 | BlockContext *target_context = label->decl_node->block_context; | |
| 2731 | gen_defers_for_block(g, this_context, target_context, false, false); | |
| 2732 | ||
| 2727 | 2733 | add_debug_source_node(g, node); |
| 2728 | 2734 | LLVMBuildBr(g->builder, node->data.goto_expr.label_entry->basic_block); |
| 2729 | 2735 | return nullptr; |
test/self_hosted.zig+18| ... | ... | @@ -591,3 +591,21 @@ var goto_counter: i32 = 0; |
| 591 | 591 | |
| 592 | 592 | |
| 593 | 593 | |
| 594 | #attribute("test") | |
| 595 | fn goto_leave_defer_scope() { | |
| 596 | test_goto_leave_defer_scope(true); | |
| 597 | } | |
| 598 | fn test_goto_leave_defer_scope(b: bool) { | |
| 599 | var it_worked = false; | |
| 600 | ||
| 601 | goto entry; | |
| 602 | exit: | |
| 603 | if (it_worked) { | |
| 604 | return; | |
| 605 | } | |
| 606 | unreachable{}; | |
| 607 | entry: | |
| 608 | defer it_worked = true; | |
| 609 | if (b) goto exit; | |
| 610 | } | |
| 611 |