authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-01 14:43:51-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
log549c32e138afc9d6d9883d9a31d103e6ee18f24f
tree2bbe6d6b2ed50d0604cc290d08f2eae089a15f10
parentdd01fe96d36a7cf898f04a55b820174d76588a32

Dwarf2: fix non-deterministic generic function debug info


1 files changed, 38 insertions(+), 64 deletions(-)

src/link/Dwarf2.zig+38-64
...@@ -1936,9 +1936,8 @@ pub fn updateComptimeNav(...@@ -1936,9 +1936,8 @@ pub fn updateComptimeNav(
1936 log.debug("updateComptimeNav({f})", .{nav.fqn.fmt(ip)});1936 log.debug("updateComptimeNav({f})", .{nav.fqn.fmt(ip)});
1937 const inst_info = nav.srcInst(ip).resolveFull(ip).?;1937 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
1938 const nav_val: Value = .fromInterned(nav.resolved.?.value);1938 const nav_val: Value = .fromInterned(nav.resolved.?.value);
1939 const file = zcu.fileByIndex(inst_info.file);1939 const zf = zcu.fileByIndex(inst_info.file);
1940 const zir = &file.zir.?;1940 const decl = zf.zir.?.getDeclaration(inst_info.inst);
1941 const decl = zir.getDeclaration(inst_info.inst);
1942 switch (decl.kind) {1941 switch (decl.kind) {
1943 .unnamed_test, .@"test", .decltest => return,1942 .unnamed_test, .@"test", .decltest => return,
1944 .@"comptime", .@"const", .@"var" => {},1943 .@"comptime", .@"const", .@"var" => {},
...@@ -1977,31 +1976,8 @@ pub fn updateComptimeNav(...@@ -1977,31 +1976,8 @@ pub fn updateComptimeNav(
1977 return;1976 return;
1978 },1977 },
1979 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {1978 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {
1980 const fi = try dwarf.getFunc(func.owner_nav);1979 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());
1981 const f = fi.get(dwarf);1980 break :done;
1982 switch (f.state) {
1983 .unresolved => {},
1984 .resolved => return,
1985 }
1986 const elf = dwarf.lf.cast(.elf2).?;
1987 const debug_info_ni = f.debug_info_ni.unwrap().?;
1988 var di_nw: MappedFile.Node.Writer = undefined;
1989 debug_info_ni.writer(zcu.gpa, &elf.mf, &di_nw);
1990 defer di_nw.deinit();
1991 elf.resetNodeRelocs(debug_info_ni);
1992 dwarf.genDeclFuncGeneric(
1993 pt,
1994 &di_nw,
1995 zir,
1996 .fromInterned(ip.namespacePtr(nav.analysis.?.namespace).owner_type),
1997 &decl,
1998 &ip.indexToKey(func.ty).func_type,
1999 nav.name.toSlice(ip),
2000 zir.getParamBody(func.zir_body_inst.resolve(ip).?),
2001 ) catch |err| switch (err) {
2002 else => |e| return e,
2003 error.WriteFailed => return dwarf.reportWriteError(&di_nw),
2004 };
2005 } else return,1981 } else return,
20061982
2007 else => return,1983 else => return,
...@@ -2011,42 +1987,6 @@ pub fn updateComptimeNav(...@@ -2011,42 +1987,6 @@ pub fn updateComptimeNav(
2011 }1987 }
2012 try dwarf.const_pool.flushPending(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? });1988 try dwarf.const_pool.flushPending(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? });
2013}1989}
2014fn genDeclFuncGeneric(
2015 dwarf: *Dwarf,
2016 pt: Zcu.PerThread,
2017 di_nw: *MappedFile.Node.Writer,
2018 zir: *const std.zig.Zir,
2019 parent_ty: Type,
2020 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2021 fn_ty: *const InternPool.Key.FuncType,
2022 name: []const u8,
2023 param_body: []const std.zig.Zir.Inst.Index,
2024) link.EmitError!void {
2025 const zcu = pt.zcu;
2026 const diw = &di_nw.interface;
2027 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func_generic));
2028 try dwarf.refType(pt, di_nw, parent_ty);
2029 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2030 try diw.writeUleb128(decl.src_column + 1);
2031 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2032 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2033 try dwarf.refType(pt, di_nw, .fromInterned(fn_ty.return_type));
2034 var param_index: u32 = 0;
2035 for (param_body) |param_inst| {
2036 switch (zir.getParamName(param_inst) orelse break) {
2037 .empty => try diw.writeUleb128(try dwarf.refAbbrevCode(.unnamed_param)),
2038 else => |param_name| {
2039 try diw.writeUleb128(try dwarf.refAbbrevCode(.param));
2040 try dwarf.strp(&dwarf.debug_str, di_nw, zir.nullTerminatedString(param_name));
2041 },
2042 }
2043 try dwarf.refType(pt, di_nw, .fromInterned(fn_ty.param_types.get(&zcu.intern_pool)[param_index]));
2044 param_index += 1;
2045 }
2046 if (fn_ty.is_var_args) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_var_args));
2047 try diw.writeUleb128(@backingInt(AbbrevCode.null));
2048 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
2049}
20501990
2051pub fn addConst(1991pub fn addConst(
2052 dwarf: *Dwarf,1992 dwarf: *Dwarf,
...@@ -2858,6 +2798,40 @@ fn updateConstInner(...@@ -2858,6 +2798,40 @@ fn updateConstInner(
2858 },2798 },
28592799
2860 else => return,2800 else => return,
2801 .func => |func| {
2802 const fi = try dwarf.getFunc(func.owner_nav);
2803 switch (fi.get(dwarf).state) {
2804 .unresolved => {},
2805 .resolved => return,
2806 }
2807 const fn_ty = ip.indexToKey(func.ty).func_type;
2808 const nav = ip.getNav(func.owner_nav);
2809 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
2810 const zf = zcu.fileByIndex(inst_info.file);
2811 const decl = zf.zir.?.getDeclaration(inst_info.inst);
2812 const parent_ty: Type = .fromInterned(ip.namespacePtr(nav.analysis.?.namespace).owner_type);
2813 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func_generic));
2814 try dwarf.refType(pt, di_nw, parent_ty);
2815 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2816 try diw.writeUleb128(decl.src_column + 1);
2817 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2818 try dwarf.strp(&dwarf.debug_str, di_nw, nav.name.toSlice(ip));
2819 try dwarf.refType(pt, di_nw, .fromInterned(fn_ty.return_type));
2820 var param_index: u32 = 0;
2821 for (zf.zir.?.getParamBody(func.zir_body_inst.resolve(ip).?)) |param_inst| {
2822 switch (zf.zir.?.getParamName(param_inst) orelse break) {
2823 .empty => try diw.writeUleb128(try dwarf.refAbbrevCode(.unnamed_param)),
2824 else => |param_name| {
2825 try diw.writeUleb128(try dwarf.refAbbrevCode(.param));
2826 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(param_name));
2827 },
2828 }
2829 try dwarf.refType(pt, di_nw, .fromInterned(fn_ty.param_types.get(&zcu.intern_pool)[param_index]));
2830 param_index += 1;
2831 }
2832 if (fn_ty.is_var_args) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_var_args));
2833 try diw.writeUleb128(@backingInt(AbbrevCode.null));
2834 },
28612835
2862 .memoized_call => unreachable, // not a value2836 .memoized_call => unreachable, // not a value
2863 }2837 }