aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-02-09 17:19:28 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-02-09 17:19:28 -0500
commit04ee3b01a159a25894f93d8448fb766ae545ab53 (patch)
tree5f728a0597fa9c6d5203d7a7f63be466780c43f1 /src/ir.cpp
parent5b10d9f917ac773ca7c842d74ef44c861484670f (diff)
downloadzig-04ee3b01a159a25894f93d8448fb766ae545ab53.tar.gz
zig-04ee3b01a159a25894f93d8448fb766ae545ab53.zip
fix defer interfering with return value spill
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 2f0c52347c..82fce395b0 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5252,6 +5252,7 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
return irb->codegen->invalid_inst_src;
} else {
return_value = ir_build_const_void(irb, scope, node);
+ ir_build_end_expr(irb, scope, node, return_value, &result_loc_ret->base);
}
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret));
@@ -5262,7 +5263,7 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
if (!have_err_defers && !irb->codegen->have_err_ret_tracing) {
// only generate unconditional defers
ir_gen_defers_for_block(irb, scope, outer_scope, false);
- IrInstSrc *result = ir_build_return_src(irb, scope, node, return_value);
+ IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr);
result_loc_ret->base.source_instruction = result;
return result;
}
@@ -5271,10 +5272,6 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr");
IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk");
- if (!have_err_defers) {
- ir_gen_defers_for_block(irb, scope, outer_scope, false);
- }
-
IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true);
IrInstSrc *is_comptime;
@@ -5288,22 +5285,18 @@ static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node,
IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt");
ir_set_cursor_at_end_and_append_block(irb, err_block);
- if (have_err_defers) {
- ir_gen_defers_for_block(irb, scope, outer_scope, true);
- }
+ ir_gen_defers_for_block(irb, scope, outer_scope, true);
if (irb->codegen->have_err_ret_tracing && !should_inline) {
ir_build_save_err_ret_addr_src(irb, scope, node);
}
ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, ok_block);
- if (have_err_defers) {
- ir_gen_defers_for_block(irb, scope, outer_scope, false);
- }
+ ir_gen_defers_for_block(irb, scope, outer_scope, false);
ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
- IrInstSrc *result = ir_build_return_src(irb, scope, node, return_value);
+ IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr);
result_loc_ret->base.source_instruction = result;
return result;
}
@@ -9622,7 +9615,10 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
}
- IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
+ ScopeExpr *spill_scope = create_expr_scope(irb->codegen, op1_node, parent_scope);
+ spill_scope->spill_harder = true;
+
+ IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, &spill_scope->base, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_inst_src)
return irb->codegen->invalid_inst_src;
@@ -9644,7 +9640,7 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
is_comptime);
ir_set_cursor_at_end_and_append_block(irb, err_block);
- Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, parent_scope, is_comptime);
+ Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime);
Scope *err_scope;
if (var_node) {
assert(var_node->type == NodeTypeSymbol);
@@ -15497,6 +15493,12 @@ static IrInstGen *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira
}
static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn *instruction) {
+ if (instruction->operand == nullptr) {
+ // result location mechanism took care of it.
+ IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr);
+ return ir_finish_anal(ira, result);
+ }
+
IrInstGen *operand = instruction->operand->child;
if (type_is_invalid(operand->value->type))
return ir_unreach_error(ira);
@@ -29551,8 +29553,13 @@ static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSp
if (!type_has_bits(operand->value->type))
return ir_const_void(ira, &instruction->base.base);
- ir_assert(instruction->spill_id == SpillIdRetErrCode, &instruction->base.base);
- ira->new_irb.exec->need_err_code_spill = true;
+ switch (instruction->spill_id) {
+ case SpillIdInvalid:
+ zig_unreachable();
+ case SpillIdRetErrCode:
+ ira->new_irb.exec->need_err_code_spill = true;
+ break;
+ }
return ir_build_spill_begin_gen(ira, &instruction->base.base, operand, instruction->spill_id);
}
@@ -29562,8 +29569,12 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil
if (type_is_invalid(operand->value->type))
return ira->codegen->invalid_inst_gen;
- if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || !type_has_bits(operand->value->type))
+ if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) ||
+ !type_has_bits(operand->value->type) ||
+ instr_is_comptime(operand))
+ {
return operand;
+ }
ir_assert(instruction->begin->base.child->id == IrInstGenIdSpillBegin, &instruction->base.base);
IrInstGenSpillBegin *begin = reinterpret_cast<IrInstGenSpillBegin *>(instruction->begin->base.child);