commit 707131e37b2ee384d46c26ada83f3c83edf7278d (tree)
parent 7eb6af1d3e92510cb558d43ac80c45964f183bb7
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Sat, 9 Apr 2016 17:26:04 -0700
goto: jumping out of scope runs defers
see #44
Diffstat:
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/src/codegen.cpp b/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;
diff --git a/test/self_hosted.zig b/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;
+}
+