authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-04-19 17:20:25+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-20 22:39:34-04:00
logaca6b7018443bfc012f39be486f848d6e62c532c
tree2951e80d75b33e4409010ad1f803ddbbc300bdca
parent32e5248820a71895ed2833bdc1f91826c7a4dba7

stage1: Handle errors when generating block IR

Closes #5005

3 files changed, 19 insertions(+), 4 deletions(-)

src/analyze.cpp+3-1
...@@ -4610,7 +4610,9 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour...@@ -4610,7 +4610,9 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour
4610 return false;4610 return false;
4611 } else if (infer_fn->anal_state == FnAnalStateReady) {4611 } else if (infer_fn->anal_state == FnAnalStateReady) {
4612 analyze_fn_body(g, infer_fn);4612 analyze_fn_body(g, infer_fn);
4613 if (err_set_type->data.error_set.incomplete) {4613 if (infer_fn->anal_state == FnAnalStateInvalid ||
4614 err_set_type->data.error_set.incomplete)
4615 {
4614 assert(g->errors.length != 0);4616 assert(g->errors.length != 0);
4615 return false;4617 return false;
4616 }4618 }
src/ast_render.cpp+1-1
...@@ -571,7 +571,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -571,7 +571,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
571 {571 {
572 const char *defer_str = defer_string(node->data.defer.kind);572 const char *defer_str = defer_string(node->data.defer.kind);
573 fprintf(ar->f, "%s ", defer_str);573 fprintf(ar->f, "%s ", defer_str);
574 render_node_grouped(ar, node->data.return_expr.expr);574 render_node_grouped(ar, node->data.defer.expr);
575 break;575 break;
576 }576 }
577 case NodeTypeVariableDeclaration:577 case NodeTypeVariableDeclaration:
src/ir.cpp+15-2
...@@ -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 }
54095409
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);
54145415
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 it5426 // 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 with5429 // 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 scope5432 // 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 scope5436 // 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 void5440 // 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 }
54365444
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 }
99109923