mirror of
https://github.com/ziglang/zig.git
synced 2025-12-18 20:23:07 +00:00
refactor ir_gen_block to make different return paths more clear
This commit is contained in:
parent
14dfbd6ad3
commit
2ed47070ef
23
src/ir.cpp
23
src/ir.cpp
@ -3350,6 +3350,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_continuation_unreachable = false;
|
bool is_continuation_unreachable = false;
|
||||||
|
IrInstruction *noreturn_return_value = nullptr;
|
||||||
IrInstruction *return_value = nullptr;
|
IrInstruction *return_value = nullptr;
|
||||||
for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
|
for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
|
||||||
AstNode *statement_node = block_node->data.block.statements.at(i);
|
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
|
|||||||
|
|
||||||
// a label is an entry point
|
// a label is an entry point
|
||||||
is_continuation_unreachable = false;
|
is_continuation_unreachable = false;
|
||||||
return_value = nullptr;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope);
|
IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope);
|
||||||
is_continuation_unreachable = instr_is_unreachable(statement_value);
|
is_continuation_unreachable = instr_is_unreachable(statement_value);
|
||||||
if (is_continuation_unreachable)
|
if (is_continuation_unreachable) {
|
||||||
return_value = statement_value;
|
// keep the last noreturn statement value around in case we need to return it
|
||||||
else
|
noreturn_return_value = statement_value;
|
||||||
return_value = nullptr;
|
}
|
||||||
if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {
|
if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {
|
||||||
// defer starts a new scope
|
// defer starts a new scope
|
||||||
child_scope = statement_node->data.defer.child_scope;
|
child_scope = statement_node->data.defer.child_scope;
|
||||||
@ -3420,18 +3420,23 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_continuation_unreachable) {
|
if (is_continuation_unreachable) {
|
||||||
|
assert(noreturn_return_value != nullptr);
|
||||||
|
return noreturn_return_value;
|
||||||
|
}
|
||||||
// control flow falls out of block
|
// control flow falls out of block
|
||||||
|
|
||||||
if (!block_node->data.block.last_statement_is_result_expression) {
|
if (block_node->data.block.last_statement_is_result_expression) {
|
||||||
|
// return value was determined by the last statement
|
||||||
|
assert(return_value != nullptr);
|
||||||
|
} else {
|
||||||
|
// return value is implicitly void
|
||||||
assert(return_value == nullptr);
|
assert(return_value == nullptr);
|
||||||
return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
|
return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
|
ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
|
||||||
}
|
|
||||||
|
|
||||||
assert(return_value != nullptr);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user