diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 442b7a1b9a..fc4b774baa 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -408,9 +408,17 @@ pub fn resolve(options: Options) !Config { }; }; + const backend_supports_error_tracing = target_util.backendSupportsFeature( + target.cpu.arch, + target.ofmt, + use_llvm, + .error_return_trace, + ); + const root_error_tracing = b: { if (options.root_error_tracing) |x| break :b x; if (root_strip) break :b false; + if (!backend_supports_error_tracing) break :b false; break :b switch (root_optimize_mode) { .Debug => true, .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false, @@ -418,6 +426,8 @@ pub fn resolve(options: Options) !Config { }; const any_error_tracing = root_error_tracing or options.any_error_tracing; + if (any_error_tracing and !backend_supports_error_tracing) + return error.BackendLacksErrorTracing; const rdynamic = options.rdynamic orelse false; diff --git a/src/Module.zig b/src/Module.zig index d7b82d15a2..86c124e3b5 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5589,16 +5589,7 @@ pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool { const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch; const ofmt = zcu.root_mod.resolved_target.result.ofmt; const use_llvm = zcu.comp.config.use_llvm; - return switch (feature) { - .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64, - .panic_unwrap_error => ofmt == .c or use_llvm, - .safety_check_formatted => ofmt == .c or use_llvm, - .error_return_trace => use_llvm, - .is_named_enum_value => use_llvm, - .error_set_has_value => use_llvm or cpu_arch.isWasm(), - .field_reordering => use_llvm, - .safety_checked_instructions => use_llvm, - }; + return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature); } /// Shortcut for calling `intern_pool.get`. diff --git a/src/Sema.zig b/src/Sema.zig index c2e05e4a2c..3a54b20ea4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2045,9 +2045,10 @@ fn analyzeAsType( pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { const mod = sema.mod; + const comp = mod.comp; const gpa = sema.gpa; const ip = &mod.intern_pool; - if (!mod.backendSupportsFeature(.error_return_trace)) return; + if (!comp.config.any_error_tracing) return; assert(!block.is_comptime); var err_trace_block = block.makeSubBlock(); @@ -6543,7 +6544,6 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref const gpa = sema.gpa; const src = sema.src; - if (!mod.backendSupportsFeature(.error_return_trace)) return .none; if (!block.ownerModule().error_tracing) return .none; if (block.is_comptime) @@ -6728,7 +6728,7 @@ fn zirCall( input_is_error = false; } - if (mod.backendSupportsFeature(.error_return_trace) and block.ownerModule().error_tracing and + if (block.ownerModule().error_tracing and !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) { const return_ty = sema.typeOf(call_inst); @@ -18759,8 +18759,6 @@ fn retWithErrTracing( fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { const mod = sema.mod; - if (!mod.backendSupportsFeature(.error_return_trace)) return false; - return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing; } @@ -18768,8 +18766,6 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; - // TODO: replace all of these checks with logic in module creation - if (!mod.backendSupportsFeature(.error_return_trace)) return; if (!block.ownerModule().error_tracing) return; // This is only relevant at runtime. @@ -18795,7 +18791,6 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) const mod = sema.mod; const ip = &mod.intern_pool; - if (!mod.backendSupportsFeature(.error_return_trace)) return; if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return; if (!start_block.ownerModule().error_tracing) return; @@ -20068,8 +20063,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { if (sema.owner_func_index != .none and ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and - block.ownerModule().error_tracing and - mod.backendSupportsFeature(.error_return_trace)) + block.ownerModule().error_tracing) { return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); } diff --git a/src/target.zig b/src/target.zig index 4adc26aff8..d1a98601cf 100644 --- a/src/target.zig +++ b/src/target.zig @@ -2,6 +2,7 @@ const std = @import("std"); const Type = @import("type.zig").Type; const AddressSpace = std.builtin.AddressSpace; const Alignment = @import("InternPool.zig").Alignment; +const Feature = @import("Module.zig").Feature; pub const default_stack_protector_buffer_size = 4; @@ -665,6 +666,24 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken }; } +pub fn backendSupportsFeature( + cpu_arch: std.Target.Cpu.Arch, + ofmt: std.Target.ObjectFormat, + use_llvm: bool, + feature: Feature, +) bool { + return switch (feature) { + .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64, + .panic_unwrap_error => ofmt == .c or use_llvm, + .safety_check_formatted => ofmt == .c or use_llvm, + .error_return_trace => use_llvm, + .is_named_enum_value => use_llvm, + .error_set_has_value => use_llvm or cpu_arch.isWasm(), + .field_reordering => use_llvm, + .safety_checked_instructions => use_llvm, + }; +} + pub fn defaultEntrySymbolName( target: std.Target, /// May be `undefined` when `target` is not WASI.