From 9bf715de74a7d5badeae932afb594b7c6b33afa3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 3 Dec 2024 20:35:23 -0800 Subject: [PATCH] rework error handling in the backends --- src/Zcu.zig | 40 ++++++++- src/Zcu/PerThread.zig | 11 +-- src/arch/aarch64/CodeGen.zig | 52 ++++------- src/arch/arm/CodeGen.zig | 50 ++++------- src/arch/riscv64/CodeGen.zig | 105 +++++++--------------- src/arch/sparc64/CodeGen.zig | 44 +++++---- src/arch/x86_64/CodeGen.zig | 117 +++++++----------------- src/codegen.zig | 169 ++++++++++++----------------------- src/link.zig | 8 +- src/link/Coff.zig | 105 ++++++++++++---------- src/link/Dwarf.zig | 12 +-- src/link/Elf.zig | 17 +++- src/link/Elf/ZigObject.zig | 41 ++------- src/link/MachO/ZigObject.zig | 43 ++------- src/link/Plan9.zig | 21 ++--- 15 files changed, 323 insertions(+), 512 deletions(-) diff --git a/src/Zcu.zig b/src/Zcu.zig index 731905d166..ccc4177f33 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -4072,15 +4072,53 @@ pub fn navValIsConst(zcu: *const Zcu, val: InternPool.Index) bool { }; } +pub const CodegenFailError = error{ + /// Indicates the error message has been already stored at `Zcu.failed_codegen`. + CodegenFail, + OutOfMemory, +}; + pub fn codegenFail( zcu: *Zcu, nav_index: InternPool.Nav.Index, comptime format: []const u8, args: anytype, -) error{ CodegenFail, OutOfMemory } { +) CodegenFailError { const gpa = zcu.gpa; try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1); const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args); zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg); return error.CodegenFail; } + +pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg) CodegenFailError { + const gpa = zcu.gpa; + { + errdefer msg.deinit(gpa); + try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg); + } + return error.CodegenFail; +} + +pub fn codegenFailType( + zcu: *Zcu, + ty_index: InternPool.Index, + comptime format: []const u8, + args: anytype, +) CodegenFailError { + const gpa = zcu.gpa; + try zcu.failed_types.ensureUnusedCapacity(gpa, 1); + const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args); + zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); + return error.CodegenFail; +} + +pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) CodegenFailError { + const gpa = zcu.gpa; + { + errdefer msg.deinit(gpa); + try zcu.failed_types.ensureUnusedCapacity(gpa, 1); + } + zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); + return error.CodegenFail; +} diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 47e650cc68..b1f5a973d9 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1726,7 +1726,6 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), - error.LinkFailure => assert(comp.link_diags.hasErrors()), error.Overflow => { try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( gpa, @@ -3112,7 +3111,6 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error lf.updateNav(pt, nav_index) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), - error.LinkFailure => assert(comp.link_diags.hasErrors()), error.Overflow => { try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( gpa, @@ -3139,7 +3137,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{ const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0); defer codegen_prog_node.end(); - if (zcu.failed_types.fetchSwapRemove(ty)) |entry| entry.deinit(); + if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(gpa); if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) { // This type failed to resolve. This is a transitive failure. @@ -3148,12 +3146,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{ if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - else => |e| try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create( - gpa, - zcu.typeSrcLoc(ty), - "failed to update container type: {s}", - .{@errorName(e)}, - )), + error.TypeFailureReported => assert(zcu.failed_types.contains(ty)), }; } diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 557f7f17f6..37eb93976e 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -24,7 +24,6 @@ const build_options = @import("build_options"); const Alignment = InternPool.Alignment; const CodeGenError = codegen.CodeGenError; -const Result = codegen.Result; const bits = @import("bits.zig"); const abi = @import("abi.zig"); @@ -51,7 +50,6 @@ debug_output: link.File.DebugInfoOutput, target: *const std.Target, func_index: InternPool.Index, owner_nav: InternPool.Nav.Index, -err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: MCValue, fn_type: Type, @@ -167,7 +165,7 @@ const DbgInfoReloc = struct { name: [:0]const u8, mcv: MCValue, - fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (reloc.tag) { .arg, .dbg_arg_inline, @@ -181,7 +179,7 @@ const DbgInfoReloc = struct { } } - fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -209,7 +207,7 @@ const DbgInfoReloc = struct { } } - fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (function.debug_output) { .dwarf => |dwarf| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -327,7 +325,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -353,7 +351,6 @@ pub fn generate( .bin_file = lf, .func_index = func_index, .owner_nav = func.owner_nav, - .err_msg = null, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` .fn_type = fn_type, @@ -370,10 +367,7 @@ pub fn generate( defer function.dbg_info_relocs.deinit(gpa); var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }; defer call_info.deinit(&function); @@ -384,15 +378,14 @@ pub fn generate( function.max_end_stack = call_info.stack_byte_count; function.gen() catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; for (function.dbg_info_relocs.items) |reloc| { - try reloc.genDbgInfo(function); + reloc.genDbgInfo(function) catch |err| + return function.fail("failed to generate debug info: {s}", .{@errorName(err)}); } var mir: Mir = .{ @@ -417,15 +410,9 @@ pub fn generate( defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.EmitFail => return Result{ .fail = emit.err_msg.? }, + error.EmitFail => return function.failMsg(emit.err_msg.?), else => |e| return e, }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { @@ -567,7 +554,7 @@ fn gen(self: *Self) !void { .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } }, }); } else { - return self.failSymbol("TODO AArch64: allow larger stacks", .{}); + @panic("TODO AArch64: allow larger stacks"); } _ = try self.addInst(.{ @@ -6191,10 +6178,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, .load_symbol, .load_tlv, .lea_symbol, .lea_direct => unreachable, // TODO }, - .fail => |msg| { - self.err_msg = msg; - return error.CodegenFail; - }, + .fail => |msg| return self.failMsg(msg), }; return mcv; } @@ -6355,18 +6339,14 @@ fn wantSafety(self: *Self) bool { }; } -fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); - return error.CodegenFail; + return self.pt.zcu.codegenFail(self.owner_nav, format, args); } -fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); - return error.CodegenFail; + return self.pt.zcu.codegenFailMsg(self.owner_nav, msg); } fn parseRegName(name: []const u8) ?Register { diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 3d3a821668..57b6b4ff65 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -23,7 +23,6 @@ const log = std.log.scoped(.codegen); const build_options = @import("build_options"); const Alignment = InternPool.Alignment; -const Result = codegen.Result; const CodeGenError = codegen.CodeGenError; const bits = @import("bits.zig"); @@ -245,7 +244,7 @@ const DbgInfoReloc = struct { name: [:0]const u8, mcv: MCValue, - fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (reloc.tag) { .arg, .dbg_arg_inline, @@ -259,7 +258,7 @@ const DbgInfoReloc = struct { } } - fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -287,7 +286,7 @@ const DbgInfoReloc = struct { } } - fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void { + fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void { switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -335,7 +334,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -377,10 +376,7 @@ pub fn generate( defer function.dbg_info_relocs.deinit(gpa); var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }; defer call_info.deinit(&function); @@ -391,15 +387,14 @@ pub fn generate( function.max_end_stack = call_info.stack_byte_count; function.gen() catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; for (function.dbg_info_relocs.items) |reloc| { - try reloc.genDbgInfo(function); + reloc.genDbgInfo(function) catch |err| + return function.fail("failed to generate debug info: {s}", .{@errorName(err)}); } var mir = Mir{ @@ -424,15 +419,9 @@ pub fn generate( defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.EmitFail => return Result{ .fail = emit.err_msg.? }, + error.EmitFail => return function.failMsg(emit.err_msg.?), else => |e| return e, }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { @@ -6310,20 +6299,19 @@ fn wantSafety(self: *Self) bool { }; } -fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - const gpa = self.gpa; - self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); - return error.CodegenFail; + const zcu = self.pt.zcu; + const func = zcu.funcInfo(self.func_index); + const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args); + return zcu.codegenFailMsg(func.owner_nav, msg); } -fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - const gpa = self.gpa; - self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); - return error.CodegenFail; + const zcu = self.pt.zcu; + const func = zcu.funcInfo(self.func_index); + return zcu.codegenFailMsg(func.owner_nav, msg); } fn parseRegName(name: []const u8) ?Register { diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index a836d02d71..40659826f1 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -32,7 +32,6 @@ const wip_mir_log = std.log.scoped(.wip_mir); const Alignment = InternPool.Alignment; const CodeGenError = codegen.CodeGenError; -const Result = codegen.Result; const bits = @import("bits.zig"); const abi = @import("abi.zig"); @@ -62,7 +61,6 @@ gpa: Allocator, mod: *Package.Module, target: *const std.Target, debug_output: link.File.DebugInfoOutput, -err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: InstTracking, fn_type: Type, @@ -761,7 +759,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const comp = zcu.comp; const gpa = zcu.gpa; @@ -788,7 +786,6 @@ pub fn generate( .target = &mod.resolved_target.result, .debug_output = debug_output, .owner = .{ .nav_index = func.owner_nav }, - .err_msg = null, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` .fn_type = fn_type, @@ -829,10 +826,7 @@ pub fn generate( const fn_info = zcu.typeToFunc(fn_type).?; var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }; @@ -861,10 +855,8 @@ pub fn generate( })); function.gen() catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; @@ -895,28 +887,10 @@ pub fn generate( defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? }, - error.InvalidInstruction => |e| { - const msg = switch (e) { - error.InvalidInstruction => "CodeGen failed to find a viable instruction.", - }; - return Result{ - .fail = try ErrorMsg.create( - gpa, - src_loc, - "{s} This is a bug in the Zig compiler.", - .{msg}, - ), - }; - }, + error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), + error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}), else => |e| return e, }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } pub fn generateLazy( @@ -926,7 +900,7 @@ pub fn generateLazy( lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const comp = bin_file.comp; const gpa = comp.gpa; const mod = comp.root_mod; @@ -941,7 +915,6 @@ pub fn generateLazy( .target = &mod.resolved_target.result, .debug_output = debug_output, .owner = .{ .lazy_sym = lazy_sym }, - .err_msg = null, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` .fn_type = undefined, @@ -957,10 +930,8 @@ pub fn generateLazy( defer function.mir_instructions.deinit(gpa); function.genLazy(lazy_sym) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; @@ -991,28 +962,10 @@ pub fn generateLazy( defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? }, - error.InvalidInstruction => |e| { - const msg = switch (e) { - error.InvalidInstruction => "CodeGen failed to find a viable instruction.", - }; - return Result{ - .fail = try ErrorMsg.create( - gpa, - src_loc, - "{s} This is a bug in the Zig compiler.", - .{msg}, - ), - }; - }, + error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), + error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}), else => |e| return e, }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } const FormatWipMirData = struct { @@ -4758,19 +4711,19 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void { return func.fail("TODO implement codegen airFieldParentPtr", .{}); } -fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { +fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void { const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; const ty = arg.ty.toType(); if (arg.name == .none) return; switch (func.debug_output) { .dwarf => |dw| switch (mcv) { - .register => |reg| try dw.genLocalDebugInfo( + .register => |reg| dw.genLocalDebugInfo( .local_arg, arg.name.toSlice(func.air), ty, .{ .reg = reg.dwarfNum() }, - ), + ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}), .load_frame => {}, else => {}, }, @@ -4779,7 +4732,7 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { } } -fn airArg(func: *Func, inst: Air.Inst.Index) !void { +fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void { var arg_index = func.arg_index; // we skip over args that have no bits @@ -5255,7 +5208,7 @@ fn airDbgInlineBlock(func: *Func, inst: Air.Inst.Index) !void { try func.lowerBlock(inst, @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len])); } -fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void { +fn airDbgVar(func: *Func, inst: Air.Inst.Index) InnerError!void { const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const operand = pl_op.operand; const ty = func.typeOf(operand); @@ -5263,7 +5216,8 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void { const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)]; - try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)); + func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)) catch |err| + return func.fail("failed to generate variable debug info: {s}", .{@errorName(err)}); return func.finishAir(inst, .unreach, .{ operand, .none, .none }); } @@ -8236,10 +8190,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)}); }, }, - .fail => |msg| { - func.err_msg = msg; - return error.CodegenFail; - }, + .fail => |msg| return func.failMsg(msg), }; return mcv; } @@ -8427,17 +8378,23 @@ fn wantSafety(func: *Func) bool { }; } -fn fail(func: *Func, comptime format: []const u8, args: anytype) InnerError { +fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(func.err_msg == null); - func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args); + const zcu = func.pt.zcu; + switch (func.owner) { + .nav_index => |i| return zcu.codegenFail(i, format, args), + .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args), + } return error.CodegenFail; } -fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerError { +fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(func.err_msg == null); - func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args); + const zcu = func.pt.zcu; + switch (func.owner) { + .nav_index => |i| return zcu.codegenFailMsg(i, msg), + .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg), + } return error.CodegenFail; } diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 7bbed29d8f..c4b9f38245 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -21,7 +21,6 @@ const Emit = @import("Emit.zig"); const Liveness = @import("../../Liveness.zig"); const Type = @import("../../Type.zig"); const CodeGenError = codegen.CodeGenError; -const Result = @import("../../codegen.zig").Result; const Endian = std.builtin.Endian; const Alignment = InternPool.Alignment; @@ -268,7 +267,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -310,10 +309,7 @@ pub fn generate( defer function.exitlude_jump_relocs.deinit(gpa); var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }; defer call_info.deinit(&function); @@ -324,10 +320,8 @@ pub fn generate( function.max_end_stack = call_info.stack_byte_count; function.gen() catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; @@ -351,15 +345,9 @@ pub fn generate( defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.EmitFail => return Result{ .fail = emit.err_msg.? }, + error.EmitFail => return function.failMsg(emit.err_msg.?), else => |e| return e, }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } fn gen(self: *Self) !void { @@ -1014,7 +1002,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { return bt.finishAir(result); } -fn airArg(self: *Self, inst: Air.Inst.Index) !void { +fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { const pt = self.pt; const zcu = pt.zcu; const arg_index = self.arg_index; @@ -1036,7 +1024,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { } }; - try self.genArgDbgInfo(inst, mcv); + self.genArgDbgInfo(inst, mcv) catch |err| + return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)}); if (self.liveness.isUnused(inst)) return self.finishAirBookkeeping(); @@ -3511,12 +3500,19 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) } } -fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - const gpa = self.gpa; - self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); - return error.CodegenFail; + const zcu = self.pt.zcu; + const func = zcu.funcInfo(self.func_index); + const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args); + return zcu.codegenFailMsg(func.owner_nav, msg); +} + +fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { + @branchHint(.cold); + const zcu = self.pt.zcu; + const func = zcu.funcInfo(self.func_index); + return zcu.codegenFailMsg(func.owner_nav, msg); } /// Called when there are no operands, and the instruction is always unreferenced. diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 298b2e11e0..147f223d11 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -19,7 +19,6 @@ const Allocator = mem.Allocator; const CodeGenError = codegen.CodeGenError; const Compilation = @import("../../Compilation.zig"); const ErrorMsg = Zcu.ErrorMsg; -const Result = codegen.Result; const Emit = @import("Emit.zig"); const Liveness = @import("../../Liveness.zig"); const Lower = @import("Lower.zig"); @@ -59,7 +58,6 @@ target: *const std.Target, owner: Owner, inline_func: InternPool.Index, mod: *Package.Module, -err_msg: ?*ErrorMsg, arg_index: u32, args: []MCValue, va_info: union { @@ -821,7 +819,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const comp = zcu.comp; const gpa = zcu.gpa; @@ -841,7 +839,6 @@ pub fn generate( .debug_output = debug_output, .owner = .{ .nav_index = func.owner_nav }, .inline_func = func_index, - .err_msg = null, .arg_index = undefined, .args = undefined, // populated after `resolveCallingConventionValues` .va_info = undefined, // populated after `resolveCallingConventionValues` @@ -881,15 +878,7 @@ pub fn generate( const fn_info = zcu.typeToFunc(fn_type).?; const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*); var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create( - gpa, - src_loc, - "CodeGen ran out of registers. This is a bug in the Zig compiler.", - .{}, - ), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }; defer call_info.deinit(&function); @@ -926,10 +915,8 @@ pub fn generate( }; function.gen() catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; @@ -953,10 +940,7 @@ pub fn generate( .pic = mod.pic, }, .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }, .debug_output = debug_output, @@ -974,29 +958,11 @@ pub fn generate( }; defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? }, - error.InvalidInstruction, error.CannotEncode => |e| { - const msg = switch (e) { - error.InvalidInstruction => "CodeGen failed to find a viable instruction.", - error.CannotEncode => "CodeGen failed to encode the instruction.", - }; - return Result{ - .fail = try ErrorMsg.create( - gpa, - src_loc, - "{s} This is a bug in the Zig compiler.", - .{msg}, - ), - }; - }, - else => |e| return e, - }; + error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } + error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}), + else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}), + }; } pub fn generateLazy( @@ -1006,7 +972,7 @@ pub fn generateLazy( lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const comp = bin_file.comp; const gpa = comp.gpa; // This function is for generating global code, so we use the root module. @@ -1022,7 +988,6 @@ pub fn generateLazy( .debug_output = debug_output, .owner = .{ .lazy_sym = lazy_sym }, .inline_func = undefined, - .err_msg = null, .arg_index = undefined, .args = undefined, .va_info = undefined, @@ -1038,10 +1003,8 @@ pub fn generateLazy( } function.genLazy(lazy_sym) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, + error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), else => |e| return e, }; @@ -1065,10 +1028,7 @@ pub fn generateLazy( .pic = mod.pic, }, .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) { - error.CodegenFail => return Result{ .fail = function.err_msg.? }, - error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), - }, + error.CodegenFail => return error.CodegenFail, else => |e| return e, }, .debug_output = debug_output, @@ -1078,29 +1038,11 @@ pub fn generateLazy( }; defer emit.deinit(); emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? }, - error.InvalidInstruction, error.CannotEncode => |e| { - const msg = switch (e) { - error.InvalidInstruction => "CodeGen failed to find a viable instruction.", - error.CannotEncode => "CodeGen failed to encode the instruction.", - }; - return Result{ - .fail = try ErrorMsg.create( - gpa, - src_loc, - "{s} This is a bug in the Zig compiler.", - .{msg}, - ), - }; - }, - else => |e| return e, + error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), + error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}), + error.CannotEncode => return function.fail("failed to find encode x86 instruction (Zig compiler bug)", .{}), + else => |e| return function.fail("failed to emit MIR: {s}", .{@errorName(e)}), }; - - if (function.err_msg) |em| { - return Result{ .fail = em }; - } else { - return Result.ok; - } } const FormatNavData = struct { @@ -19276,10 +19218,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { .load_got => |sym_index| .{ .lea_got = sym_index }, .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, }, - .fail => |msg| { - self.err_msg = msg; - return error.CodegenFail; - }, + .fail => |msg| return self.failMsg(msg), }; } @@ -19592,11 +19531,23 @@ fn resolveCallingConventionValues( return result; } -fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { +fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @branchHint(.cold); - assert(self.err_msg == null); - const gpa = self.gpa; - self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); + const zcu = self.pt.zcu; + switch (self.owner) { + .nav_index => |i| return zcu.codegenFail(i, format, args), + .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args), + } + return error.CodegenFail; +} + +fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { + @branchHint(.cold); + const zcu = self.pt.zcu; + switch (self.owner) { + .nav_index => |i| return zcu.codegenFailMsg(i, msg), + .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg), + } return error.CodegenFail; } diff --git a/src/codegen.zig b/src/codegen.zig index 8ab6fb33b6..0f49e44b97 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -24,13 +24,6 @@ const Zir = std.zig.Zir; const Alignment = InternPool.Alignment; const dev = @import("dev.zig"); -pub const Result = union(enum) { - /// The `code` parameter passed to `generateSymbol` has the value. - ok, - /// There was a codegen error. - fail: *ErrorMsg, -}; - pub const CodeGenError = error{ OutOfMemory, /// Compiler was asked to operate on a number larger than supported. @@ -64,7 +57,7 @@ pub fn generateFunction( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const func = zcu.funcInfo(func_index); const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result; @@ -89,7 +82,7 @@ pub fn generateLazyFunction( lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool); const target = zcu.fileByIndex(file).mod.resolved_target.result; @@ -120,17 +113,17 @@ pub fn generateLazySymbol( code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, reloc_parent: link.File.RelocInfo.Parent, -) CodeGenError!Result { +) CodeGenError!void { _ = reloc_parent; const tracy = trace(@src()); defer tracy.end(); const comp = bin_file.comp; - const ip = &pt.zcu.intern_pool; + const zcu = pt.zcu; + const ip = &zcu.intern_pool; const target = comp.root_mod.resolved_target.result; const endian = target.cpu.arch.endian(); - const gpa = comp.gpa; log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ @tagName(lazy_sym.kind), @@ -161,26 +154,29 @@ pub fn generateLazySymbol( string_index += @intCast(err_name.len + 1); } mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian); - return .ok; - } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") { + } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") { alignment.* = .@"1"; const enum_ty = Type.fromInterned(lazy_sym.ty); - const tag_names = enum_ty.enumFields(pt.zcu); + const tag_names = enum_ty.enumFields(zcu); for (0..tag_names.len) |tag_index| { const tag_name = tag_names.get(ip)[tag_index].toSlice(ip); try code.ensureUnusedCapacity(tag_name.len + 1); code.appendSliceAssumeCapacity(tag_name); code.appendAssumeCapacity(0); } - return .ok; - } else return .{ .fail = try .create( - gpa, - src_loc, - "TODO implement generateLazySymbol for {s} {}", - .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) }, - ) }; + } else { + return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{ + @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), + }); + } } +pub const GenerateSymbolError = error{ + OutOfMemory, + /// Compiler was asked to operate on a number larger than supported. + Overflow, +}; + pub fn generateSymbol( bin_file: *link.File, pt: Zcu.PerThread, @@ -188,7 +184,7 @@ pub fn generateSymbol( val: Value, code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, -) CodeGenError!Result { +) GenerateSymbolError!void { const tracy = trace(@src()); defer tracy.end(); @@ -204,7 +200,7 @@ pub fn generateSymbol( if (val.isUndefDeep(zcu)) { const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; try code.appendNTimes(0xaa, abi_size); - return .ok; + return; } switch (ip.indexToKey(val.toIntern())) { @@ -266,7 +262,7 @@ pub fn generateSymbol( if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { try code.writer().writeInt(u16, err_val, endian); - return .ok; + return; } const payload_align = payload_ty.abiAlignment(zcu); @@ -281,13 +277,10 @@ pub fn generateSymbol( // emit payload part of the error union { const begin = code.items.len; - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), .payload => |payload| payload, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); const unpadded_end = code.items.len - begin; const padded_end = abi_align.forward(unpadded_end); const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow; @@ -312,10 +305,7 @@ pub fn generateSymbol( }, .enum_tag => |enum_tag| { const int_tag_ty = ty.intTagType(zcu); - switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent); }, .float => |float| switch (float.storage) { .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)), @@ -328,19 +318,10 @@ pub fn generateSymbol( }, .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), }, - .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - }, + .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0), .slice => |slice| { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent); + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent); }, .opt => { const payload_type = ty.optionalChild(zcu); @@ -349,10 +330,7 @@ pub fn generateSymbol( if (ty.optionalReprIsPayload(zcu)) { if (payload_val) |value| { - switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent); } else { try code.appendNTimes(0, abi_size); } @@ -362,10 +340,7 @@ pub fn generateSymbol( const value = payload_val orelse Value.fromInterned(try pt.intern(.{ .undef = payload_type.toIntern(), })); - switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent); } try code.writer().writeByte(@intFromBool(payload_val != null)); try code.appendNTimes(0, padding); @@ -377,17 +352,14 @@ pub fn generateSymbol( .elems, .repeated_elem => { var index: u64 = 0; while (index < array_type.lenIncludingSentinel()) : (index += 1) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { .bytes => unreachable, .elems => |elems| elems[@intCast(index)], .repeated_elem => |elem| if (index < array_type.len) elem else array_type.sentinel, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); } }, }, @@ -437,16 +409,13 @@ pub fn generateSymbol( .elems, .repeated_elem => { var index: u64 = 0; while (index < vector_type.len) : (index += 1) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { .bytes => unreachable, .elems => |elems| elems[ math.cast(usize, index) orelse return error.Overflow ], .repeated_elem => |elem| elem, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); } }, } @@ -476,10 +445,7 @@ pub fn generateSymbol( .repeated_elem => |elem| elem, }; - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); const unpadded_field_end = code.items.len - struct_begin; // Pad struct members if required @@ -518,10 +484,8 @@ pub fn generateSymbol( return error.Overflow; var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); defer tmp_list.deinit(); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) { - .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent); + @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items); } else { Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; } @@ -553,10 +517,7 @@ pub fn generateSymbol( ) orelse return error.Overflow; if (padding > 0) try code.appendNTimes(0, padding); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); } const size = struct_type.sizeUnordered(ip); @@ -582,10 +543,7 @@ pub fn generateSymbol( // Check if we should store the tag first. if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent); } const union_obj = zcu.typeToUnion(ty).?; @@ -595,10 +553,7 @@ pub fn generateSymbol( if (!field_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent); const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow; if (padding > 0) { @@ -606,17 +561,11 @@ pub fn generateSymbol( } } } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent); } if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent); if (layout.padding > 0) { try code.appendNTimes(0, layout.padding); @@ -625,7 +574,6 @@ pub fn generateSymbol( }, .memoized_call => unreachable, } - return .ok; } fn lowerPtr( @@ -636,7 +584,7 @@ fn lowerPtr( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, prev_offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { const zcu = pt.zcu; const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; const offset: u64 = prev_offset + ptr.byte_offset; @@ -689,7 +637,7 @@ fn lowerUavRef( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const ip = &zcu.intern_pool; @@ -702,14 +650,7 @@ fn lowerUavRef( const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn"; if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, ptr_width_bytes); - return .ok; - } - - const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment; - const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc); - switch (res) { - .mcv => {}, - .fail => |em| return .{ .fail = em }, + return; } switch (lf.tag) { @@ -727,11 +668,17 @@ fn lowerUavRef( .pointee = .{ .uav_index = uav.val }, }); try code.appendNTimes(0, ptr_width_bytes); - return .ok; + return; }, else => {}, } + const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment; + switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) { + .mcv => {}, + .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}), + } + const vaddr = try lf.getUavVAddr(uav_val, .{ .parent = reloc_parent, .offset = code.items.len, @@ -744,8 +691,6 @@ fn lowerUavRef( 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian), else => unreachable, } - - return Result.ok; } fn lowerNavRef( @@ -756,7 +701,7 @@ fn lowerNavRef( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { _ = src_loc; const zcu = pt.zcu; const gpa = zcu.gpa; @@ -768,7 +713,7 @@ fn lowerNavRef( const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn"; if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, ptr_width_bytes); - return Result.ok; + return; } switch (lf.tag) { @@ -786,16 +731,16 @@ fn lowerNavRef( .pointee = .{ .nav_index = nav_index }, }); try code.appendNTimes(0, ptr_width_bytes); - return .ok; + return; }, else => {}, } - const vaddr = try lf.getNavVAddr(pt, nav_index, .{ + const vaddr = lf.getNavVAddr(pt, nav_index, .{ .parent = reloc_parent, .offset = code.items.len, .addend = @intCast(offset), - }); + }) catch @panic("TODO rework getNavVAddr"); const endian = target.cpu.arch.endian(); switch (ptr_width_bytes) { 2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian), @@ -803,8 +748,6 @@ fn lowerNavRef( 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian), else => unreachable, } - - return .ok; } /// Helper struct to denote that the value is in memory but requires a linker relocation fixup: diff --git a/src/link.zig b/src/link.zig index d037ccd97b..22eff87e59 100644 --- a/src/link.zig +++ b/src/link.zig @@ -673,7 +673,13 @@ pub const File = struct { } } - pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateNavError!void { + pub const UpdateContainerTypeError = error{ + OutOfMemory, + /// `Zcu.failed_types` is already populated with the error message. + TypeFailureReported, + }; + + pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void { switch (base.tag) { else => {}, inline .elf => |tag| { diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 2ff67d8863..c84e3419e4 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -754,7 +754,7 @@ fn allocateGlobal(coff: *Coff) !u32 { return index; } -fn addGotEntry(coff: *Coff, target: SymbolWithLoc) error{ OutOfMemory, LinkFailure }!void { +fn addGotEntry(coff: *Coff, target: SymbolWithLoc) !void { const gpa = coff.base.comp.gpa; if (coff.got_table.lookup.contains(target)) return; const got_index = try coff.got_table.allocateEntry(gpa, target); @@ -780,7 +780,7 @@ pub fn createAtom(coff: *Coff) !Atom.Index { return atom_index; } -fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) link.File.UpdateNavError!u32 { +fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 { const atom = coff.getAtom(atom_index); const sym = atom.getSymbol(coff); const align_ok = mem.alignBackward(u32, sym.value, alignment) == sym.value; @@ -909,12 +909,12 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void { .p32 => { var buf: [4]u8 = undefined; mem.writeInt(u32, &buf, @intCast(entry_value + coff.image_base), .little); - try coff.pwriteAll(&buf, file_offset); + try coff.base.file.?.pwriteAll(&buf, file_offset); }, .p64 => { var buf: [8]u8 = undefined; mem.writeInt(u64, &buf, entry_value + coff.image_base, .little); - try coff.pwriteAll(&buf, file_offset); + try coff.base.file.?.pwriteAll(&buf, file_offset); }, } @@ -1122,7 +1122,7 @@ pub fn updateFunc( var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const res = codegen.generateFunction( + codegen.generateFunction( &coff.base, pt, zcu.navSrcLoc(nav_index), @@ -1134,7 +1134,7 @@ pub fn updateFunc( ) catch |err| switch (err) { error.CodegenFail => return error.CodegenFail, error.OutOfMemory => return error.OutOfMemory, - else => |e| { + error.Overflow => |e| { try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( gpa, zcu.navSrcLoc(nav_index), @@ -1145,15 +1145,8 @@ pub fn updateFunc( return error.CodegenFail; }, }; - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(zcu.gpa, nav_index, em); - return; - }, - }; - try coff.updateNavCode(pt, nav_index, code, .FUNCTION); + try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION); // Exports will be updated by `Zcu.processExports` after the update. } @@ -1182,16 +1175,13 @@ fn lowerConst( try coff.setSymbolName(sym, name); sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(sect_id + 1)); - const res = try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{ + try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{ .atom_index = coff.getAtom(atom_index).getSymbolIndex().?, }); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return .{ .fail = em }, - }; + const code = code_buffer.items; const atom = coff.getAtomPtr(atom_index); - atom.size = @as(u32, @intCast(code.len)); + atom.size = @intCast(code.len); atom.getSymbolPtr(coff).value = try coff.allocateAtom( atom_index, atom.size, @@ -1250,7 +1240,7 @@ pub fn updateNav( var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &coff.base, pt, zcu.navSrcLoc(nav_index), @@ -1258,15 +1248,8 @@ pub fn updateNav( &code_buffer, .{ .atom_index = atom.getSymbolIndex().? }, ); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(gpa, nav_index, em); - return; - }, - }; - try coff.updateNavCode(pt, nav_index, code, .NULL); + try coff.updateNavCode(pt, nav_index, code_buffer.items, .NULL); } // Exports will be updated by `Zcu.processExports` after the update. @@ -1278,11 +1261,10 @@ fn updateLazySymbolAtom( sym: link.File.LazySymbol, atom_index: Atom.Index, section_index: u16, -) link.File.FlushError!void { +) !void { const zcu = pt.zcu; const comp = coff.base.comp; const gpa = comp.gpa; - const diags = &comp.link_diags; var required_alignment: InternPool.Alignment = .none; var code_buffer = std.ArrayList(u8).init(gpa); @@ -1298,7 +1280,7 @@ fn updateLazySymbolAtom( const local_sym_index = atom.getSymbolIndex().?; const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded; - const res = codegen.generateLazySymbol( + try codegen.generateLazySymbol( &coff.base, pt, src, @@ -1307,14 +1289,8 @@ fn updateLazySymbolAtom( &code_buffer, .none, .{ .atom_index = local_sym_index }, - ) catch |err| switch (err) { - error.CodegenFail => return error.LinkFailure, - else => |e| return diags.fail("failed to generate lazy symbol: {s}", .{@errorName(e)}), - }; - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return diags.fail("failed to generate code: {s}", .{em.msg}), - }; + ); + const code = code_buffer.items; const code_len: u32 = @intCast(code.len); const symbol = atom.getSymbolPtr(coff); @@ -1438,7 +1414,10 @@ fn updateNavCode( const capacity = atom.capacity(coff); const need_realloc = code.len > capacity or !required_alignment.check(sym.value); if (need_realloc) { - const vaddr = try coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)); + const vaddr = coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| return coff.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(e)}), + }; log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr }); log.debug(" (required alignment 0x{x}", .{required_alignment}); @@ -1446,7 +1425,10 @@ fn updateNavCode( sym.value = vaddr; log.debug(" (updating GOT entry)", .{}); const got_entry_index = coff.got_table.lookup.get(.{ .sym_index = sym_index }).?; - try coff.writeOffsetTableEntry(got_entry_index); + coff.writeOffsetTableEntry(got_entry_index) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| return coff.base.cgFail(nav_index, "failed to write offset table entry: {s}", .{@errorName(e)}), + }; coff.markRelocsDirtyByTarget(.{ .sym_index = sym_index }); } } else if (code_len < atom.size) { @@ -1459,16 +1441,25 @@ fn updateNavCode( sym.section_number = @enumFromInt(sect_index + 1); sym.type = .{ .complex_type = complex_type, .base_type = .NULL }; - const vaddr = try coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)); + const vaddr = coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| return coff.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(e)}), + }; errdefer coff.freeAtom(atom_index); log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr }); coff.getAtomPtr(atom_index).size = code_len; sym.value = vaddr; - try coff.addGotEntry(.{ .sym_index = sym_index }); + coff.addGotEntry(.{ .sym_index = sym_index }) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| return coff.base.cgFail(nav_index, "failed to add GOT entry: {s}", .{@errorName(e)}), + }; } - try coff.writeAtom(atom_index, code); + coff.writeAtom(atom_index, code) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| return coff.base.cgFail(nav_index, "failed to write atom: {s}", .{@errorName(e)}), + }; } pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void { @@ -2229,12 +2220,16 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director return null; } -pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { +pub fn flushModule( + coff: *Coff, + arena: Allocator, + tid: Zcu.PerThread.Id, + prog_node: std.Progress.Node, +) link.File.FlushError!void { const tracy = trace(@src()); defer tracy.end(); const comp = coff.base.comp; - const gpa = comp.gpa; const diags = &comp.link_diags; if (coff.llvm_object) |llvm_object| { @@ -2245,6 +2240,20 @@ pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no const sub_prog_node = prog_node.start("COFF Flush", 0); defer sub_prog_node.end(); + return flushModuleInner(coff, arena, tid) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.LinkFailure => return error.LinkFailure, + else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}), + }; +} + +fn flushModuleInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void { + _ = arena; + + const comp = coff.base.comp; + const gpa = comp.gpa; + const diags = &comp.link_diags; + const pt: Zcu.PerThread = .activate( comp.zcu orelse return diags.fail("linking without zig source is not yet implemented", .{}), tid, @@ -2757,7 +2766,7 @@ fn writeImportTables(coff: *Coff) !void { coff.imports_count_dirty = false; } -fn writeStrtab(coff: *Coff) link.File.FlushError!void { +fn writeStrtab(coff: *Coff) !void { if (coff.strtab_offset == null) return; const comp = coff.base.comp; diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index ac966f0abc..f168c78cde 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -21,7 +21,6 @@ debug_rnglists: DebugRngLists, debug_str: StringSection, pub const UpdateError = error{ - CodegenFail, ReinterpretDeclRef, Unimplemented, OutOfMemory, @@ -1893,17 +1892,15 @@ pub const WipNav = struct { if (bytes == 0) return; var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa); defer wip_nav.debug_info = dim.moveToUnmanaged(); - switch (try codegen.generateSymbol( + try codegen.generateSymbol( wip_nav.dwarf.bin_file, wip_nav.pt, src_loc, val, &dim, .{ .debug_output = .{ .dwarf = wip_nav } }, - )) { - .ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes), - .fail => unreachable, - } + ); + assert(dim.items.len == wip_nav.debug_info.items.len + bytes); } const AbbrevCodeForForm = struct { @@ -2346,7 +2343,6 @@ pub fn initWipNav( ) error{ OutOfMemory, CodegenFail }!?WipNav { return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - error.CodegenFail => return error.CodegenFail, else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), }; } @@ -2669,7 +2665,6 @@ pub fn finishWipNav( ) error{ OutOfMemory, CodegenFail }!void { return finishWipNavInner(dwarf, pt, nav_index, wip_nav) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - error.CodegenFail => return error.CodegenFail, else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf: {s}", .{@errorName(e)}), }; } @@ -2701,7 +2696,6 @@ fn finishWipNavInner( pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void { return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - error.CodegenFail => return error.CodegenFail, else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}), }; } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 115c9f4550..7dd092782a 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2368,12 +2368,25 @@ pub fn updateContainerType( self: *Elf, pt: Zcu.PerThread, ty: InternPool.Index, -) link.File.UpdateNavError!void { +) link.File.UpdateContainerTypeError!void { if (build_options.skip_non_native and builtin.object_format != .elf) { @panic("Attempted to compile for object format that was disabled by build configuration"); } if (self.llvm_object) |_| return; - return self.zigObjectPtr().?.updateContainerType(pt, ty); + const zcu = pt.zcu; + const gpa = zcu.gpa; + return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => |e| { + try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create( + gpa, + zcu.typeSrcLoc(ty), + "failed to update container type: {s}", + .{@errorName(e)}, + )); + return error.TypeFailureReported; + }, + }; } pub fn updateExports( diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 8578a7c9c0..524a280723 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -1437,7 +1437,7 @@ pub fn updateFunc( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - const res = try codegen.generateFunction( + try codegen.generateFunction( &elf_file.base, pt, zcu.navSrcLoc(func.owner_nav), @@ -1447,14 +1447,7 @@ pub fn updateFunc( &code_buffer, if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none, ); - - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(gpa, func.owner_nav, em); - return; - }, - }; + const code = code_buffer.items; const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code); log.debug("setting shdr({x},{s}) for {}", .{ @@ -1574,7 +1567,7 @@ pub fn updateNav( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &elf_file.base, pt, zcu.navSrcLoc(nav_index), @@ -1582,14 +1575,7 @@ pub fn updateNav( &code_buffer, .{ .atom_index = sym_index }, ); - - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(zcu.gpa, nav_index, em); - return; - }, - }; + const code = code_buffer.items; const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code); log.debug("setting shdr({x},{s}) for {}", .{ @@ -1612,7 +1598,7 @@ pub fn updateContainerType( self: *ZigObject, pt: Zcu.PerThread, ty: InternPool.Index, -) link.File.UpdateNavError!void { +) !void { const tracy = trace(@src()); defer tracy.end(); @@ -1643,7 +1629,7 @@ fn updateLazySymbol( }; const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded; - const res = try codegen.generateLazySymbol( + try codegen.generateLazySymbol( &elf_file.base, pt, src, @@ -1653,13 +1639,7 @@ fn updateLazySymbol( .none, .{ .atom_index = symbol_index }, ); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - log.err("{s}", .{em.msg}); - return error.CodegenFail; - }, - }; + const code = code_buffer.items; const output_section_index = switch (sym.kind) { .code => if (self.text_index) |sym_index| @@ -1732,7 +1712,7 @@ fn lowerConst( const name_off = try self.addString(gpa, name); const sym_index = try self.newSymbolWithAtom(gpa, name_off); - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &elf_file.base, pt, src_loc, @@ -1740,10 +1720,7 @@ fn lowerConst( &code_buffer, .{ .atom_index = sym_index }, ); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return .{ .fail = em }, - }; + const code = code_buffer.items; const local_sym = self.symbol(sym_index); const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index]; diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 3d99baad06..afb011d46f 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -590,7 +590,6 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) defer pt.deactivate(); dwarf.flushModule(pt) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - error.CodegenFail => return error.LinkFailure, else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}), }; @@ -796,7 +795,7 @@ pub fn updateFunc( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - const res = try codegen.generateFunction( + try codegen.generateFunction( &macho_file.base, pt, zcu.navSrcLoc(func.owner_nav), @@ -806,14 +805,7 @@ pub fn updateFunc( &code_buffer, if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, ); - - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(gpa, func.owner_nav, em); - return error.CodegenFail; - }, - }; + const code = code_buffer.items; const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code); const old_rva, const old_alignment = blk: { @@ -914,7 +906,7 @@ pub fn updateNav( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &macho_file.base, pt, zcu.navSrcLoc(nav_index), @@ -922,14 +914,8 @@ pub fn updateNav( &code_buffer, .{ .atom_index = sym_index }, ); + const code = code_buffer.items; - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(zcu.gpa, nav_index, em); - return; - }, - }; const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code); if (isThreadlocal(macho_file, nav_index)) try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code) @@ -1221,7 +1207,7 @@ fn lowerConst( const name_str = try self.addString(gpa, name); const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file); - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &macho_file.base, pt, src_loc, @@ -1229,10 +1215,7 @@ fn lowerConst( &code_buffer, .{ .atom_index = sym_index }, ); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return .{ .fail = em }, - }; + const code = code_buffer.items; const sym = &self.symbols.items[sym_index]; sym.out_n_sect = output_section_index; @@ -1367,7 +1350,6 @@ fn updateLazySymbol( ) !void { const zcu = pt.zcu; const gpa = zcu.gpa; - const diags = &macho_file.base.comp.link_diags; var required_alignment: Atom.Alignment = .none; var code_buffer = std.ArrayList(u8).init(gpa); @@ -1383,7 +1365,7 @@ fn updateLazySymbol( }; const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded; - const res = codegen.generateLazySymbol( + try codegen.generateLazySymbol( &macho_file.base, pt, src, @@ -1392,15 +1374,8 @@ fn updateLazySymbol( &code_buffer, .none, .{ .atom_index = symbol_index }, - ) catch |err| switch (err) { - error.CodegenFail => return error.LinkFailure, - error.OutOfMemory => return error.OutOfMemory, - else => |e| return diags.fail("failed to codegen symbol: {s}", .{@errorName(e)}), - }; - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}), - }; + ); + const code = code_buffer.items; const output_section_index = switch (lazy_sym.kind) { .code => macho_file.zig_text_sect_index.?, diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 1811fe63f9..15069b0bdc 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -465,7 +465,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); // TODO we need the symbol index for symbol in the table of locals for the containing atom - const res = try codegen.generateSymbol( + try codegen.generateSymbol( &self.base, pt, zcu.navSrcLoc(nav_index), @@ -473,10 +473,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde &code_buffer, .{ .atom_index = @intCast(atom_idx) }, ); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em), - }; + const code = code_buffer.items; try self.data_nav_table.ensureUnusedCapacity(gpa, 1); const duped_code = try gpa.dupe(u8, code); self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } }; @@ -1081,7 +1078,7 @@ fn updateLazySymbolAtom( // generate the code const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded; - const res = codegen.generateLazySymbol( + codegen.generateLazySymbol( &self.base, pt, src, @@ -1095,10 +1092,7 @@ fn updateLazySymbolAtom( error.CodegenFail => return error.LinkFailure, error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}), }; - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}), - }; + const code = code_buffer.items; // duped_code is freed when the atom is freed const duped_code = try gpa.dupe(u8, code); errdefer gpa.free(duped_code); @@ -1408,11 +1402,8 @@ pub fn lowerUav( gop.value_ptr.* = index; // we need to free name latex var code_buffer = std.ArrayList(u8).init(gpa); - const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index }); - const code = switch (res) { - .ok => code_buffer.items, - .fail => |em| return .{ .fail = em }, - }; + try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index }); + const code = code_buffer.items; const atom_ptr = self.getAtomPtr(index); atom_ptr.* = .{ .type = .d,