| ... | @@ -5982,12 +5982,34 @@ static bool ir_goto_pass2(IrBuilder *irb) { | ... | @@ -5982,12 +5982,34 @@ static bool ir_goto_pass2(IrBuilder *irb) { |
| 5982 | irb->current_basic_block->instruction_list.resize(goto_item->instruction_index); | 5982 | irb->current_basic_block->instruction_list.resize(goto_item->instruction_index); |
| 5983 | | 5983 | |
| 5984 | Buf *label_name = source_node->data.goto_expr.name; | 5984 | Buf *label_name = source_node->data.goto_expr.name; |
| 5985 | LabelTableEntry *label = find_label(irb->exec, goto_item->scope, label_name); | 5985 | |
| 5986 | if (!label) { | 5986 | // Search up the scope until we find one of these things: |
| 5987 | add_node_error(irb->codegen, source_node, | 5987 | // * A block scope with the label in it => OK |
| 5988 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); | 5988 | // * A defer expression scope => error, error, cannot leave defer expression |
| 5989 | return false; | 5989 | // * Top level scope => error, didn't find label |
| | 5990 | |
| | 5991 | LabelTableEntry *label; |
| | 5992 | Scope *search_scope = goto_item->scope; |
| | 5993 | for (;;) { |
| | 5994 | if (search_scope == nullptr) { |
| | 5995 | add_node_error(irb->codegen, source_node, |
| | 5996 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); |
| | 5997 | return false; |
| | 5998 | } else if (search_scope->id == ScopeIdBlock) { |
| | 5999 | ScopeBlock *block_scope = (ScopeBlock *)search_scope; |
| | 6000 | auto entry = block_scope->label_table.maybe_get(label_name); |
| | 6001 | if (entry) { |
| | 6002 | label = entry->value; |
| | 6003 | break; |
| | 6004 | } |
| | 6005 | } else if (search_scope->id == ScopeIdDeferExpr) { |
| | 6006 | add_node_error(irb->codegen, source_node, |
| | 6007 | buf_sprintf("cannot goto out of defer expression")); |
| | 6008 | return false; |
| | 6009 | } |
| | 6010 | search_scope = search_scope->parent; |
| 5990 | } | 6011 | } |
| | 6012 | |
| 5991 | label->used = true; | 6013 | label->used = true; |
| 5992 | | 6014 | |
| 5993 | IrInstruction *is_comptime = ir_build_const_bool(irb, goto_item->scope, source_node, | 6015 | IrInstruction *is_comptime = ir_build_const_bool(irb, goto_item->scope, source_node, |