authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-09 17:26:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-09 17:26:04-07:00
log707131e37b2ee384d46c26ada83f3c83edf7278d
tree9be432cadba02d1814997072029dd16705a5c740
parent7eb6af1d3e92510cb558d43ac80c45964f183bb7

goto: jumping out of scope runs defers

see #44

2 files changed, 24 insertions(+), 0 deletions(-)

src/codegen.cpp+6
......@@ -2724,6 +2724,12 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
27242724static LLVMValueRef gen_goto(CodeGen *g, AstNode *node) {
27252725 assert(node->type == NodeTypeGoto);
27262726
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
27272733 add_debug_source_node(g, node);
27282734 LLVMBuildBr(g->builder, node->data.goto_expr.label_entry->basic_block);
27292735 return nullptr;
test/self_hosted.zig+18
......@@ -591,3 +591,21 @@ var goto_counter: i32 = 0;
591591
592592
593593
594#attribute("test")
595fn goto_leave_defer_scope() {
596 test_goto_leave_defer_scope(true);
597}
598fn test_goto_leave_defer_scope(b: bool) {
599 var it_worked = false;
600
601 goto entry;
602exit:
603 if (it_worked) {
604 return;
605 }
606 unreachable{};
607entry:
608 defer it_worked = true;
609 if (b) goto exit;
610}
611