From 2ccdaee101e6e0d8cb4a4560b032ff9bab4b5f58 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 31 Dec 2016 01:58:37 -0500 Subject: [PATCH] IR: add error for goto jumping over variable declaration --- src/codegen.cpp | 2 ++ src/ir.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 7884f52b5..2a77675a7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3008,6 +3008,8 @@ static void do_code_gen(CodeGen *g) { } if (ir_get_var_is_comptime(var)) continue; + if (type_requires_comptime(var->value.type)) + continue; if (var->src_arg_index == SIZE_MAX) { var->value_ref = LLVMBuildAlloca(g->builder, var->value.type->type_ref, buf_ptr(&var->name)); diff --git a/src/ir.cpp b/src/ir.cpp index 33bfb0fe9..aba7aff3b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2738,12 +2738,14 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco } } -static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, +static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers, bool gen_maybe_defers) { Scope *scope = inner_scope; while (scope != outer_scope) { - assert(scope); + if (!scope) + return false; + if (scope->id == ScopeIdDefer) { AstNode *defer_node = scope->source_node; assert(defer_node->type == NodeTypeDefer); @@ -2759,6 +2761,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o } scope = scope->parent; } + return true; } static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { @@ -5105,7 +5108,11 @@ static bool ir_goto_pass2(IrBuilder *irb) { IrInstruction *is_comptime = ir_build_const_bool(irb, goto_item->scope, source_node, ir_should_inline(irb) || source_node->data.goto_expr.is_inline); - ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false, false); + if (!ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false, false)) { + add_node_error(irb->codegen, source_node, + buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); + return false; + } ir_build_br(irb, goto_item->scope, source_node, label->bb, is_comptime); }