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...@@ -1807,6 +1807,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1807 .@"break";1807 .@"break";
18081808
1809 if (rhs == 0) {1809 if (rhs == 0) {
1810 try genDefers(parent_gz, scope, parent_scope, .normal_only);
1811
1810 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);1812 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
1811 return Zir.Inst.Ref.unreachable_value;1813 return Zir.Inst.Ref.unreachable_value;
1812 }1814 }
...@@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1819 const prev_rvalue_noresult = parent_gz.rvalue_noresult;1821 const prev_rvalue_noresult = parent_gz.rvalue_noresult;
1820 parent_gz.rvalue_noresult = .none;1822 parent_gz.rvalue_noresult = .none;
1821 const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node);1823 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);
1822 parent_gz.rvalue_noresult = prev_rvalue_noresult;1825 parent_gz.rvalue_noresult = prev_rvalue_noresult;
18231826
1827 try genDefers(parent_gz, scope, parent_scope, .normal_only);
1828
1824 switch (block_gz.break_result_loc) {1829 switch (block_gz.break_result_loc) {
1825 .block_ptr => {1830 .block_ptr => {
1826 const br = try parent_gz.addBreak(break_tag, block_inst, operand);1831 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 });
1828 },1833 },
1829 .ptr => {1834 .ptr => {
1830 // In this case we don't have any mechanism to intercept it;1835 // 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...@@ -1843,13 +1848,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1843 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,1848 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
1844 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,1849 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
1845 .namespace => break,1850 .namespace => break,
1846 .defer_normal => {1851 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
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,
1853 .top => unreachable,1852 .top => unreachable,
1854 }1853 }
1855 }1854 }
...@@ -2030,7 +2029,7 @@ fn labeledBlockExpr(...@@ -2030,7 +2029,7 @@ fn labeledBlockExpr(
2030 // The code took advantage of the result location as a pointer.2029 // The code took advantage of the result location as a pointer.
2031 // Turn the break instruction operands into void.2030 // Turn the break instruction operands into void.
2032 for (block_scope.labeled_breaks.items) |br| {2031 for (block_scope.labeled_breaks.items) |br| {
2033 zir_datas[br].@"break".operand = .void_value;2032 zir_datas[br.br].@"break".operand = .void_value;
2034 }2033 }
2035 try block_scope.setBlockBody(block_inst);2034 try block_scope.setBlockBody(block_inst);
20362035
...@@ -2047,17 +2046,17 @@ fn labeledBlockExpr(...@@ -2047,17 +2046,17 @@ fn labeledBlockExpr(
2047 for (block_scope.labeled_breaks.items) |br| {2046 for (block_scope.labeled_breaks.items) |br| {
2048 // We expect the `store_to_block_ptr` to be created between 1-3 instructions2047 // We expect the `store_to_block_ptr` to be created between 1-3 instructions
2049 // prior to the break.2048 // prior to the break.
2050 var search_index = br -| 3;2049 var search_index = br.search -| 3;
2051 while (search_index < br) : (search_index += 1) {2050 while (search_index < br.search) : (search_index += 1) {
2052 if (zir_tags[search_index] == .store_to_block_ptr and2051 if (zir_tags[search_index] == .store_to_block_ptr and
2053 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)2052 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)
2054 {2053 {
2055 zir_tags[search_index] = .as;2054 zir_tags[search_index] = .as;
2056 zir_datas[search_index].bin = .{2055 zir_datas[search_index].bin = .{
2057 .lhs = block_scope.rl_ty_inst,2056 .lhs = block_scope.rl_ty_inst,
2058 .rhs = zir_datas[br].@"break".operand,2057 .rhs = zir_datas[br.br].@"break".operand,
2059 };2058 };
2060 zir_datas[br].@"break".operand = indexToRef(search_index);2059 zir_datas[br.br].@"break".operand = indexToRef(search_index);
2061 break;2060 break;
2062 }2061 }
2063 } else unreachable;2062 } else unreachable;
...@@ -9719,7 +9718,7 @@ const GenZir = struct {...@@ -9719,7 +9718,7 @@ const GenZir = struct {
9719 break_count: usize = 0,9718 break_count: usize = 0,
9720 /// Tracks `break :foo bar` instructions so they can possibly be elided later if9719 /// Tracks `break :foo bar` instructions so they can possibly be elided later if
9721 /// the labeled block ends up not needing a result location pointer.9720 /// 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
9724 suspend_node: Ast.Node.Index = 0,9723 suspend_node: Ast.Node.Index = 0,
9725 nosuspend_node: Ast.Node.Index = 0,9724 nosuspend_node: Ast.Node.Index = 0,