authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-04-15 20:43:07+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-04-15 22:33:07+03:00
log1c4c826a505b3f4863a0125f7915273ad2e7c1c0
treed678ced032ae0205a2b4fca08e372dde5b5ee6a3
parent7be62f695ffb468e19241a564d544d6a0adab829

AstGen: fix defer generation in `breakExpr`


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

src/AstGen.zig+13-14
......@@ -1807,6 +1807,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
18071807 .@"break";
18081808
18091809 if (rhs == 0) {
1810 try genDefers(parent_gz, scope, parent_scope, .normal_only);
1811
18101812 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
18111813 return Zir.Inst.Ref.unreachable_value;
18121814 }
......@@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
18191821 const prev_rvalue_noresult = parent_gz.rvalue_noresult;
18201822 parent_gz.rvalue_noresult = .none;
18211823 const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node);
1824 const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
18221825 parent_gz.rvalue_noresult = prev_rvalue_noresult;
18231826
1827 try genDefers(parent_gz, scope, parent_scope, .normal_only);
1828
18241829 switch (block_gz.break_result_loc) {
18251830 .block_ptr => {
18261831 const br = try parent_gz.addBreak(break_tag, block_inst, operand);
1827 try block_gz.labeled_breaks.append(astgen.gpa, br);
1832 try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index });
18281833 },
18291834 .ptr => {
18301835 // In this case we don't have any mechanism to intercept it;
......@@ -1843,13 +1848,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
18431848 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
18441849 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
18451850 .namespace => break,
1846 .defer_normal => {
1847 const defer_scope = scope.cast(Scope.Defer).?;
1848 scope = defer_scope.parent;
1849 const expr_node = node_datas[defer_scope.defer_node].rhs;
1850 try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node);
1851 },
1852 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1851 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
18531852 .top => unreachable,
18541853 }
18551854 }
......@@ -2030,7 +2029,7 @@ fn labeledBlockExpr(
20302029 // The code took advantage of the result location as a pointer.
20312030 // Turn the break instruction operands into void.
20322031 for (block_scope.labeled_breaks.items) |br| {
2033 zir_datas[br].@"break".operand = .void_value;
2032 zir_datas[br.br].@"break".operand = .void_value;
20342033 }
20352034 try block_scope.setBlockBody(block_inst);
20362035
......@@ -2047,17 +2046,17 @@ fn labeledBlockExpr(
20472046 for (block_scope.labeled_breaks.items) |br| {
20482047 // We expect the `store_to_block_ptr` to be created between 1-3 instructions
20492048 // prior to the break.
2050 var search_index = br -| 3;
2051 while (search_index < br) : (search_index += 1) {
2049 var search_index = br.search -| 3;
2050 while (search_index < br.search) : (search_index += 1) {
20522051 if (zir_tags[search_index] == .store_to_block_ptr and
20532052 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)
20542053 {
20552054 zir_tags[search_index] = .as;
20562055 zir_datas[search_index].bin = .{
20572056 .lhs = block_scope.rl_ty_inst,
2058 .rhs = zir_datas[br].@"break".operand,
2057 .rhs = zir_datas[br.br].@"break".operand,
20592058 };
2060 zir_datas[br].@"break".operand = indexToRef(search_index);
2059 zir_datas[br.br].@"break".operand = indexToRef(search_index);
20612060 break;
20622061 }
20632062 } else unreachable;
......@@ -9719,7 +9718,7 @@ const GenZir = struct {
97199718 break_count: usize = 0,
97209719 /// Tracks `break :foo bar` instructions so they can possibly be elided later if
97219720 /// the labeled block ends up not needing a result location pointer.
9722 labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{},
9721 labeled_breaks: ArrayListUnmanaged(struct { br: Zir.Inst.Index, search: Zir.Inst.Index }) = .{},
97239722
97249723 suspend_node: Ast.Node.Index = 0,
97259724 nosuspend_node: Ast.Node.Index = 0,