authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-12 20:41:25+03:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-10-21 10:43:42-07:00
log5316a00a188955d60cc38d56def51b8605181225
treed26f110e2472fe5ea0853056ab86924f17e046c0
parent28054d96f0ed5280660811612732cb000f9c09e8

stage2: properly reset error return trace index


4 files changed, 111 insertions(+), 5 deletions(-)

src/AstGen.zig+39-2
...@@ -2471,6 +2471,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2471,6 +2471,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2471 .try_ptr,2471 .try_ptr,
2472 //.try_inline,2472 //.try_inline,
2473 //.try_ptr_inline,2473 //.try_ptr_inline,
2474 .save_err_ret_index,
2474 => break :b false,2475 => break :b false,
24752476
2476 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {2477 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
...@@ -2533,6 +2534,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2533,6 +2534,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2533 .validate_array_init_ty,2534 .validate_array_init_ty,
2534 .validate_struct_init_ty,2535 .validate_struct_init_ty,
2535 .validate_deref,2536 .validate_deref,
2537 .restore_err_ret_index,
2536 => break :b true,2538 => break :b true,
25372539
2538 .@"defer" => unreachable,2540 .@"defer" => unreachable,
...@@ -5152,10 +5154,16 @@ fn orelseCatchExpr(...@@ -5152,10 +5154,16 @@ fn orelseCatchExpr(
5152 const astgen = parent_gz.astgen;5154 const astgen = parent_gz.astgen;
5153 const tree = astgen.tree;5155 const tree = astgen.tree;
51545156
5157 const do_err_trace = astgen.fn_block != null and (cond_op == .is_non_err or cond_op == .is_non_err_ptr);
5158
5155 var block_scope = parent_gz.makeSubBlock(scope);5159 var block_scope = parent_gz.makeSubBlock(scope);
5156 block_scope.setBreakResultLoc(rl);5160 block_scope.setBreakResultLoc(rl);
5157 defer block_scope.unstack();5161 defer block_scope.unstack();
51585162
5163 if (do_err_trace) {
5164 block_scope.saved_err_trace_index = try parent_gz.addNode(.save_err_ret_index, node);
5165 }
5166
5159 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {5167 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
5160 .ref => .ref,5168 .ref => .ref,
5161 else => .none,5169 else => .none,
...@@ -5220,7 +5228,7 @@ fn orelseCatchExpr(...@@ -5220,7 +5228,7 @@ fn orelseCatchExpr(
5220 // instructions or not.5228 // instructions or not.
52215229
5222 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";5230 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5223 return finishThenElseBlock(5231 const result = try finishThenElseBlock(
5224 parent_gz,5232 parent_gz,
5225 rl,5233 rl,
5226 node,5234 node,
...@@ -5235,6 +5243,16 @@ fn orelseCatchExpr(...@@ -5235,6 +5243,16 @@ fn orelseCatchExpr(
5235 block,5243 block,
5236 break_tag,5244 break_tag,
5237 );5245 );
5246 if (do_err_trace) {
5247 _ = try parent_gz.add(.{
5248 .tag = .restore_err_ret_index,
5249 .data = .{ .un_node = .{
5250 .operand = parent_gz.saved_err_trace_index,
5251 .src_node = parent_gz.nodeIndexToRelative(node),
5252 } },
5253 });
5254 }
5255 return result;
5238}5256}
52395257
5240/// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`.5258/// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`.
...@@ -5430,10 +5448,16 @@ fn ifExpr(...@@ -5430,10 +5448,16 @@ fn ifExpr(
5430 const tree = astgen.tree;5448 const tree = astgen.tree;
5431 const token_tags = tree.tokens.items(.tag);5449 const token_tags = tree.tokens.items(.tag);
54325450
5451 const do_err_trace = astgen.fn_block != null and if_full.error_token != null;
5452
5433 var block_scope = parent_gz.makeSubBlock(scope);5453 var block_scope = parent_gz.makeSubBlock(scope);
5434 block_scope.setBreakResultLoc(rl);5454 block_scope.setBreakResultLoc(rl);
5435 defer block_scope.unstack();5455 defer block_scope.unstack();
54365456
5457 if (do_err_trace) {
5458 block_scope.saved_err_trace_index = try parent_gz.addNode(.save_err_ret_index, node);
5459 }
5460
5437 const payload_is_ref = if (if_full.payload_token) |payload_token|5461 const payload_is_ref = if (if_full.payload_token) |payload_token|
5438 token_tags[payload_token] == .asterisk5462 token_tags[payload_token] == .asterisk
5439 else5463 else
...@@ -5602,7 +5626,7 @@ fn ifExpr(...@@ -5602,7 +5626,7 @@ fn ifExpr(
5602 };5626 };
56035627
5604 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";5628 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5605 return finishThenElseBlock(5629 const result = try finishThenElseBlock(
5606 parent_gz,5630 parent_gz,
5607 rl,5631 rl,
5608 node,5632 node,
...@@ -5617,6 +5641,16 @@ fn ifExpr(...@@ -5617,6 +5641,16 @@ fn ifExpr(
5617 block,5641 block,
5618 break_tag,5642 break_tag,
5619 );5643 );
5644 if (do_err_trace) {
5645 _ = try parent_gz.add(.{
5646 .tag = .restore_err_ret_index,
5647 .data = .{ .un_node = .{
5648 .operand = parent_gz.saved_err_trace_index,
5649 .src_node = parent_gz.nodeIndexToRelative(node),
5650 } },
5651 });
5652 }
5653 return result;
5620}5654}
56215655
5622/// Supports `else_scope` stacked on `then_scope`. Unstacks `else_scope` then `then_scope`.5656/// Supports `else_scope` stacked on `then_scope`. Unstacks `else_scope` then `then_scope`.
...@@ -10300,6 +10334,8 @@ const GenZir = struct {...@@ -10300,6 +10334,8 @@ const GenZir = struct {
10300 /// Keys are the raw instruction index, values are the closure_capture instruction.10334 /// Keys are the raw instruction index, values are the closure_capture instruction.
10301 captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},10335 captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},
1030210336
10337 saved_err_trace_index: Zir.Inst.Ref = .none,
10338
10303 const unstacked_top = std.math.maxInt(usize);10339 const unstacked_top = std.math.maxInt(usize);
10304 /// Call unstack before adding any new instructions to containing GenZir.10340 /// Call unstack before adding any new instructions to containing GenZir.
10305 fn unstack(self: *GenZir) void {10341 fn unstack(self: *GenZir) void {
...@@ -10344,6 +10380,7 @@ const GenZir = struct {...@@ -10344,6 +10380,7 @@ const GenZir = struct {
10344 .any_defer_node = gz.any_defer_node,10380 .any_defer_node = gz.any_defer_node,
10345 .instructions = gz.instructions,10381 .instructions = gz.instructions,
10346 .instructions_top = gz.instructions.items.len,10382 .instructions_top = gz.instructions.items.len,
10383 .saved_err_trace_index = gz.saved_err_trace_index,
10347 };10384 };
10348 }10385 }
1034910386
src/Sema.zig+53-2
...@@ -926,6 +926,8 @@ fn analyzeBodyInner(...@@ -926,6 +926,8 @@ fn analyzeBodyInner(
926 .ret_ptr => try sema.zirRetPtr(block, inst),926 .ret_ptr => try sema.zirRetPtr(block, inst),
927 .ret_type => try sema.addType(sema.fn_ret_ty),927 .ret_type => try sema.addType(sema.fn_ret_ty),
928928
929 .save_err_ret_index => try sema.zirSaveErrRetIndex(block, inst),
930
929 // Instructions that we know to *always* be noreturn based solely on their tag.931 // Instructions that we know to *always* be noreturn based solely on their tag.
930 // These functions match the return type of analyzeBody so that we can932 // These functions match the return type of analyzeBody so that we can
931 // tail call them here.933 // tail call them here.
...@@ -1208,6 +1210,11 @@ fn analyzeBodyInner(...@@ -1208,6 +1210,11 @@ fn analyzeBodyInner(
1208 i += 1;1210 i += 1;
1209 continue;1211 continue;
1210 },1212 },
1213 .restore_err_ret_index => {
1214 try sema.zirRestoreErrRetIndex(block, inst);
1215 i += 1;
1216 continue;
1217 },
12111218
1212 // Special case instructions to handle comptime control flow.1219 // Special case instructions to handle comptime control flow.
1213 .@"break" => {1220 .@"break" => {
...@@ -16176,6 +16183,52 @@ fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {...@@ -16176,6 +16183,52 @@ fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
16176 backend_supports_error_return_tracing;16183 backend_supports_error_return_tracing;
16177}16184}
1617816185
16186fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
16187 const inst_data = sema.code.instructions.items(.data)[inst].node;
16188 const src = LazySrcLoc.nodeOffset(inst_data);
16189
16190 // This is only relevant at runtime.
16191 if (block.is_comptime) return Air.Inst.Ref.zero_usize;
16192
16193 const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
16194 const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
16195 sema.mod.comp.bin_file.options.error_return_tracing and
16196 backend_supports_error_return_tracing;
16197 if (!ok) return Air.Inst.Ref.zero_usize;
16198
16199 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
16200 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
16201 const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
16202 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
16203 return sema.fieldVal(block, src, err_return_trace, "index", src);
16204}
16205
16206fn zirRestoreErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
16207 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16208 const src = inst_data.src();
16209
16210 // This is only relevant at runtime.
16211 if (block.is_comptime) return;
16212
16213 const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
16214 const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
16215 sema.mod.comp.bin_file.options.error_return_tracing and
16216 backend_supports_error_return_tracing;
16217 if (!ok) return;
16218
16219 const operand = if (inst_data.operand != .none)
16220 try sema.resolveInst(inst_data.operand)
16221 else
16222 .zero_usize;
16223
16224 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
16225 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
16226 const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
16227 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
16228 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true);
16229 try sema.storePtr2(block, src, field_ptr, src, operand, src, .store);
16230}
16231
16179fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {16232fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
16180 assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion);16233 assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion);
1618116234
...@@ -17181,8 +17234,6 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17181,8 +17234,6 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1718117234
17182fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17235fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17183 const inst_data = sema.code.instructions.items(.data)[inst].un_node;17236 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
17184 const src = inst_data.src();
17185 _ = src;
17186 const operand = try sema.resolveInst(inst_data.operand);17237 const operand = try sema.resolveInst(inst_data.operand);
17187 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };17238 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1718817239
src/Zir.zig+16
...@@ -988,6 +988,15 @@ pub const Inst = struct {...@@ -988,6 +988,15 @@ pub const Inst = struct {
988 /// Uses the `err_defer_code` union field.988 /// Uses the `err_defer_code` union field.
989 defer_err_code,989 defer_err_code,
990990
991 /// Saves the current error return case if it exists,
992 /// otherwise just returns zero.
993 /// Uses the `node` union field.
994 save_err_ret_index,
995 /// Sets error return trace to zero if no operand is given,
996 /// otherwise sets the value to the given amount.
997 /// Uses the `un_node` union field.
998 restore_err_ret_index,
999
991 /// The ZIR instruction tag is one of the `Extended` ones.1000 /// The ZIR instruction tag is one of the `Extended` ones.
992 /// Uses the `extended` union field.1001 /// Uses the `extended` union field.
993 extended,1002 extended,
...@@ -1236,6 +1245,8 @@ pub const Inst = struct {...@@ -1236,6 +1245,8 @@ pub const Inst = struct {
1236 //.try_ptr_inline,1245 //.try_ptr_inline,
1237 .@"defer",1246 .@"defer",
1238 .defer_err_code,1247 .defer_err_code,
1248 .save_err_ret_index,
1249 .restore_err_ret_index,
1239 => false,1250 => false,
12401251
1241 .@"break",1252 .@"break",
...@@ -1305,6 +1316,7 @@ pub const Inst = struct {...@@ -1305,6 +1316,7 @@ pub const Inst = struct {
1305 .check_comptime_control_flow,1316 .check_comptime_control_flow,
1306 .@"defer",1317 .@"defer",
1307 .defer_err_code,1318 .defer_err_code,
1319 .restore_err_ret_index,
1308 => true,1320 => true,
13091321
1310 .param,1322 .param,
...@@ -1530,6 +1542,7 @@ pub const Inst = struct {...@@ -1530,6 +1542,7 @@ pub const Inst = struct {
1530 .try_ptr,1542 .try_ptr,
1531 //.try_inline,1543 //.try_inline,
1532 //.try_ptr_inline,1544 //.try_ptr_inline,
1545 .save_err_ret_index,
1533 => false,1546 => false,
15341547
1535 .extended => switch (data.extended.opcode) {1548 .extended => switch (data.extended.opcode) {
...@@ -1810,6 +1823,9 @@ pub const Inst = struct {...@@ -1810,6 +1823,9 @@ pub const Inst = struct {
1810 .@"defer" = .@"defer",1823 .@"defer" = .@"defer",
1811 .defer_err_code = .defer_err_code,1824 .defer_err_code = .defer_err_code,
18121825
1826 .save_err_ret_index = .node,
1827 .restore_err_ret_index = .un_node,
1828
1813 .extended = .extended,1829 .extended = .extended,
1814 });1830 });
1815 };1831 };
src/print_zir.zig+3-1
...@@ -232,6 +232,7 @@ const Writer = struct {...@@ -232,6 +232,7 @@ const Writer = struct {
232 .validate_deref,232 .validate_deref,
233 .overflow_arithmetic_ptr,233 .overflow_arithmetic_ptr,
234 .check_comptime_control_flow,234 .check_comptime_control_flow,
235 .restore_err_ret_index,
235 => try self.writeUnNode(stream, inst),236 => try self.writeUnNode(stream, inst),
236237
237 .ref,238 .ref,
...@@ -405,6 +406,7 @@ const Writer = struct {...@@ -405,6 +406,7 @@ const Writer = struct {
405 .alloc_inferred_comptime_mut,406 .alloc_inferred_comptime_mut,
406 .ret_ptr,407 .ret_ptr,
407 .ret_type,408 .ret_type,
409 .save_err_ret_index,
408 => try self.writeNode(stream, inst),410 => try self.writeNode(stream, inst),
409411
410 .error_value,412 .error_value,
...@@ -440,7 +442,7 @@ const Writer = struct {...@@ -440,7 +442,7 @@ const Writer = struct {
440442
441 .dbg_block_begin,443 .dbg_block_begin,
442 .dbg_block_end,444 .dbg_block_end,
443 => try stream.writeAll("))"),445 => try stream.writeAll(")"),
444446
445 .closure_get => try self.writeInstNode(stream, inst),447 .closure_get => try self.writeInstNode(stream, inst),
446448