Commit 707131e37b

Andrew Kelley <superjoe30@gmail.com>
2016-04-10 02:26:04
goto: jumping out of scope runs defers
see #44
1 parent 7eb6af1
Changed files (2)
src/codegen.cpp
@@ -2724,6 +2724,12 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
 static LLVMValueRef gen_goto(CodeGen *g, AstNode *node) {
     assert(node->type == NodeTypeGoto);
 
+    // generate defers for blocks that we exit
+    LabelTableEntry *label = node->data.goto_expr.label_entry;
+    BlockContext *this_context = node->block_context;
+    BlockContext *target_context = label->decl_node->block_context;
+    gen_defers_for_block(g, this_context, target_context, false, false);
+
     add_debug_source_node(g, node);
     LLVMBuildBr(g->builder, node->data.goto_expr.label_entry->basic_block);
     return nullptr;
test/self_hosted.zig
@@ -591,3 +591,21 @@ var goto_counter: i32 = 0;
 
 
 
+#attribute("test")
+fn goto_leave_defer_scope() {
+    test_goto_leave_defer_scope(true);
+}
+fn test_goto_leave_defer_scope(b: bool) {
+    var it_worked = false;
+
+    goto entry;
+exit:
+    if (it_worked) {
+        return;
+    }
+    unreachable{};
+entry:
+    defer it_worked = true;
+    if (b) goto exit;
+}
+