authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-04-23 09:04:15-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-04-23 09:04:15-07:00
log2ed47070efa5933365da724e79f6ed87d603ee27
tree13023433b288288179cbd8e12275f2e7afb6ebbf
parent14dfbd6ad39dadbd8505957b031f67bcd1a7b8a4

refactor ir_gen_block to make different return paths more clear


1 files changed, 19 insertions(+), 14 deletions(-)

src/ir.cpp+19-14
......@@ -3350,6 +3350,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
33503350 }
33513351
33523352 bool is_continuation_unreachable = false;
3353 IrInstruction *noreturn_return_value = nullptr;
33533354 IrInstruction *return_value = nullptr;
33543355 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
33553356 AstNode *statement_node = block_node->data.block.statements.at(i);
......@@ -3383,16 +3384,15 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
33833384
33843385 // a label is an entry point
33853386 is_continuation_unreachable = false;
3386 return_value = nullptr;
33873387 continue;
33883388 }
33893389
33903390 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope);
33913391 is_continuation_unreachable = instr_is_unreachable(statement_value);
3392 if (is_continuation_unreachable)
3393 return_value = statement_value;
3394 else
3395 return_value = nullptr;
3392 if (is_continuation_unreachable) {
3393 // keep the last noreturn statement value around in case we need to return it
3394 noreturn_return_value = statement_value;
3395 }
33963396 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {
33973397 // defer starts a new scope
33983398 child_scope = statement_node->data.defer.child_scope;
......@@ -3420,18 +3420,23 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
34203420 }
34213421 }
34223422
3423 if (!is_continuation_unreachable) {
3424 // control flow falls out of block
3425
3426 if (!block_node->data.block.last_statement_is_result_expression) {
3427 assert(return_value == nullptr);
3428 return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
3429 }
3423 if (is_continuation_unreachable) {
3424 assert(noreturn_return_value != nullptr);
3425 return noreturn_return_value;
3426 }
3427 // control flow falls out of block
34303428
3431 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
3429 if (block_node->data.block.last_statement_is_result_expression) {
3430 // return value was determined by the last statement
3431 assert(return_value != nullptr);
3432 } else {
3433 // return value is implicitly void
3434 assert(return_value == nullptr);
3435 return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
34323436 }
34333437
3434 assert(return_value != nullptr);
3438 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
3439
34353440 return return_value;
34363441}
34373442