aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-09-07 17:37:17 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-09-07 17:37:17 -0400
commit229323e13a074e94ef8a58409c81cfd9ac807dd8 (patch)
tree07e39a8d4656fcd930b381466d07e67bb8bb837b /src/ir.cpp
parentd3cf040c900c14feec427f3835f247b6a4c616bb (diff)
downloadzig-229323e13a074e94ef8a58409c81cfd9ac807dd8.tar.gz
zig-229323e13a074e94ef8a58409c81cfd9ac807dd8.zip
fix suspensions inside for loops generating invalid LLVM IR
closes #3076
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 1a0aad36e9..6b71fa8d17 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -6474,6 +6474,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node,
ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);
+ ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope);
+
AstNode *index_var_source_node;
ZigVar *index_var;
const char *index_var_name;
@@ -6504,11 +6506,11 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
Buf *len_field_name = buf_create_from_str("len");
IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false);
- IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref);
+ IrInstruction *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref);
ir_build_br(irb, parent_scope, node, cond_block, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, cond_block);
- IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr);
+ IrInstruction *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr);
IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
IrBasicBlock *after_cond_block = irb->current_basic_block;
IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
@@ -6518,7 +6520,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, body_block);
- IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false,
+ Scope *elem_ptr_scope = node->data.for_expr.elem_is_ptr ? parent_scope : &spill_scope->base;
+ IrInstruction *elem_ptr = ir_build_elem_ptr(irb, elem_ptr_scope, node, array_val_ptr, index_val, false,
PtrLenSingle, nullptr);
// TODO make it an error to write to element variable or i variable.
Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
@@ -6526,7 +6529,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
Scope *child_scope = elem_var->child_scope;
IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ?
- ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr;
+ ir_build_ref(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr;
ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr);
ZigList<IrInstruction *> incoming_values = {0};
@@ -6539,6 +6542,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
loop_scope->incoming_values = &incoming_values;
loop_scope->lval = LValNone;
loop_scope->peer_parent = peer_parent;
+ loop_scope->spill_scope = spill_scope;
// Note the body block of the loop is not the place that lval and result_loc are used -
// it's actually in break statements, handled similarly to return statements.
@@ -8166,7 +8170,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
{
child_scope = scope;
} else {
- child_scope = create_expr_scope(irb->codegen, node, scope);
+ child_scope = &create_expr_scope(irb->codegen, node, scope)->base;
}
IrInstruction *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc);
if (result == irb->codegen->invalid_instruction) {