| ... | @@ -5408,11 +5408,19 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * | ... | @@ -5408,11 +5408,19 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * |
| 5408 | } | 5408 | } |
| 5409 | | 5409 | |
| 5410 | bool is_continuation_unreachable = false; | 5410 | bool is_continuation_unreachable = false; |
| | 5411 | bool found_invalid_inst = false; |
| 5411 | IrInstSrc *noreturn_return_value = nullptr; | 5412 | IrInstSrc *noreturn_return_value = nullptr; |
| 5412 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { | 5413 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 5413 | AstNode *statement_node = block_node->data.block.statements.at(i); | 5414 | AstNode *statement_node = block_node->data.block.statements.at(i); |
| 5414 | | 5415 | |
| 5415 | IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); | 5416 | IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); |
| | 5417 | if (statement_value == irb->codegen->invalid_inst_src) { |
| | 5418 | // keep generating all the elements of the block in case of error, |
| | 5419 | // we want to collect other compile errors |
| | 5420 | found_invalid_inst = true; |
| | 5421 | continue; |
| | 5422 | } |
| | 5423 | |
| 5416 | is_continuation_unreachable = instr_is_unreachable(statement_value); | 5424 | is_continuation_unreachable = instr_is_unreachable(statement_value); |
| 5417 | if (is_continuation_unreachable) { | 5425 | if (is_continuation_unreachable) { |
| 5418 | // keep the last noreturn statement value around in case we need to return it | 5426 | // keep the last noreturn statement value around in case we need to return it |
| ... | @@ -5420,7 +5428,7 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * | ... | @@ -5420,7 +5428,7 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * |
| 5420 | } | 5428 | } |
| 5421 | // This logic must be kept in sync with | 5429 | // This logic must be kept in sync with |
| 5422 | // [STMT_EXPR_TEST_THING] <--- (search this token) | 5430 | // [STMT_EXPR_TEST_THING] <--- (search this token) |
| 5423 | if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_inst_src) { | 5431 | if (statement_node->type == NodeTypeDefer) { |
| 5424 | // defer starts a new scope | 5432 | // defer starts a new scope |
| 5425 | child_scope = statement_node->data.defer.child_scope; | 5433 | child_scope = statement_node->data.defer.child_scope; |
| 5426 | assert(child_scope); | 5434 | assert(child_scope); |
| ... | @@ -5428,12 +5436,15 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * | ... | @@ -5428,12 +5436,15 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * |
| 5428 | // variable declarations start a new scope | 5436 | // variable declarations start a new scope |
| 5429 | IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; | 5437 | IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; |
| 5430 | child_scope = decl_var_instruction->var->child_scope; | 5438 | child_scope = decl_var_instruction->var->child_scope; |
| 5431 | } else if (statement_value != irb->codegen->invalid_inst_src && !is_continuation_unreachable) { | 5439 | } else if (!is_continuation_unreachable) { |
| 5432 | // this statement's value must be void | 5440 | // this statement's value must be void |
| 5433 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); | 5441 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); |
| 5434 | } | 5442 | } |
| 5435 | } | 5443 | } |
| 5436 | | 5444 | |
| | 5445 | if (found_invalid_inst) |
| | 5446 | return irb->codegen->invalid_inst_src; |
| | 5447 | |
| 5437 | if (is_continuation_unreachable) { | 5448 | if (is_continuation_unreachable) { |
| 5438 | assert(noreturn_return_value != nullptr); | 5449 | assert(noreturn_return_value != nullptr); |
| 5439 | if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { | 5450 | if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { |
| ... | @@ -9905,6 +9916,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode | ... | @@ -9905,6 +9916,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode |
| 9905 | ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); | 9916 | ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); |
| 9906 | Scope *child_scope = &suspend_scope->base; | 9917 | Scope *child_scope = &suspend_scope->base; |
| 9907 | IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); | 9918 | IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); |
| | 9919 | if (susp_res == irb->codegen->invalid_inst_src) |
| | 9920 | return irb->codegen->invalid_inst_src; |
| 9908 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); | 9921 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); |
| 9909 | } | 9922 | } |
| 9910 | | 9923 | |