authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-23 18:19:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-02 13:26:50-07:00
log125b85d7375b96b4847f6ead51c853cdc0567506
tree34a947e48f84ce6455d3ff133828a8e0e5614ce8
parentd84b386f6034278c8a9e8c3d2b0975ac541584aa

move "unreachable code" error from stage1 to stage2

* AstGen: implement "unreachable code" error for blocks. This works at the statement level. * stage1: remove the "unreachable code" error implementation, which means removing the `is_gen` field from IrInstSrc. This is one small step towards a smaller memory footprint for stage1. The benefits won't be realized until a future commit because this flag took advantage of padding. There may be a regression here with "union has no associated enum" error, and there is a regression with the following code: ```zig const a = noreturn; ``` A future commit will address these regressions.

6 files changed, 109 insertions(+), 105 deletions(-)

lib/std/unicode.zig-1
...@@ -247,7 +247,6 @@ pub const Utf8View = struct {...@@ -247,7 +247,6 @@ pub const Utf8View = struct {
247 } else |err| switch (err) {247 } else |err| switch (err) {
248 error.InvalidUtf8 => {248 error.InvalidUtf8 => {
249 @compileError("invalid utf8");249 @compileError("invalid utf8");
250 unreachable;
251 },250 },
252 }251 }
253 }252 }
src/AstGen.zig+49-21
...@@ -1570,7 +1570,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1570,7 +1570,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1570 const defer_scope = scope.cast(Scope.Defer).?;1570 const defer_scope = scope.cast(Scope.Defer).?;
1571 scope = defer_scope.parent;1571 scope = defer_scope.parent;
1572 const expr_node = node_datas[defer_scope.defer_node].rhs;1572 const expr_node = node_datas[defer_scope.defer_node].rhs;
1573 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1573 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1574 },1574 },
1575 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1575 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1576 .top => unreachable,1576 .top => unreachable,
...@@ -1623,7 +1623,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)...@@ -1623,7 +1623,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
1623 const defer_scope = scope.cast(Scope.Defer).?;1623 const defer_scope = scope.cast(Scope.Defer).?;
1624 scope = defer_scope.parent;1624 scope = defer_scope.parent;
1625 const expr_node = node_datas[defer_scope.defer_node].rhs;1625 const expr_node = node_datas[defer_scope.defer_node].rhs;
1626 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1626 _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1627 },1627 },
1628 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1628 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1629 .namespace => break,1629 .namespace => break,
...@@ -1785,8 +1785,23 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1785,8 +1785,23 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1785 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);1785 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
1786 defer block_arena.deinit();1786 defer block_arena.deinit();
17871787
1788 var noreturn_src_node: ast.Node.Index = 0;
1788 var scope = parent_scope;1789 var scope = parent_scope;
1789 for (statements) |statement| {1790 for (statements) |statement| {
1791 if (noreturn_src_node != 0) {
1792 return astgen.failNodeNotes(
1793 statement,
1794 "unreachable code",
1795 .{},
1796 &[_]u32{
1797 try astgen.errNoteNode(
1798 noreturn_src_node,
1799 "control flow is diverted here",
1800 .{},
1801 ),
1802 },
1803 );
1804 }
1790 switch (node_tags[statement]) {1805 switch (node_tags[statement]) {
1791 // zig fmt: off1806 // zig fmt: off
1792 .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)),1807 .global_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.globalVarDecl(statement)),
...@@ -1814,7 +1829,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1814,7 +1829,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1814 .assign_mul => try assignOp(gz, scope, statement, .mul),1829 .assign_mul => try assignOp(gz, scope, statement, .mul),
1815 .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap),1830 .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap),
18161831
1817 else => try unusedResultExpr(gz, scope, statement),1832 else => noreturn_src_node = try unusedResultExpr(gz, scope, statement),
1818 // zig fmt: on1833 // zig fmt: on
1819 }1834 }
1820 }1835 }
...@@ -1823,11 +1838,14 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod...@@ -1823,11 +1838,14 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const ast.Nod
1823 try checkUsed(gz, parent_scope, scope);1838 try checkUsed(gz, parent_scope, scope);
1824}1839}
18251840
1826fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!void {1841/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
1842/// Otherwise returns 0.
1843fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) InnerError!ast.Node.Index {
1827 try emitDbgNode(gz, statement);1844 try emitDbgNode(gz, statement);
1828 // We need to emit an error if the result is not `noreturn` or `void`, but1845 // We need to emit an error if the result is not `noreturn` or `void`, but
1829 // we want to avoid adding the ZIR instruction if possible for performance.1846 // we want to avoid adding the ZIR instruction if possible for performance.
1830 const maybe_unused_result = try expr(gz, scope, .none, statement);1847 const maybe_unused_result = try expr(gz, scope, .none, statement);
1848 var noreturn_src_node: ast.Node.Index = 0;
1831 const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: {1849 const elide_check = if (gz.refToIndex(maybe_unused_result)) |inst| b: {
1832 // Note that this array becomes invalid after appending more items to it1850 // Note that this array becomes invalid after appending more items to it
1833 // in the above while loop.1851 // in the above while loop.
...@@ -2061,15 +2079,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2061,15 +2079,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2061 .extended,2079 .extended,
2062 => break :b false,2080 => break :b false,
20632081
2064 // ZIR instructions that are always either `noreturn` or `void`.2082 // ZIR instructions that are always `noreturn`.
2065 .breakpoint,
2066 .fence,
2067 .dbg_stmt,
2068 .ensure_result_used,
2069 .ensure_result_non_error,
2070 .@"export",
2071 .set_eval_branch_quota,
2072 .ensure_err_payload_void,
2073 .@"break",2083 .@"break",
2074 .break_inline,2084 .break_inline,
2075 .condbr,2085 .condbr,
...@@ -2078,16 +2088,30 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2078,16 +2088,30 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2078 .ret_node,2088 .ret_node,
2079 .ret_coerce,2089 .ret_coerce,
2080 .@"unreachable",2090 .@"unreachable",
2091 .repeat,
2092 .repeat_inline,
2093 .panic,
2094 => {
2095 noreturn_src_node = statement;
2096 break :b true;
2097 },
2098
2099 // ZIR instructions that are always `void`.
2100 .breakpoint,
2101 .fence,
2102 .dbg_stmt,
2103 .ensure_result_used,
2104 .ensure_result_non_error,
2105 .@"export",
2106 .set_eval_branch_quota,
2107 .ensure_err_payload_void,
2081 .store,2108 .store,
2082 .store_node,2109 .store_node,
2083 .store_to_block_ptr,2110 .store_to_block_ptr,
2084 .store_to_inferred_ptr,2111 .store_to_inferred_ptr,
2085 .resolve_inferred_alloc,2112 .resolve_inferred_alloc,
2086 .repeat,
2087 .repeat_inline,
2088 .validate_struct_init_ptr,2113 .validate_struct_init_ptr,
2089 .validate_array_init_ptr,2114 .validate_array_init_ptr,
2090 .panic,
2091 .set_align_stack,2115 .set_align_stack,
2092 .set_cold,2116 .set_cold,
2093 .set_float_mode,2117 .set_float_mode,
...@@ -2097,15 +2121,19 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -2097,15 +2121,19 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
2097 } else switch (maybe_unused_result) {2121 } else switch (maybe_unused_result) {
2098 .none => unreachable,2122 .none => unreachable,
20992123
2100 .void_value,2124 .unreachable_value => b: {
2101 .unreachable_value,2125 noreturn_src_node = statement;
2102 => true,2126 break :b true;
2127 },
2128
2129 .void_value => true,
21032130
2104 else => false,2131 else => false,
2105 };2132 };
2106 if (!elide_check) {2133 if (!elide_check) {
2107 _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement);2134 _ = try gz.addUnNode(.ensure_result_used, maybe_unused_result, statement);
2108 }2135 }
2136 return noreturn_src_node;
2109}2137}
21102138
2111fn genDefers(2139fn genDefers(
...@@ -2132,7 +2160,7 @@ fn genDefers(...@@ -2132,7 +2160,7 @@ fn genDefers(
2132 const prev_in_defer = gz.in_defer;2160 const prev_in_defer = gz.in_defer;
2133 gz.in_defer = true;2161 gz.in_defer = true;
2134 defer gz.in_defer = prev_in_defer;2162 defer gz.in_defer = prev_in_defer;
2135 try unusedResultExpr(gz, defer_scope.parent, expr_node);2163 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2136 },2164 },
2137 .defer_error => {2165 .defer_error => {
2138 const defer_scope = scope.cast(Scope.Defer).?;2166 const defer_scope = scope.cast(Scope.Defer).?;
...@@ -2142,7 +2170,7 @@ fn genDefers(...@@ -2142,7 +2170,7 @@ fn genDefers(
2142 const prev_in_defer = gz.in_defer;2170 const prev_in_defer = gz.in_defer;
2143 gz.in_defer = true;2171 gz.in_defer = true;
2144 defer gz.in_defer = prev_in_defer;2172 defer gz.in_defer = prev_in_defer;
2145 try unusedResultExpr(gz, defer_scope.parent, expr_node);2173 _ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
2146 },2174 },
2147 .namespace => unreachable,2175 .namespace => unreachable,
2148 .top => unreachable,2176 .top => unreachable,
src/stage1/all_types.hpp-3
...@@ -2733,9 +2733,6 @@ struct IrInstSrc {...@@ -2733,9 +2733,6 @@ struct IrInstSrc {
2733 IrInst base;2733 IrInst base;
27342734
2735 IrInstSrcId id;2735 IrInstSrcId id;
2736 // true if this instruction was generated by zig and not from user code
2737 // this matters for the "unreachable code" compile error
2738 bool is_gen;
2739 bool is_noreturn;2736 bool is_noreturn;
27402737
2741 // When analyzing IR, instructions that point to this instruction in the "old ir"2738 // When analyzing IR, instructions that point to this instruction in the "old ir"
src/stage1/astgen.cpp+55-66
...@@ -2557,7 +2557,6 @@ static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode...@@ -2557,7 +2557,6 @@ static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode
2557{2557{
2558 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);2558 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);
2559 instruction->result_loc = result_loc;2559 instruction->result_loc = result_loc;
2560 instruction->base.is_gen = true;
25612560
2562 return &instruction->base;2561 return &instruction->base;
2563}2562}
...@@ -2737,7 +2736,6 @@ static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *s...@@ -2737,7 +2736,6 @@ static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *s
2737 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)2736 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)
2738{2737{
2739 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);2738 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);
2740 instruction->base.is_gen = true;
2741 instruction->align = align;2739 instruction->align = align;
2742 instruction->name_hint = name_hint;2740 instruction->name_hint = name_hint;
2743 instruction->is_comptime = is_comptime;2741 instruction->is_comptime = is_comptime;
...@@ -2752,7 +2750,6 @@ static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *sou...@@ -2752,7 +2750,6 @@ static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *sou
2752 IrInstSrc *value, ResultLoc *result_loc)2750 IrInstSrc *value, ResultLoc *result_loc)
2753{2751{
2754 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);2752 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);
2755 instruction->base.is_gen = true;
2756 instruction->value = value;2753 instruction->value = value;
2757 instruction->result_loc = result_loc;2754 instruction->result_loc = result_loc;
27582755
...@@ -2885,11 +2882,6 @@ static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_s...@@ -2885,11 +2882,6 @@ static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_s
2885 }2882 }
2886}2883}
28872884
2888static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) {
2889 instruction->is_gen = true;
2890 return instruction;
2891}
2892
2893static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {2885static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {
2894 Scope *scope = inner_scope;2886 Scope *scope = inner_scope;
2895 if (is_noreturn != nullptr) *is_noreturn = false;2887 if (is_noreturn != nullptr) *is_noreturn = false;
...@@ -2948,8 +2940,8 @@ static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope...@@ -2948,8 +2940,8 @@ static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope
2948 if (defer_expr_value->is_noreturn) {2940 if (defer_expr_value->is_noreturn) {
2949 if (is_noreturn != nullptr) *is_noreturn = true;2941 if (is_noreturn != nullptr) *is_noreturn = true;
2950 } else {2942 } else {
2951 ir_mark_gen(ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,2943 ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2952 defer_expr_value));2944 defer_expr_value);
2953 }2945 }
2954 scope = scope->parent;2946 scope = scope->parent;
2955 continue;2947 continue;
...@@ -3047,7 +3039,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3047,7 +3039,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3047 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);3039 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);
3048 }3040 }
30493041
3050 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret));3042 ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret);
30513043
3052 size_t defer_counts[2];3044 size_t defer_counts[2];
3053 ir_count_defers(ag, scope, outer_scope, defer_counts);3045 ir_count_defers(ag, scope, outer_scope, defer_counts);
...@@ -3074,7 +3066,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3074,7 +3066,7 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3074 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);3066 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);
3075 }3067 }
30763068
3077 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime));3069 ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime);
3078 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");3070 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");
30793071
3080 ir_set_cursor_at_end_and_append_block(ag, err_block);3072 ir_set_cursor_at_end_and_append_block(ag, err_block);
...@@ -3112,12 +3104,12 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L...@@ -3112,12 +3104,12 @@ static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
3112 } else {3104 } else {
3113 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);3105 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);
3114 }3106 }
3115 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime));3107 ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime);
31163108
3117 ir_set_cursor_at_end_and_append_block(ag, return_block);3109 ir_set_cursor_at_end_and_append_block(ag, return_block);
3118 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);3110 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);
3119 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);3111 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
3120 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr));3112 ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr);
3121 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,3113 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,
3122 SpillIdRetErrCode);3114 SpillIdRetErrCode);
3123 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();3115 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
...@@ -3338,7 +3330,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3338,7 +3330,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3338 child_scope = decl_var_instruction->var->child_scope;3330 child_scope = decl_var_instruction->var->child_scope;
3339 } else if (!is_continuation_unreachable) {3331 } else if (!is_continuation_unreachable) {
3340 // this statement's value must be void3332 // this statement's value must be void
3341 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value));3333 ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value);
3342 }3334 }
3343 }3335 }
33443336
...@@ -3364,7 +3356,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3364,7 +3356,7 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3364 return ir_expr_wrap(ag, parent_scope, phi, result_loc);3356 return ir_expr_wrap(ag, parent_scope, phi, result_loc);
3365 } else {3357 } else {
3366 incoming_blocks.append(ag->current_basic_block);3358 incoming_blocks.append(ag->current_basic_block);
3367 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(ag, parent_scope, block_node));3359 IrInstSrc *else_expr_result = ir_build_const_void(ag, parent_scope, block_node);
33683360
3369 if (scope_block->peer_parent != nullptr) {3361 if (scope_block->peer_parent != nullptr) {
3370 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);3362 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
...@@ -3387,13 +3379,13 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3387,13 +3379,13 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
33873379
3388 IrInstSrc *result;3380 IrInstSrc *result;
3389 if (block_node->data.block.name != nullptr) {3381 if (block_node->data.block.name != nullptr) {
3390 ir_mark_gen(ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));3382 ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime);
3391 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);3383 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3392 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,3384 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3393 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);3385 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3394 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);3386 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);
3395 } else {3387 } else {
3396 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(ag, child_scope, block_node));3388 IrInstSrc *void_inst = ir_build_const_void(ag, child_scope, block_node);
3397 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);3389 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);
3398 }3390 }
3399 if (!is_return_from_fn)3391 if (!is_return_from_fn)
...@@ -3402,14 +3394,14 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b...@@ -3402,14 +3394,14 @@ static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *b
3402 // no need for save_err_ret_addr because this cannot return error3394 // no need for save_err_ret_addr because this cannot return error
3403 // only generate unconditional defers3395 // only generate unconditional defers
34043396
3405 ir_mark_gen(ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr));3397 ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr);
3406 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();3398 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3407 result_loc_ret->base.id = ResultLocIdReturn;3399 result_loc_ret->base.id = ResultLocIdReturn;
3408 ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);3400 ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);
3409 ir_mark_gen(ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base));3401 ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base);
3410 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))3402 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3411 return ag->codegen->invalid_inst_src;3403 return ag->codegen->invalid_inst_src;
3412 return ir_mark_gen(ir_build_return_src(ag, child_scope, result->base.source_node, result));3404 return ir_build_return_src(ag, child_scope, result->base.source_node, result);
3413}3405}
34143406
3415static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {3407static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
...@@ -3628,7 +3620,7 @@ static IrInstSrc *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *...@@ -3628,7 +3620,7 @@ static IrInstSrc *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *
3628 return ag->codegen->invalid_inst_src;3620 return ag->codegen->invalid_inst_src;
3629 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;3621 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;
3630 if (!instr_is_unreachable(null_result))3622 if (!instr_is_unreachable(null_result))
3631 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));3623 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
36323624
3633 ir_set_cursor_at_end_and_append_block(ag, ok_block);3625 ir_set_cursor_at_end_and_append_block(ag, ok_block);
3634 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);3626 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);
...@@ -5395,7 +5387,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n...@@ -5395,7 +5387,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n
5395 return ag->codegen->invalid_inst_src;5387 return ag->codegen->invalid_inst_src;
5396 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;5388 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
5397 if (!instr_is_unreachable(then_expr_result))5389 if (!instr_is_unreachable(then_expr_result))
5398 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));5390 ir_build_br(ag, scope, node, endif_block, is_comptime);
53995391
5400 ir_set_cursor_at_end_and_append_block(ag, else_block);5392 ir_set_cursor_at_end_and_append_block(ag, else_block);
5401 IrInstSrc *else_expr_result;5393 IrInstSrc *else_expr_result;
...@@ -5409,7 +5401,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n...@@ -5409,7 +5401,7 @@ static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *n
5409 }5401 }
5410 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;5402 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
5411 if (!instr_is_unreachable(else_expr_result))5403 if (!instr_is_unreachable(else_expr_result))
5412 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));5404 ir_build_br(ag, scope, node, endif_block, is_comptime);
54135405
5414 ir_set_cursor_at_end_and_append_block(ag, endif_block);5406 ir_set_cursor_at_end_and_append_block(ag, endif_block);
5415 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);5407 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -5954,12 +5946,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -5954,12 +5946,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
5954 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,5946 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,
5955 true, false);5947 true, false);
5956 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;5948 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
5957 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));5949 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
5958 IrInstSrc *cond_br_inst;5950 IrInstSrc *cond_br_inst;
5959 if (!instr_is_unreachable(is_err)) {5951 if (!instr_is_unreachable(is_err)) {
5960 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,5952 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,
5961 else_block, body_block, is_comptime);5953 else_block, body_block, is_comptime);
5962 cond_br_inst->is_gen = true;
5963 } else {5954 } else {
5964 // for the purposes of the source instruction to ir_build_result_peers5955 // for the purposes of the source instruction to ir_build_result_peers
5965 cond_br_inst = ag->current_basic_block->instruction_list.last();5956 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6005,8 +5996,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6005,8 +5996,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6005 }5996 }
60065997
6007 if (!instr_is_unreachable(body_result)) {5998 if (!instr_is_unreachable(body_result)) {
6008 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result));5999 ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result);
6009 ir_mark_gen(ir_build_br(ag, payload_scope, node, continue_block, is_comptime));6000 ir_build_br(ag, payload_scope, node, continue_block, is_comptime);
6010 }6001 }
60116002
6012 if (continue_expr_node) {6003 if (continue_expr_node) {
...@@ -6015,8 +6006,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6015,8 +6006,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6015 if (expr_result == ag->codegen->invalid_inst_src)6006 if (expr_result == ag->codegen->invalid_inst_src)
6016 return expr_result;6007 return expr_result;
6017 if (!instr_is_unreachable(expr_result)) {6008 if (!instr_is_unreachable(expr_result)) {
6018 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result));6009 ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result);
6019 ir_mark_gen(ir_build_br(ag, payload_scope, node, cond_block, is_comptime));6010 ir_build_br(ag, payload_scope, node, cond_block, is_comptime);
6020 }6011 }
6021 }6012 }
60226013
...@@ -6041,7 +6032,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6041,7 +6032,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6041 if (else_result == ag->codegen->invalid_inst_src)6032 if (else_result == ag->codegen->invalid_inst_src)
6042 return else_result;6033 return else_result;
6043 if (!instr_is_unreachable(else_result))6034 if (!instr_is_unreachable(else_result))
6044 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6035 ir_build_br(ag, scope, node, end_block, is_comptime);
6045 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6036 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6046 ir_set_cursor_at_end_and_append_block(ag, end_block);6037 ir_set_cursor_at_end_and_append_block(ag, end_block);
6047 if (else_result) {6038 if (else_result) {
...@@ -6075,12 +6066,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6075,12 +6066,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6075 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);6066 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);
6076 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);6067 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);
6077 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6068 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6078 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));6069 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6079 IrInstSrc *cond_br_inst;6070 IrInstSrc *cond_br_inst;
6080 if (!instr_is_unreachable(is_non_null)) {6071 if (!instr_is_unreachable(is_non_null)) {
6081 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,6072 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,
6082 body_block, else_block, is_comptime);6073 body_block, else_block, is_comptime);
6083 cond_br_inst->is_gen = true;
6084 } else {6074 } else {
6085 // for the purposes of the source instruction to ir_build_result_peers6075 // for the purposes of the source instruction to ir_build_result_peers
6086 cond_br_inst = ag->current_basic_block->instruction_list.last();6076 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6123,8 +6113,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6123,8 +6113,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6123 }6113 }
61246114
6125 if (!instr_is_unreachable(body_result)) {6115 if (!instr_is_unreachable(body_result)) {
6126 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result));6116 ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result);
6127 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));6117 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6128 }6118 }
61296119
6130 if (continue_expr_node) {6120 if (continue_expr_node) {
...@@ -6133,8 +6123,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6133,8 +6123,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6133 if (expr_result == ag->codegen->invalid_inst_src)6123 if (expr_result == ag->codegen->invalid_inst_src)
6134 return expr_result;6124 return expr_result;
6135 if (!instr_is_unreachable(expr_result)) {6125 if (!instr_is_unreachable(expr_result)) {
6136 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result));6126 ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result);
6137 ir_mark_gen(ir_build_br(ag, child_scope, node, cond_block, is_comptime));6127 ir_build_br(ag, child_scope, node, cond_block, is_comptime);
6138 }6128 }
6139 }6129 }
61406130
...@@ -6151,7 +6141,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6151,7 +6141,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6151 if (else_result == ag->codegen->invalid_inst_src)6141 if (else_result == ag->codegen->invalid_inst_src)
6152 return else_result;6142 return else_result;
6153 if (!instr_is_unreachable(else_result))6143 if (!instr_is_unreachable(else_result))
6154 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6144 ir_build_br(ag, scope, node, end_block, is_comptime);
6155 }6145 }
6156 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6146 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6157 ir_set_cursor_at_end_and_append_block(ag, end_block);6147 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6175,12 +6165,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6175,12 +6165,11 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6175 if (cond_val == ag->codegen->invalid_inst_src)6165 if (cond_val == ag->codegen->invalid_inst_src)
6176 return cond_val;6166 return cond_val;
6177 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6167 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6178 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));6168 IrInstSrc *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6179 IrInstSrc *cond_br_inst;6169 IrInstSrc *cond_br_inst;
6180 if (!instr_is_unreachable(cond_val)) {6170 if (!instr_is_unreachable(cond_val)) {
6181 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,6171 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,
6182 body_block, else_block, is_comptime);6172 body_block, else_block, is_comptime);
6183 cond_br_inst->is_gen = true;
6184 } else {6173 } else {
6185 // for the purposes of the source instruction to ir_build_result_peers6174 // for the purposes of the source instruction to ir_build_result_peers
6186 cond_br_inst = ag->current_basic_block->instruction_list.last();6175 cond_br_inst = ag->current_basic_block->instruction_list.last();
...@@ -6219,8 +6208,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6219,8 +6208,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6219 }6208 }
62206209
6221 if (!instr_is_unreachable(body_result)) {6210 if (!instr_is_unreachable(body_result)) {
6222 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result));6211 ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result);
6223 ir_mark_gen(ir_build_br(ag, scope, node, continue_block, is_comptime));6212 ir_build_br(ag, scope, node, continue_block, is_comptime);
6224 }6213 }
62256214
6226 if (continue_expr_node) {6215 if (continue_expr_node) {
...@@ -6229,8 +6218,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6229,8 +6218,8 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6229 if (expr_result == ag->codegen->invalid_inst_src)6218 if (expr_result == ag->codegen->invalid_inst_src)
6230 return expr_result;6219 return expr_result;
6231 if (!instr_is_unreachable(expr_result)) {6220 if (!instr_is_unreachable(expr_result)) {
6232 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result));6221 ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result);
6233 ir_mark_gen(ir_build_br(ag, scope, node, cond_block, is_comptime));6222 ir_build_br(ag, scope, node, cond_block, is_comptime);
6234 }6223 }
6235 }6224 }
62366225
...@@ -6248,7 +6237,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod...@@ -6248,7 +6237,7 @@ static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
6248 if (else_result == ag->codegen->invalid_inst_src)6237 if (else_result == ag->codegen->invalid_inst_src)
6249 return else_result;6238 return else_result;
6250 if (!instr_is_unreachable(else_result))6239 if (!instr_is_unreachable(else_result))
6251 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));6240 ir_build_br(ag, scope, node, end_block, is_comptime);
6252 }6241 }
6253 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6242 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6254 ir_set_cursor_at_end_and_append_block(ag, end_block);6243 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6332,9 +6321,9 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6332,9 +6321,9 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6332 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);6321 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);
6333 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);6322 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
6334 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;6323 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6335 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, parent_scope, node));6324 IrInstSrc *void_else_value = else_node ? nullptr : ir_build_const_void(ag, parent_scope, node);
6336 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(ag, parent_scope, node, cond,6325 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, cond,
6337 body_block, else_block, is_comptime));6326 body_block, else_block, is_comptime);
63386327
6339 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);6328 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);
63406329
...@@ -6377,8 +6366,8 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6377,8 +6366,8 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6377 }6366 }
63786367
6379 if (!instr_is_unreachable(body_result)) {6368 if (!instr_is_unreachable(body_result)) {
6380 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result));6369 ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result);
6381 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));6370 ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6382 }6371 }
63836372
6384 ir_set_cursor_at_end_and_append_block(ag, continue_block);6373 ir_set_cursor_at_end_and_append_block(ag, continue_block);
...@@ -6399,7 +6388,7 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -6399,7 +6388,7 @@ static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode
6399 if (else_result == ag->codegen->invalid_inst_src)6388 if (else_result == ag->codegen->invalid_inst_src)
6400 return else_result;6389 return else_result;
6401 if (!instr_is_unreachable(else_result))6390 if (!instr_is_unreachable(else_result))
6402 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));6391 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
6403 }6392 }
6404 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6393 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6405 ir_set_cursor_at_end_and_append_block(ag, end_block);6394 ir_set_cursor_at_end_and_append_block(ag, end_block);
...@@ -6719,7 +6708,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod...@@ -6719,7 +6708,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod
6719 return then_expr_result;6708 return then_expr_result;
6720 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;6709 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6721 if (!instr_is_unreachable(then_expr_result))6710 if (!instr_is_unreachable(then_expr_result))
6722 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6711 ir_build_br(ag, scope, node, endif_block, is_comptime);
67236712
6724 ir_set_cursor_at_end_and_append_block(ag, else_block);6713 ir_set_cursor_at_end_and_append_block(ag, else_block);
6725 IrInstSrc *else_expr_result;6714 IrInstSrc *else_expr_result;
...@@ -6733,7 +6722,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod...@@ -6733,7 +6722,7 @@ static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNod
6733 }6722 }
6734 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6723 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6735 if (!instr_is_unreachable(else_expr_result))6724 if (!instr_is_unreachable(else_expr_result))
6736 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6725 ir_build_br(ag, scope, node, endif_block, is_comptime);
67376726
6738 ir_set_cursor_at_end_and_append_block(ag, endif_block);6727 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6739 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);6728 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -6802,7 +6791,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -6802,7 +6791,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
6802 return then_expr_result;6791 return then_expr_result;
6803 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;6792 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6804 if (!instr_is_unreachable(then_expr_result))6793 if (!instr_is_unreachable(then_expr_result))
6805 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6794 ir_build_br(ag, scope, node, endif_block, is_comptime);
68066795
6807 ir_set_cursor_at_end_and_append_block(ag, else_block);6796 ir_set_cursor_at_end_and_append_block(ag, else_block);
68086797
...@@ -6831,7 +6820,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -6831,7 +6820,7 @@ static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
6831 }6820 }
6832 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;6821 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6833 if (!instr_is_unreachable(else_expr_result))6822 if (!instr_is_unreachable(else_expr_result))
6834 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));6823 ir_build_br(ag, scope, node, endif_block, is_comptime);
68356824
6836 ir_set_cursor_at_end_and_append_block(ag, endif_block);6825 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6837 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);6826 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
...@@ -6893,7 +6882,7 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw...@@ -6893,7 +6882,7 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw
6893 if (expr_result == ag->codegen->invalid_inst_src)6882 if (expr_result == ag->codegen->invalid_inst_src)
6894 return false;6883 return false;
6895 if (!instr_is_unreachable(expr_result))6884 if (!instr_is_unreachable(expr_result))
6896 ir_mark_gen(ir_build_br(ag, scope, switch_node, end_block, is_comptime));6885 ir_build_br(ag, scope, switch_node, end_block, is_comptime);
6897 incoming_blocks->append(ag->current_basic_block);6886 incoming_blocks->append(ag->current_basic_block);
6898 incoming_values->append(expr_result);6887 incoming_values->append(expr_result);
6899 return true;6888 return true;
...@@ -7008,8 +6997,8 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no...@@ -7008,8 +6997,8 @@ static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *no
70086997
7009 assert(ok_bit);6998 assert(ok_bit);
7010 assert(last_item_node);6999 assert(last_item_node);
7011 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(ag, scope, last_item_node, ok_bit,7000 IrInstSrc *br_inst = ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7012 range_block_yes, range_block_no, is_comptime));7001 range_block_yes, range_block_no, is_comptime);
7013 if (peer_parent->base.source_instruction == nullptr) {7002 if (peer_parent->base.source_instruction == nullptr) {
7014 peer_parent->base.source_instruction = br_inst;7003 peer_parent->base.source_instruction = br_inst;
7015 }7004 }
...@@ -7349,14 +7338,14 @@ static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNo...@@ -7349,14 +7338,14 @@ static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNo
73497338
7350 for (size_t i = 0; i < runtime_scopes.length; i += 1) {7339 for (size_t i = 0; i < runtime_scopes.length; i += 1) {
7351 ScopeRuntime *scope_runtime = runtime_scopes.at(i);7340 ScopeRuntime *scope_runtime = runtime_scopes.at(i);
7352 ir_mark_gen(ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime));7341 ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime);
7353 }7342 }
7354 runtime_scopes.deinit();7343 runtime_scopes.deinit();
73557344
7356 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;7345 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;
7357 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))7346 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))
7358 return ag->codegen->invalid_inst_src;7347 return ag->codegen->invalid_inst_src;
7359 return ir_mark_gen(ir_build_br(ag, continue_scope, node, dest_block, is_comptime));7348 return ir_build_br(ag, continue_scope, node, dest_block, is_comptime);
7360}7349}
73617350
7362static IrInstSrc *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {7351static IrInstSrc *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
...@@ -7482,7 +7471,7 @@ static IrInstSrc *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *n...@@ -7482,7 +7471,7 @@ static IrInstSrc *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *n
7482 return ag->codegen->invalid_inst_src;7471 return ag->codegen->invalid_inst_src;
7483 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;7472 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;
7484 if (!instr_is_unreachable(err_result))7473 if (!instr_is_unreachable(err_result))
7485 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));7474 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
74867475
7487 ir_set_cursor_at_end_and_append_block(ag, ok_block);7476 ir_set_cursor_at_end_and_append_block(ag, ok_block);
7488 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);7477 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);
...@@ -7757,9 +7746,9 @@ static IrInstSrc *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode...@@ -7757,9 +7746,9 @@ static IrInstSrc *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode
7757 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);7746 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);
7758 if (susp_res == ag->codegen->invalid_inst_src)7747 if (susp_res == ag->codegen->invalid_inst_src)
7759 return ag->codegen->invalid_inst_src;7748 return ag->codegen->invalid_inst_src;
7760 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res));7749 ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res);
77617750
7762 return ir_mark_gen(ir_build_suspend_finish_src(ag, parent_scope, node, begin));7751 return ir_build_suspend_finish_src(ag, parent_scope, node, begin);
7763}7752}
77647753
7765static IrInstSrc *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,7754static IrInstSrc *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,
...@@ -8073,13 +8062,13 @@ bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *sta...@@ -8073,13 +8062,13 @@ bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *sta
8073 }8062 }
80748063
8075 if (!instr_is_unreachable(result)) {8064 if (!instr_is_unreachable(result)) {
8076 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr));8065 ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr);
8077 // no need for save_err_ret_addr because this cannot return error8066 // no need for save_err_ret_addr because this cannot return error
8078 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();8067 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
8079 result_loc_ret->base.id = ResultLocIdReturn;8068 result_loc_ret->base.id = ResultLocIdReturn;
8080 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);8069 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
8081 ir_mark_gen(ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base));8070 ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base);
8082 ir_mark_gen(ir_build_return_src(ag, scope, result->base.source_node, result));8071 ir_build_return_src(ag, scope, result->base.source_node, result);
8083 }8072 }
80848073
8085 return true;8074 return true;
src/stage1/ir.cpp+3-13
...@@ -5407,16 +5407,6 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -5407,16 +5407,6 @@ static void ir_finish_bb(IrAnalyze *ira) {
5407 ira->new_irb.current_basic_block->debug_id);5407 ira->new_irb.current_basic_block->debug_id);
5408 }5408 }
5409 }5409 }
5410 ira->instruction_index += 1;
5411 while (ira->instruction_index < ira->zir_current_basic_block->instruction_list.length) {
5412 IrInstSrc *next_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
5413 if (!next_instruction->is_gen) {
5414 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code"));
5415 break;
5416 }
5417 ira->instruction_index += 1;
5418 }
5419
5420 ir_start_next_bb(ira);5410 ir_start_next_bb(ira);
5421}5411}
54225412
...@@ -15934,7 +15924,7 @@ static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopC...@@ -15934,7 +15924,7 @@ static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopC
15934 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op);15924 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op);
15935}15925}
1593615926
15937static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) {15927static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value) {
15938 if (type_is_invalid(value->value->type))15928 if (type_is_invalid(value->value->type))
15939 return ira->codegen->invalid_inst_gen;15929 return ira->codegen->invalid_inst_gen;
1594015930
...@@ -15943,7 +15933,7 @@ static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrI...@@ -15943,7 +15933,7 @@ static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrI
15943 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name)));15933 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name)));
15944 return ira->codegen->invalid_inst_gen;15934 return ira->codegen->invalid_inst_gen;
15945 }15935 }
15946 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) {15936 if (!value->value->type->data.unionation.have_explicit_tag_type) {
15947 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));15937 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum"));
15948 if (value->value->type->data.unionation.decl_node != nullptr) {15938 if (value->value->type->data.unionation.decl_node != nullptr) {
15949 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node,15939 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node,
...@@ -16906,7 +16896,7 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc...@@ -16906,7 +16896,7 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
16906 }16896 }
1690716897
16908 if (target_type->id == ZigTypeIdUnion) {16898 if (target_type->id == ZigTypeIdUnion) {
16909 target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen);16899 target = ir_analyze_union_tag(ira, &instruction->base.base, target);
16910 if (type_is_invalid(target->value->type))16900 if (type_is_invalid(target->value->type))
16911 return ira->codegen->invalid_inst_gen;16901 return ira->codegen->invalid_inst_gen;
16912 target_type = target->value->type;16902 target_type = target->value->type;
test/compile_errors.zig+2-1
...@@ -4762,7 +4762,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4762,7 +4762,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4762 \\4762 \\
4763 \\fn b() void {}4763 \\fn b() void {}
4764 , &[_][]const u8{4764 , &[_][]const u8{
4765 "tmp.zig:3:5: error: unreachable code",4765 "tmp.zig:3:6: error: unreachable code",
4766 "tmp.zig:2:5: note: control flow is diverted here",
4766 });4767 });
47674768
4768 cases.add("bad import",4769 cases.add("bad import",