| author | |
| committer | |
| log | 0e815c652d7908be62612bb931c2ee9698dd41da |
| tree | 2fdefb0b7575805af532ed4fb60057d1cb3dc206 |
| parent | 61fe307d0f05eea901577900f4ab2bdaf0ffb35f |
| parent | d4b6a53327352dc239644dab0ec2abbe3a1b1be9 |
| signature |
compiler: include error trace in all functions, implement for x86_64 backend12 files changed, 174 insertions(+), 106 deletions(-)
lib/std/builtin.zig+2-1| ... | ... | @@ -1150,9 +1150,10 @@ pub const panicInactiveUnionField = Panic.inactiveUnionField; |
| 1150 | 1150 | /// To be deleted after zig1.wasm is updated. |
| 1151 | 1151 | pub const panic_messages = Panic.messages; |
| 1152 | 1152 | |
| 1153 | pub noinline fn returnError(st: *StackTrace) void { | |
| 1153 | pub noinline fn returnError() void { | |
| 1154 | 1154 | @branchHint(.unlikely); |
| 1155 | 1155 | @setRuntimeSafety(false); |
| 1156 | const st = @errorReturnTrace().?; | |
| 1156 | 1157 | if (st.index < st.instruction_addresses.len) |
| 1157 | 1158 | st.instruction_addresses[st.index] = @returnAddress(); |
| 1158 | 1159 | st.index += 1; |
src/InternPool.zig+7-18| ... | ... | @@ -2294,17 +2294,6 @@ pub const Key = union(enum) { |
| 2294 | 2294 | return @atomicLoad(FuncAnalysis, func.analysisPtr(ip), .unordered); |
| 2295 | 2295 | } |
| 2296 | 2296 | |
| 2297 | pub fn setCallsOrAwaitsErrorableFn(func: Func, ip: *InternPool, value: bool) void { | |
| 2298 | const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex; | |
| 2299 | extra_mutex.lock(); | |
| 2300 | defer extra_mutex.unlock(); | |
| 2301 | ||
| 2302 | const analysis_ptr = func.analysisPtr(ip); | |
| 2303 | var analysis = analysis_ptr.*; | |
| 2304 | analysis.calls_or_awaits_errorable_fn = value; | |
| 2305 | @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release); | |
| 2306 | } | |
| 2307 | ||
| 2308 | 2297 | pub fn setBranchHint(func: Func, ip: *InternPool, hint: std.builtin.BranchHint) void { |
| 2309 | 2298 | const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex; |
| 2310 | 2299 | extra_mutex.lock(); |
| ... | ... | @@ -5975,7 +5964,7 @@ pub const FuncAnalysis = packed struct(u32) { |
| 5975 | 5964 | is_analyzed: bool, |
| 5976 | 5965 | branch_hint: std.builtin.BranchHint, |
| 5977 | 5966 | is_noinline: bool, |
| 5978 | calls_or_awaits_errorable_fn: bool, | |
| 5967 | has_error_trace: bool, | |
| 5979 | 5968 | /// True if this function has an inferred error set. |
| 5980 | 5969 | inferred_error_set: bool, |
| 5981 | 5970 | disable_instrumentation: bool, |
| ... | ... | @@ -9007,7 +8996,7 @@ pub fn getFuncDecl( |
| 9007 | 8996 | .is_analyzed = false, |
| 9008 | 8997 | .branch_hint = .none, |
| 9009 | 8998 | .is_noinline = key.is_noinline, |
| 9010 | .calls_or_awaits_errorable_fn = false, | |
| 8999 | .has_error_trace = false, | |
| 9011 | 9000 | .inferred_error_set = false, |
| 9012 | 9001 | .disable_instrumentation = false, |
| 9013 | 9002 | }, |
| ... | ... | @@ -9116,7 +9105,7 @@ pub fn getFuncDeclIes( |
| 9116 | 9105 | .is_analyzed = false, |
| 9117 | 9106 | .branch_hint = .none, |
| 9118 | 9107 | .is_noinline = key.is_noinline, |
| 9119 | .calls_or_awaits_errorable_fn = false, | |
| 9108 | .has_error_trace = false, | |
| 9120 | 9109 | .inferred_error_set = true, |
| 9121 | 9110 | .disable_instrumentation = false, |
| 9122 | 9111 | }, |
| ... | ... | @@ -9312,7 +9301,7 @@ pub fn getFuncInstance( |
| 9312 | 9301 | .is_analyzed = false, |
| 9313 | 9302 | .branch_hint = .none, |
| 9314 | 9303 | .is_noinline = arg.is_noinline, |
| 9315 | .calls_or_awaits_errorable_fn = false, | |
| 9304 | .has_error_trace = false, | |
| 9316 | 9305 | .inferred_error_set = false, |
| 9317 | 9306 | .disable_instrumentation = false, |
| 9318 | 9307 | }, |
| ... | ... | @@ -9410,7 +9399,7 @@ pub fn getFuncInstanceIes( |
| 9410 | 9399 | .is_analyzed = false, |
| 9411 | 9400 | .branch_hint = .none, |
| 9412 | 9401 | .is_noinline = arg.is_noinline, |
| 9413 | .calls_or_awaits_errorable_fn = false, | |
| 9402 | .has_error_trace = false, | |
| 9414 | 9403 | .inferred_error_set = true, |
| 9415 | 9404 | .disable_instrumentation = false, |
| 9416 | 9405 | }, |
| ... | ... | @@ -12174,7 +12163,7 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { |
| 12174 | 12163 | return @atomicLoad(FuncAnalysis, ip.funcAnalysisPtr(func), .unordered); |
| 12175 | 12164 | } |
| 12176 | 12165 | |
| 12177 | pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { | |
| 12166 | pub fn funcSetHasErrorTrace(ip: *InternPool, func: Index, has_error_trace: bool) void { | |
| 12178 | 12167 | const unwrapped_func = func.unwrap(ip); |
| 12179 | 12168 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; |
| 12180 | 12169 | extra_mutex.lock(); |
| ... | ... | @@ -12182,7 +12171,7 @@ pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { |
| 12182 | 12171 | |
| 12183 | 12172 | const analysis_ptr = ip.funcAnalysisPtr(func); |
| 12184 | 12173 | var analysis = analysis_ptr.*; |
| 12185 | analysis.calls_or_awaits_errorable_fn = true; | |
| 12174 | analysis.has_error_trace = has_error_trace; | |
| 12186 | 12175 | @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release); |
| 12187 | 12176 | } |
| 12188 | 12177 |
src/Sema.zig+19-24| ... | ... | @@ -7198,14 +7198,6 @@ fn zirCall( |
| 7198 | 7198 | const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1); |
| 7199 | 7199 | const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call); |
| 7200 | 7200 | |
| 7201 | switch (sema.owner.unwrap()) { | |
| 7202 | .@"comptime", .type, .memoized_state, .nav_ty, .nav_val => input_is_error = false, | |
| 7203 | .func => |owner_func| if (!zcu.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) { | |
| 7204 | // No errorable fn actually called; we have no error return trace | |
| 7205 | input_is_error = false; | |
| 7206 | }, | |
| 7207 | } | |
| 7208 | ||
| 7209 | 7201 | if (block.ownerModule().error_tracing and |
| 7210 | 7202 | !block.isComptime() and !block.is_typeof and (input_is_error or pop_error_return_trace)) |
| 7211 | 7203 | { |
| ... | ... | @@ -7872,6 +7864,12 @@ fn analyzeCall( |
| 7872 | 7864 | } |
| 7873 | 7865 | break :msg msg; |
| 7874 | 7866 | }); |
| 7867 | if (func_ty_info.cc == .auto) { | |
| 7868 | switch (sema.owner.unwrap()) { | |
| 7869 | .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {}, | |
| 7870 | .func => |owner_func| ip.funcSetHasErrorTrace(owner_func, true), | |
| 7871 | } | |
| 7872 | } | |
| 7875 | 7873 | for (args, 0..) |arg, arg_idx| { |
| 7876 | 7874 | try sema.validateRuntimeValue(block, args_info.argSrc(block, arg_idx), arg); |
| 7877 | 7875 | } |
| ... | ... | @@ -7946,13 +7944,6 @@ fn analyzeCall( |
| 7946 | 7944 | try zcu.ensureFuncBodyAnalysisQueued(runtime_func_val.toIntern()); |
| 7947 | 7945 | } |
| 7948 | 7946 | |
| 7949 | switch (sema.owner.unwrap()) { | |
| 7950 | .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {}, | |
| 7951 | .func => |owner_func| if (resolved_ret_ty.isError(zcu)) { | |
| 7952 | ip.funcSetCallsOrAwaitsErrorableFn(owner_func); | |
| 7953 | }, | |
| 7954 | } | |
| 7955 | ||
| 7956 | 7947 | const call_tag: Air.Inst.Tag = switch (modifier) { |
| 7957 | 7948 | .auto, .no_async => .call, |
| 7958 | 7949 | .never_tail => .call_never_tail, |
| ... | ... | @@ -19706,16 +19697,16 @@ fn retWithErrTracing( |
| 19706 | 19697 | .bool_false => false, |
| 19707 | 19698 | else => true, |
| 19708 | 19699 | }; |
| 19700 | ||
| 19701 | // This means we're returning something that might be an error! | |
| 19702 | // This should only be possible with the `auto` cc, so we definitely have an error trace. | |
| 19703 | assert(pt.zcu.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).has_error_trace); | |
| 19704 | ||
| 19709 | 19705 | const gpa = sema.gpa; |
| 19710 | const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace); | |
| 19711 | try stack_trace_ty.resolveFields(pt); | |
| 19712 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); | |
| 19713 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); | |
| 19714 | 19706 | const return_err_fn = Air.internedToRef(try sema.getBuiltin(src, .returnError)); |
| 19715 | const args: [1]Air.Inst.Ref = .{err_return_trace}; | |
| 19716 | 19707 | |
| 19717 | 19708 | if (!need_check) { |
| 19718 | try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return"); | |
| 19709 | try sema.callBuiltin(block, src, return_err_fn, .never_inline, &.{}, .@"error return"); | |
| 19719 | 19710 | _ = try block.addUnOp(ret_tag, operand); |
| 19720 | 19711 | return; |
| 19721 | 19712 | } |
| ... | ... | @@ -19726,7 +19717,7 @@ fn retWithErrTracing( |
| 19726 | 19717 | |
| 19727 | 19718 | var else_block = block.makeSubBlock(); |
| 19728 | 19719 | defer else_block.instructions.deinit(gpa); |
| 19729 | try sema.callBuiltin(&else_block, src, return_err_fn, .never_inline, &args, .@"error return"); | |
| 19720 | try sema.callBuiltin(&else_block, src, return_err_fn, .never_inline, &.{}, .@"error return"); | |
| 19730 | 19721 | _ = try else_block.addUnOp(ret_tag, operand); |
| 19731 | 19722 | |
| 19732 | 19723 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".fields.len + |
| ... | ... | @@ -19837,7 +19828,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19837 | 19828 | return; |
| 19838 | 19829 | } |
| 19839 | 19830 | |
| 19840 | if (!zcu.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return; | |
| 19831 | if (!zcu.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).has_error_trace) return; | |
| 19841 | 19832 | if (!start_block.ownerModule().error_tracing) return; |
| 19842 | 19833 | |
| 19843 | 19834 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere |
| ... | ... | @@ -21123,7 +21114,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21123 | 21114 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| 21124 | 21115 | |
| 21125 | 21116 | switch (sema.owner.unwrap()) { |
| 21126 | .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) { | |
| 21117 | .func => |func| if (ip.funcAnalysisUnordered(func).has_error_trace and block.ownerModule().error_tracing) { | |
| 21127 | 21118 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 21128 | 21119 | }, |
| 21129 | 21120 | .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {}, |
| ... | ... | @@ -27096,6 +27087,10 @@ fn preparePanicId(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPo |
| 27096 | 27087 | const zcu = sema.pt.zcu; |
| 27097 | 27088 | try sema.ensureMemoizedStateResolved(src, .panic); |
| 27098 | 27089 | try zcu.ensureFuncBodyAnalysisQueued(zcu.builtin_decl_values.get(.@"Panic.call")); |
| 27090 | switch (sema.owner.unwrap()) { | |
| 27091 | .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {}, | |
| 27092 | .func => |owner_func| zcu.intern_pool.funcSetHasErrorTrace(owner_func, true), | |
| 27093 | } | |
| 27099 | 27094 | return zcu.builtin_decl_values.get(panic_id.toBuiltin()); |
| 27100 | 27095 | } |
| 27101 | 27096 |
src/Zcu/PerThread.zig+4-6| ... | ... | @@ -2596,7 +2596,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE |
| 2596 | 2596 | } |
| 2597 | 2597 | |
| 2598 | 2598 | // reset in case calls to errorable functions are removed. |
| 2599 | func.setCallsOrAwaitsErrorableFn(ip, false); | |
| 2599 | ip.funcSetHasErrorTrace(func_index, fn_ty_info.cc == .auto); | |
| 2600 | 2600 | |
| 2601 | 2601 | // First few indexes of extra are reserved and set at the end. |
| 2602 | 2602 | const reserved_count = @typeInfo(Air.ExtraIndex).@"enum".fields.len; |
| ... | ... | @@ -2707,11 +2707,9 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE |
| 2707 | 2707 | |
| 2708 | 2708 | func.setBranchHint(ip, sema.branch_hint orelse .none); |
| 2709 | 2709 | |
| 2710 | // If we don't get an error return trace from a caller, create our own. | |
| 2711 | if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and | |
| 2712 | zcu.comp.config.any_error_tracing and | |
| 2713 | !sema.fn_ret_ty.isError(zcu)) | |
| 2714 | { | |
| 2710 | if (zcu.comp.config.any_error_tracing and func.analysisUnordered(ip).has_error_trace and fn_ty_info.cc != .auto) { | |
| 2711 | // We're using an error trace, but didn't start out with one from the caller. | |
| 2712 | // We'll have to create it at the start of the function. | |
| 2715 | 2713 | sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) { |
| 2716 | 2714 | error.ComptimeReturn => unreachable, |
| 2717 | 2715 | error.ComptimeBreak => unreachable, |
src/arch/x86_64/CodeGen.zig+123-40| ... | ... | @@ -33,6 +33,8 @@ const FrameIndex = bits.FrameIndex; |
| 33 | 33 | |
| 34 | 34 | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; |
| 35 | 35 | |
| 36 | const err_ret_trace_index: Air.Inst.Index = @enumFromInt(std.math.maxInt(u32)); | |
| 37 | ||
| 36 | 38 | gpa: Allocator, |
| 37 | 39 | pt: Zcu.PerThread, |
| 38 | 40 | air: Air, |
| ... | ... | @@ -55,6 +57,7 @@ va_info: union { |
| 55 | 57 | win64: struct {}, |
| 56 | 58 | }, |
| 57 | 59 | ret_mcv: InstTracking, |
| 60 | err_ret_trace_reg: Register, | |
| 58 | 61 | fn_type: Type, |
| 59 | 62 | src_loc: Zcu.LazySrcLoc, |
| 60 | 63 | |
| ... | ... | @@ -626,6 +629,7 @@ const InstTracking = struct { |
| 626 | 629 | switch (self.long) { |
| 627 | 630 | .none => self.long = try cg.allocRegOrMem(inst, false), |
| 628 | 631 | .load_frame => {}, |
| 632 | .lea_frame => return, | |
| 629 | 633 | .reserved_frame => |index| self.long = .{ .load_frame = .{ .index = index } }, |
| 630 | 634 | else => unreachable, |
| 631 | 635 | } |
| ... | ... | @@ -887,6 +891,7 @@ pub fn generate( |
| 887 | 891 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 888 | 892 | .va_info = undefined, // populated after `resolveCallingConventionValues` |
| 889 | 893 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| 894 | .err_ret_trace_reg = undefined, // populated after `resolveCallingConventionValues` | |
| 890 | 895 | .fn_type = fn_type, |
| 891 | 896 | .src_loc = src_loc, |
| 892 | 897 | .end_di_line = func.rbrace_line, |
| ... | ... | @@ -935,6 +940,7 @@ pub fn generate( |
| 935 | 940 | |
| 936 | 941 | function.args = call_info.args; |
| 937 | 942 | function.ret_mcv = call_info.return_value; |
| 943 | function.err_ret_trace_reg = call_info.err_ret_trace_reg; | |
| 938 | 944 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), .init(.{ |
| 939 | 945 | .size = Type.usize.abiSize(zcu), |
| 940 | 946 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), |
| ... | ... | @@ -962,6 +968,14 @@ pub fn generate( |
| 962 | 968 | } }, |
| 963 | 969 | .x86_64_win => .{ .win64 = .{} }, |
| 964 | 970 | }; |
| 971 | if (call_info.err_ret_trace_reg != .none) { | |
| 972 | function.register_manager.getRegAssumeFree(call_info.err_ret_trace_reg, err_ret_trace_index); | |
| 973 | try function.inst_tracking.putNoClobber( | |
| 974 | gpa, | |
| 975 | err_ret_trace_index, | |
| 976 | .init(.{ .register = call_info.err_ret_trace_reg }), | |
| 977 | ); | |
| 978 | } | |
| 965 | 979 | |
| 966 | 980 | function.gen() catch |err| switch (err) { |
| 967 | 981 | error.CodegenFail => return error.CodegenFail, |
| ... | ... | @@ -1042,6 +1056,7 @@ pub fn generateLazy( |
| 1042 | 1056 | .args = undefined, |
| 1043 | 1057 | .va_info = undefined, |
| 1044 | 1058 | .ret_mcv = undefined, |
| 1059 | .err_ret_trace_reg = undefined, | |
| 1045 | 1060 | .fn_type = undefined, |
| 1046 | 1061 | .src_loc = src_loc, |
| 1047 | 1062 | .end_di_line = undefined, // no debug info yet |
| ... | ... | @@ -2503,9 +2518,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2503 | 2518 | .optional_payload => try cg.airOptionalPayload(inst), |
| 2504 | 2519 | .unwrap_errunion_err => try cg.airUnwrapErrUnionErr(inst), |
| 2505 | 2520 | .unwrap_errunion_payload => try cg.airUnwrapErrUnionPayload(inst), |
| 2506 | .err_return_trace => try cg.airErrReturnTrace(inst), | |
| 2507 | .set_err_return_trace => try cg.airSetErrReturnTrace(inst), | |
| 2508 | .save_err_return_trace_index=> try cg.airSaveErrReturnTraceIndex(inst), | |
| 2509 | 2521 | |
| 2510 | 2522 | .wrap_optional => try cg.airWrapOptional(inst), |
| 2511 | 2523 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), |
| ... | ... | @@ -11236,12 +11248,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 11236 | 11248 | .wasm_memory_size => unreachable, |
| 11237 | 11249 | .wasm_memory_grow => unreachable, |
| 11238 | 11250 | |
| 11251 | .err_return_trace => { | |
| 11252 | const ert: Temp = .{ .index = err_ret_trace_index }; | |
| 11253 | try ert.moveTo(inst, cg); | |
| 11254 | }, | |
| 11255 | .set_err_return_trace => { | |
| 11256 | const un_op = air_datas[@intFromEnum(inst)].un_op; | |
| 11257 | var ops = try cg.tempsFromOperands(inst, .{un_op}); | |
| 11258 | switch (ops[0].unwrap(cg)) { | |
| 11259 | .ref => { | |
| 11260 | const result = try cg.allocRegOrMem(err_ret_trace_index, true); | |
| 11261 | try cg.genCopy(.usize, result, ops[0].tracking(cg).short, .{}); | |
| 11262 | tracking_log.debug("{} => {} (birth)", .{ err_ret_trace_index, result }); | |
| 11263 | cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, .init(result)); | |
| 11264 | }, | |
| 11265 | .temp => |temp_index| { | |
| 11266 | const temp_tracking = temp_index.tracking(cg); | |
| 11267 | tracking_log.debug("{} => {} (birth)", .{ err_ret_trace_index, temp_tracking.short }); | |
| 11268 | cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, temp_tracking.*); | |
| 11269 | assert(cg.reuseTemp(err_ret_trace_index, temp_index.toIndex(), temp_tracking)); | |
| 11270 | }, | |
| 11271 | .err_ret_trace => unreachable, | |
| 11272 | } | |
| 11273 | }, | |
| 11274 | ||
| 11239 | 11275 | .addrspace_cast => { |
| 11240 | 11276 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 11241 | 11277 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 11242 | 11278 | try ops[0].moveTo(inst, cg); |
| 11243 | 11279 | }, |
| 11244 | 11280 | |
| 11281 | .save_err_return_trace_index => { | |
| 11282 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | |
| 11283 | const agg_ty = ty_pl.ty.toType(); | |
| 11284 | assert(agg_ty.containerLayout(zcu) != .@"packed"); | |
| 11285 | var ert: Temp = .{ .index = err_ret_trace_index }; | |
| 11286 | var res = try ert.load(.usize, .{ .disp = @intCast(agg_ty.structFieldOffset(ty_pl.payload, zcu)) }, cg); | |
| 11287 | try ert.die(cg); | |
| 11288 | try res.moveTo(inst, cg); | |
| 11289 | }, | |
| 11290 | ||
| 11245 | 11291 | .vector_store_elem => return cg.fail("TODO implement vector_store_elem", .{}), |
| 11246 | 11292 | |
| 11247 | 11293 | .c_va_arg => try cg.airVaArg(inst), |
| ... | ... | @@ -11697,7 +11743,7 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co |
| 11697 | 11743 | const target_maybe_inst = if (state.free_registers.isSet(reg_index)) null else target_slot; |
| 11698 | 11744 | if (std.debug.runtime_safety) if (target_maybe_inst) |target_inst| |
| 11699 | 11745 | assert(self.inst_tracking.getIndex(target_inst).? < state.inst_tracking_len); |
| 11700 | if (opts.emit_instructions) { | |
| 11746 | if (opts.emit_instructions and current_maybe_inst != target_maybe_inst) { | |
| 11701 | 11747 | if (current_maybe_inst) |current_inst| |
| 11702 | 11748 | try self.inst_tracking.getPtr(current_inst).?.spill(self, current_inst); |
| 11703 | 11749 | if (target_maybe_inst) |target_inst| |
| ... | ... | @@ -11709,7 +11755,7 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co |
| 11709 | 11755 | self.register_manager.freeRegIndex(reg_index); |
| 11710 | 11756 | } |
| 11711 | 11757 | if (target_maybe_inst) |target_inst| { |
| 11712 | self.register_manager.getRegIndexAssumeFree(reg_index, target_maybe_inst); | |
| 11758 | self.register_manager.getRegIndexAssumeFree(reg_index, target_inst); | |
| 11713 | 11759 | self.inst_tracking.getPtr(target_inst).?.trackMaterialize(target_inst, reg_tracking); |
| 11714 | 11760 | } |
| 11715 | 11761 | } else if (target_maybe_inst) |_| |
| ... | ... | @@ -11750,9 +11796,10 @@ pub fn spillEflagsIfOccupied(self: *CodeGen) !void { |
| 11750 | 11796 | } |
| 11751 | 11797 | } |
| 11752 | 11798 | |
| 11753 | pub fn spillCallerPreservedRegs(self: *CodeGen, cc: std.builtin.CallingConvention.Tag) !void { | |
| 11799 | pub fn spillCallerPreservedRegs(self: *CodeGen, cc: std.builtin.CallingConvention.Tag, ignore_reg: Register) !void { | |
| 11754 | 11800 | switch (cc) { |
| 11755 | inline .auto, .x86_64_sysv, .x86_64_win => |tag| try self.spillRegisters(abi.getCallerPreservedRegs(tag)), | |
| 11801 | inline .auto, .x86_64_sysv, .x86_64_win => |tag| inline for (comptime abi.getCallerPreservedRegs(tag)) |reg| | |
| 11802 | if (reg != ignore_reg) try self.register_manager.getKnownReg(reg, null), | |
| 11756 | 11803 | else => unreachable, |
| 11757 | 11804 | } |
| 11758 | 11805 | } |
| ... | ... | @@ -14406,22 +14453,6 @@ fn genUnwrapErrUnionPayloadPtrMir( |
| 14406 | 14453 | return result; |
| 14407 | 14454 | } |
| 14408 | 14455 | |
| 14409 | fn airErrReturnTrace(self: *CodeGen, inst: Air.Inst.Index) !void { | |
| 14410 | _ = inst; | |
| 14411 | return self.fail("TODO implement airErrReturnTrace for {}", .{self.target.cpu.arch}); | |
| 14412 | //return self.finishAir(inst, result, .{ .none, .none, .none }); | |
| 14413 | } | |
| 14414 | ||
| 14415 | fn airSetErrReturnTrace(self: *CodeGen, inst: Air.Inst.Index) !void { | |
| 14416 | _ = inst; | |
| 14417 | return self.fail("TODO implement airSetErrReturnTrace for {}", .{self.target.cpu.arch}); | |
| 14418 | } | |
| 14419 | ||
| 14420 | fn airSaveErrReturnTraceIndex(self: *CodeGen, inst: Air.Inst.Index) !void { | |
| 14421 | _ = inst; | |
| 14422 | return self.fail("TODO implement airSaveErrReturnTraceIndex for {}", .{self.target.cpu.arch}); | |
| 14423 | } | |
| 14424 | ||
| 14425 | 14456 | fn airWrapOptional(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 14426 | 14457 | const pt = self.pt; |
| 14427 | 14458 | const zcu = pt.zcu; |
| ... | ... | @@ -21188,7 +21219,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 21188 | 21219 | } |
| 21189 | 21220 | |
| 21190 | 21221 | try self.spillEflagsIfOccupied(); |
| 21191 | try self.spillCallerPreservedRegs(fn_info.cc); | |
| 21222 | try self.spillCallerPreservedRegs(fn_info.cc, call_info.err_ret_trace_reg); | |
| 21192 | 21223 | |
| 21193 | 21224 | // set stack arguments first because this can clobber registers |
| 21194 | 21225 | // also clobber spill arguments as we go |
| ... | ... | @@ -21273,6 +21304,24 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 21273 | 21304 | else => unreachable, |
| 21274 | 21305 | }; |
| 21275 | 21306 | |
| 21307 | if (call_info.err_ret_trace_reg != .none) { | |
| 21308 | if (self.inst_tracking.getPtr(err_ret_trace_index)) |err_ret_trace| { | |
| 21309 | if (switch (err_ret_trace.short) { | |
| 21310 | .register => |reg| call_info.err_ret_trace_reg != reg, | |
| 21311 | else => true, | |
| 21312 | }) { | |
| 21313 | try self.register_manager.getReg(call_info.err_ret_trace_reg, err_ret_trace_index); | |
| 21314 | try reg_locks.append(self.register_manager.lockReg(call_info.err_ret_trace_reg)); | |
| 21315 | ||
| 21316 | try self.genSetReg(call_info.err_ret_trace_reg, .usize, err_ret_trace.short, .{}); | |
| 21317 | err_ret_trace.trackMaterialize(err_ret_trace_index, .{ | |
| 21318 | .long = err_ret_trace.long, | |
| 21319 | .short = .{ .register = call_info.err_ret_trace_reg }, | |
| 21320 | }); | |
| 21321 | } | |
| 21322 | } | |
| 21323 | } | |
| 21324 | ||
| 21276 | 21325 | // now we are free to set register arguments |
| 21277 | 21326 | switch (call_info.return_value.long) { |
| 21278 | 21327 | .none, .unreach => {}, |
| ... | ... | @@ -21447,6 +21496,17 @@ fn airRet(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void { |
| 21447 | 21496 | else => unreachable, |
| 21448 | 21497 | } |
| 21449 | 21498 | self.ret_mcv.liveOut(self, inst); |
| 21499 | ||
| 21500 | if (self.err_ret_trace_reg != .none) { | |
| 21501 | if (self.inst_tracking.getPtr(err_ret_trace_index)) |err_ret_trace| { | |
| 21502 | if (switch (err_ret_trace.short) { | |
| 21503 | .register => |reg| self.err_ret_trace_reg != reg, | |
| 21504 | else => true, | |
| 21505 | }) try self.genSetReg(self.err_ret_trace_reg, .usize, err_ret_trace.short, .{}); | |
| 21506 | err_ret_trace.liveOut(self, err_ret_trace_index); | |
| 21507 | } | |
| 21508 | } | |
| 21509 | ||
| 21450 | 21510 | try self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 21451 | 21511 | |
| 21452 | 21512 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| ... | ... | @@ -21467,6 +21527,17 @@ fn airRetLoad(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 21467 | 21527 | else => unreachable, |
| 21468 | 21528 | } |
| 21469 | 21529 | self.ret_mcv.liveOut(self, inst); |
| 21530 | ||
| 21531 | if (self.err_ret_trace_reg != .none) { | |
| 21532 | if (self.inst_tracking.getPtr(err_ret_trace_index)) |err_ret_trace| { | |
| 21533 | if (switch (err_ret_trace.short) { | |
| 21534 | .register => |reg| self.err_ret_trace_reg != reg, | |
| 21535 | else => true, | |
| 21536 | }) try self.genSetReg(self.err_ret_trace_reg, .usize, err_ret_trace.short, .{}); | |
| 21537 | err_ret_trace.liveOut(self, err_ret_trace_index); | |
| 21538 | } | |
| 21539 | } | |
| 21540 | ||
| 21470 | 21541 | try self.finishAir(inst, .unreach, .{ un_op, .none, .none }); |
| 21471 | 21542 | |
| 21472 | 21543 | // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction |
| ... | ... | @@ -26098,8 +26169,13 @@ fn airTagName(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 26098 | 26169 | stack_frame_align.* = stack_frame_align.max(needed_call_frame.abi_align); |
| 26099 | 26170 | } |
| 26100 | 26171 | |
| 26172 | const err_ret_trace_reg = if (zcu.comp.config.any_error_tracing) err_ret_trace_reg: { | |
| 26173 | const param_gpr = abi.getCAbiIntParamRegs(.auto); | |
| 26174 | break :err_ret_trace_reg param_gpr[param_gpr.len - 1]; | |
| 26175 | } else .none; | |
| 26176 | ||
| 26101 | 26177 | try self.spillEflagsIfOccupied(); |
| 26102 | try self.spillCallerPreservedRegs(.auto); | |
| 26178 | try self.spillCallerPreservedRegs(.auto, err_ret_trace_reg); | |
| 26103 | 26179 | |
| 26104 | 26180 | const param_regs = abi.getCAbiIntParamRegs(.auto); |
| 26105 | 26181 | |
| ... | ... | @@ -28564,6 +28640,7 @@ const CallMCValues = struct { |
| 28564 | 28640 | stack_align: InternPool.Alignment, |
| 28565 | 28641 | gp_count: u32, |
| 28566 | 28642 | fp_count: u32, |
| 28643 | err_ret_trace_reg: Register, | |
| 28567 | 28644 | |
| 28568 | 28645 | fn deinit(self: *CallMCValues, func: *CodeGen) void { |
| 28569 | 28646 | func.gpa.free(self.args); |
| ... | ... | @@ -28598,6 +28675,7 @@ fn resolveCallingConventionValues( |
| 28598 | 28675 | .stack_align = undefined, |
| 28599 | 28676 | .gp_count = 0, |
| 28600 | 28677 | .fp_count = 0, |
| 28678 | .err_ret_trace_reg = .none, | |
| 28601 | 28679 | }; |
| 28602 | 28680 | errdefer self.gpa.free(result.args); |
| 28603 | 28681 | |
| ... | ... | @@ -28842,6 +28920,11 @@ fn resolveCallingConventionValues( |
| 28842 | 28920 | var param_x87 = abi.getCAbiX87ParamRegs(cc); |
| 28843 | 28921 | var param_sse = abi.getCAbiSseParamRegs(cc, self.target); |
| 28844 | 28922 | |
| 28923 | if (zcu.comp.config.any_error_tracing) { | |
| 28924 | result.err_ret_trace_reg = param_gpr[param_gpr.len - 1]; | |
| 28925 | param_gpr = param_gpr[0 .. param_gpr.len - 1]; | |
| 28926 | } | |
| 28927 | ||
| 28845 | 28928 | // Return values |
| 28846 | 28929 | result.return_value = if (ret_ty.isNoReturn(zcu)) |
| 28847 | 28930 | .init(.unreach) |
| ... | ... | @@ -29159,16 +29242,8 @@ fn typeOf(self: *CodeGen, inst: Air.Inst.Ref) Type { |
| 29159 | 29242 | } |
| 29160 | 29243 | |
| 29161 | 29244 | fn typeOfIndex(self: *CodeGen, inst: Air.Inst.Index) Type { |
| 29162 | const pt = self.pt; | |
| 29163 | const zcu = pt.zcu; | |
| 29164 | 29245 | const temp: Temp = .{ .index = inst }; |
| 29165 | return switch (temp.unwrap(self)) { | |
| 29166 | .ref => switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) { | |
| 29167 | .loop_switch_br => self.typeOf(self.air.unwrapSwitch(inst).operand), | |
| 29168 | else => self.air.typeOfIndex(inst, &zcu.intern_pool), | |
| 29169 | }, | |
| 29170 | .temp => temp.typeOf(self), | |
| 29171 | }; | |
| 29246 | return temp.typeOf(self); | |
| 29172 | 29247 | } |
| 29173 | 29248 | |
| 29174 | 29249 | fn intCompilerRtAbiName(int_bits: u32) u8 { |
| ... | ... | @@ -29336,10 +29411,12 @@ const Temp = struct { |
| 29336 | 29411 | fn unwrap(temp: Temp, cg: *CodeGen) union(enum) { |
| 29337 | 29412 | ref: Air.Inst.Ref, |
| 29338 | 29413 | temp: Index, |
| 29414 | err_ret_trace, | |
| 29339 | 29415 | } { |
| 29340 | 29416 | switch (temp.index.unwrap()) { |
| 29341 | 29417 | .ref => |ref| return .{ .ref = ref }, |
| 29342 | 29418 | .target => |target_index| { |
| 29419 | if (temp.index == err_ret_trace_index) return .err_ret_trace; | |
| 29343 | 29420 | const temp_index: Index = @enumFromInt(target_index); |
| 29344 | 29421 | assert(temp_index.isValid(cg)); |
| 29345 | 29422 | return .{ .temp = temp_index }; |
| ... | ... | @@ -29349,14 +29426,18 @@ const Temp = struct { |
| 29349 | 29426 | |
| 29350 | 29427 | fn typeOf(temp: Temp, cg: *CodeGen) Type { |
| 29351 | 29428 | return switch (temp.unwrap(cg)) { |
| 29352 | .ref => |ref| cg.typeOf(ref), | |
| 29429 | .ref => switch (cg.air.instructions.items(.tag)[@intFromEnum(temp.index)]) { | |
| 29430 | .loop_switch_br => cg.typeOf(cg.air.unwrapSwitch(temp.index).operand), | |
| 29431 | else => cg.air.typeOfIndex(temp.index, &cg.pt.zcu.intern_pool), | |
| 29432 | }, | |
| 29353 | 29433 | .temp => |temp_index| temp_index.typeOf(cg), |
| 29434 | .err_ret_trace => .usize, | |
| 29354 | 29435 | }; |
| 29355 | 29436 | } |
| 29356 | 29437 | |
| 29357 | 29438 | fn isMut(temp: Temp, cg: *CodeGen) bool { |
| 29358 | 29439 | return switch (temp.unwrap(cg)) { |
| 29359 | .ref => false, | |
| 29440 | .ref, .err_ret_trace => false, | |
| 29360 | 29441 | .temp => |temp_index| switch (temp_index.tracking(cg).short) { |
| 29361 | 29442 | .none, |
| 29362 | 29443 | .unreach, |
| ... | ... | @@ -29456,7 +29537,7 @@ const Temp = struct { |
| 29456 | 29537 | fn toOffset(temp: *Temp, off: i32, cg: *CodeGen) !void { |
| 29457 | 29538 | if (off == 0) return; |
| 29458 | 29539 | switch (temp.unwrap(cg)) { |
| 29459 | .ref => {}, | |
| 29540 | .ref, .err_ret_trace => {}, | |
| 29460 | 29541 | .temp => |temp_index| { |
| 29461 | 29542 | const temp_tracking = temp_index.tracking(cg); |
| 29462 | 29543 | switch (temp_tracking.short) { |
| ... | ... | @@ -29617,6 +29698,7 @@ const Temp = struct { |
| 29617 | 29698 | }, |
| 29618 | 29699 | } |
| 29619 | 29700 | }, |
| 29701 | .err_ret_trace => unreachable, | |
| 29620 | 29702 | } |
| 29621 | 29703 | const new_temp = try temp.getLimb(limb_ty, limb_index, cg); |
| 29622 | 29704 | try temp.die(cg); |
| ... | ... | @@ -29633,7 +29715,7 @@ const Temp = struct { |
| 29633 | 29715 | } |
| 29634 | 29716 | |
| 29635 | 29717 | fn toReg(temp: *Temp, new_reg: Register, cg: *CodeGen) !bool { |
| 29636 | const val, const ty = val_ty: switch (temp.unwrap(cg)) { | |
| 29718 | const val, const ty: Type = val_ty: switch (temp.unwrap(cg)) { | |
| 29637 | 29719 | .ref => |ref| .{ temp.tracking(cg).short, cg.typeOf(ref) }, |
| 29638 | 29720 | .temp => |temp_index| { |
| 29639 | 29721 | const temp_tracking = temp_index.tracking(cg); |
| ... | ... | @@ -29641,6 +29723,7 @@ const Temp = struct { |
| 29641 | 29723 | temp_tracking.short.register == new_reg) return false; |
| 29642 | 29724 | break :val_ty .{ temp_tracking.short, temp_index.typeOf(cg) }; |
| 29643 | 29725 | }, |
| 29726 | .err_ret_trace => .{ temp.tracking(cg).short, .usize }, | |
| 29644 | 29727 | }; |
| 29645 | 29728 | const new_temp_index = cg.next_temp_index; |
| 29646 | 29729 | try cg.register_manager.getReg(new_reg, new_temp_index.toIndex()); |
| ... | ... | @@ -30167,7 +30250,7 @@ const Temp = struct { |
| 30167 | 30250 | |
| 30168 | 30251 | fn moveTo(temp: Temp, inst: Air.Inst.Index, cg: *CodeGen) !void { |
| 30169 | 30252 | if (cg.liveness.isUnused(inst)) try temp.die(cg) else switch (temp.unwrap(cg)) { |
| 30170 | .ref => { | |
| 30253 | .ref, .err_ret_trace => { | |
| 30171 | 30254 | const result = try cg.allocRegOrMem(inst, true); |
| 30172 | 30255 | try cg.genCopy(cg.typeOfIndex(inst), result, temp.tracking(cg).short, .{}); |
| 30173 | 30256 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); |
| ... | ... | @@ -30184,7 +30267,7 @@ const Temp = struct { |
| 30184 | 30267 | |
| 30185 | 30268 | fn die(temp: Temp, cg: *CodeGen) !void { |
| 30186 | 30269 | switch (temp.unwrap(cg)) { |
| 30187 | .ref => {}, | |
| 30270 | .ref, .err_ret_trace => {}, | |
| 30188 | 30271 | .temp => |temp_index| try temp_index.tracking(cg).die(cg, temp_index.toIndex()), |
| 30189 | 30272 | } |
| 30190 | 30273 | } |
src/codegen/llvm.zig+14-12| ... | ... | @@ -1497,8 +1497,7 @@ pub const Object = struct { |
| 1497 | 1497 | .unsigned => try attributes.addRetAttr(.zeroext, &o.builder), |
| 1498 | 1498 | }; |
| 1499 | 1499 | |
| 1500 | const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and | |
| 1501 | comp.config.any_error_tracing; | |
| 1500 | const err_return_tracing = fn_info.cc == .auto and comp.config.any_error_tracing; | |
| 1502 | 1501 | |
| 1503 | 1502 | const err_ret_trace: Builder.Value = if (err_return_tracing) param: { |
| 1504 | 1503 | const param = wip.arg(llvm_arg_i); |
| ... | ... | @@ -2805,9 +2804,7 @@ pub const Object = struct { |
| 2805 | 2804 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void)); |
| 2806 | 2805 | } |
| 2807 | 2806 | |
| 2808 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and | |
| 2809 | zcu.comp.config.any_error_tracing) | |
| 2810 | { | |
| 2807 | if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) { | |
| 2811 | 2808 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 2812 | 2809 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2813 | 2810 | } |
| ... | ... | @@ -2970,8 +2967,7 @@ pub const Object = struct { |
| 2970 | 2967 | llvm_arg_i += 1; |
| 2971 | 2968 | } |
| 2972 | 2969 | |
| 2973 | const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and | |
| 2974 | zcu.comp.config.any_error_tracing; | |
| 2970 | const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing; | |
| 2975 | 2971 | |
| 2976 | 2972 | if (err_return_tracing) { |
| 2977 | 2973 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| ... | ... | @@ -3736,9 +3732,7 @@ pub const Object = struct { |
| 3736 | 3732 | try llvm_params.append(o.gpa, .ptr); |
| 3737 | 3733 | } |
| 3738 | 3734 | |
| 3739 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and | |
| 3740 | zcu.comp.config.any_error_tracing) | |
| 3741 | { | |
| 3735 | if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) { | |
| 3742 | 3736 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 3743 | 3737 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); |
| 3744 | 3738 | } |
| ... | ... | @@ -5483,7 +5477,7 @@ pub const FuncGen = struct { |
| 5483 | 5477 | break :blk ret_ptr; |
| 5484 | 5478 | }; |
| 5485 | 5479 | |
| 5486 | const err_return_tracing = return_type.isError(zcu) and zcu.comp.config.any_error_tracing; | |
| 5480 | const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing; | |
| 5487 | 5481 | if (err_return_tracing) { |
| 5488 | 5482 | assert(self.err_ret_trace != .none); |
| 5489 | 5483 | try llvm_args.append(self.err_ret_trace); |
| ... | ... | @@ -5762,6 +5756,8 @@ pub const FuncGen = struct { |
| 5762 | 5756 | const panic_nav = ip.getNav(panic_func.owner_nav); |
| 5763 | 5757 | const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?; |
| 5764 | 5758 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav); |
| 5759 | const has_err_trace = zcu.comp.config.any_error_tracing and fn_info.cc == .auto; | |
| 5760 | if (has_err_trace) assert(fg.err_ret_trace != .none); | |
| 5765 | 5761 | _ = try fg.wip.callIntrinsicAssumeCold(); |
| 5766 | 5762 | _ = try fg.wip.call( |
| 5767 | 5763 | .normal, |
| ... | ... | @@ -5769,7 +5765,13 @@ pub const FuncGen = struct { |
| 5769 | 5765 | .none, |
| 5770 | 5766 | panic_global.typeOf(&o.builder), |
| 5771 | 5767 | panic_global.toValue(&o.builder), |
| 5772 | &.{ | |
| 5768 | if (has_err_trace) &.{ | |
| 5769 | fg.err_ret_trace, | |
| 5770 | msg_ptr.toValue(), | |
| 5771 | try o.builder.intValue(llvm_usize, msg_len), | |
| 5772 | try o.builder.nullValue(.ptr), | |
| 5773 | null_opt_addr_global.toValue(), | |
| 5774 | } else &.{ | |
| 5773 | 5775 | msg_ptr.toValue(), |
| 5774 | 5776 | try o.builder.intValue(llvm_usize, msg_len), |
| 5775 | 5777 | try o.builder.nullValue(.ptr), |
src/target.zig+1-1| ... | ... | @@ -708,7 +708,7 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt |
| 708 | 708 | else => false, |
| 709 | 709 | }, |
| 710 | 710 | .error_return_trace => switch (backend) { |
| 711 | .stage2_llvm => true, | |
| 711 | .stage2_llvm, .stage2_x86_64 => true, | |
| 712 | 712 | else => false, |
| 713 | 713 | }, |
| 714 | 714 | .is_named_enum_value => switch (backend) { |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ |
test/cases/compile_errors/anytype_param_requires_comptime.zig+1-1| ... | ... | @@ -15,6 +15,6 @@ pub export fn entry() void { |
| 15 | 15 | // error |
| 16 | 16 | // |
| 17 | 17 | // :7:25: error: unable to resolve comptime value |
| 18 | // :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_165.C' must be comptime-known | |
| 18 | // :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_441.C' must be comptime-known | |
| 19 | 19 | // :4:16: note: struct requires comptime because of this field |
| 20 | 20 | // :4:16: note: types are not available at runtime |
test/cases/compile_errors/bogus_method_call_on_slice.zig+1-1| ... | ... | @@ -16,5 +16,5 @@ pub export fn entry2() void { |
| 16 | 16 | // |
| 17 | 17 | // :3:6: error: no field or member function named 'copy' in '[]const u8' |
| 18 | 18 | // :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})' |
| 19 | // :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_169' | |
| 19 | // :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_445' | |
| 20 | 20 | // :12:6: note: struct declared here |
test/cases/compile_errors/coerce_anon_struct.zig+1-1| ... | ... | @@ -6,6 +6,6 @@ export fn foo() void { |
| 6 | 6 | |
| 7 | 7 | // error |
| 8 | 8 | // |
| 9 | // :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_158' | |
| 9 | // :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_434' | |
| 10 | 10 | // :3:16: note: struct declared here |
| 11 | 11 | // :1:11: note: struct declared here |
test/cases/compile_errors/implicit_cast_of_error_set_not_a_subset.zig+1-1| ... | ... | @@ -12,5 +12,5 @@ fn foo(set1: Set1) void { |
| 12 | 12 | // backend=stage2 |
| 13 | 13 | // target=native |
| 14 | 14 | // |
| 15 | // :7:21: error: expected type 'error{A,C}', found 'error{A,B}' | |
| 15 | // :7:21: error: expected type 'error{C,A}', found 'error{A,B}' | |
| 16 | 16 | // :7:21: note: 'error.B' not a member of destination error set |