authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-04 05:41:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-05 21:42:33-04:00
log470e2b63d9f28984f20c66ee6730fa30241bae5a
tree9348579abf5fa0a00a18aefd41ecc62f5cd34634
parent596e0bd47b8482b0c002cddd8d5f895d77f5ea27

Dwarf: handle undefined type values

Closes #23461

3 files changed, 32 insertions(+), 13 deletions(-)

src/Air/types_resolved.zig+1
...@@ -439,6 +439,7 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {...@@ -439,6 +439,7 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
439pub fn checkVal(val: Value, zcu: *Zcu) bool {439pub fn checkVal(val: Value, zcu: *Zcu) bool {
440 const ty = val.typeOf(zcu);440 const ty = val.typeOf(zcu);
441 if (!checkType(ty, zcu)) return false;441 if (!checkType(ty, zcu)) return false;
442 if (val.isUndef(zcu)) return true;
442 if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false;443 if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false;
443 // Check for lazy values444 // Check for lazy values
444 switch (zcu.intern_pool.indexToKey(val.toIntern())) {445 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
src/link/Dwarf.zig+24-13
...@@ -1438,7 +1438,7 @@ pub const WipNav = struct {...@@ -1438,7 +1438,7 @@ pub const WipNav = struct {
1438 debug_info: std.ArrayListUnmanaged(u8),1438 debug_info: std.ArrayListUnmanaged(u8),
1439 debug_line: std.ArrayListUnmanaged(u8),1439 debug_line: std.ArrayListUnmanaged(u8),
1440 debug_loclists: std.ArrayListUnmanaged(u8),1440 debug_loclists: std.ArrayListUnmanaged(u8),
1441 pending_lazy: std.ArrayListUnmanaged(InternPool.Index),1441 pending_lazy: PendingLazy,
14421442
1443 pub fn deinit(wip_nav: *WipNav) void {1443 pub fn deinit(wip_nav: *WipNav) void {
1444 const gpa = wip_nav.dwarf.gpa;1444 const gpa = wip_nav.dwarf.gpa;
...@@ -1447,7 +1447,8 @@ pub const WipNav = struct {...@@ -1447,7 +1447,8 @@ pub const WipNav = struct {
1447 wip_nav.debug_info.deinit(gpa);1447 wip_nav.debug_info.deinit(gpa);
1448 wip_nav.debug_line.deinit(gpa);1448 wip_nav.debug_line.deinit(gpa);
1449 wip_nav.debug_loclists.deinit(gpa);1449 wip_nav.debug_loclists.deinit(gpa);
1450 wip_nav.pending_lazy.deinit(gpa);1450 wip_nav.pending_lazy.types.deinit(gpa);
1451 wip_nav.pending_lazy.values.deinit(gpa);
1451 }1452 }
14521453
1453 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {1454 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {
...@@ -1834,7 +1835,7 @@ pub const WipNav = struct {...@@ -1834,7 +1835,7 @@ pub const WipNav = struct {
1834 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1835 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1835 const entry = try wip_nav.dwarf.addCommonEntry(unit);1836 const entry = try wip_nav.dwarf.addCommonEntry(unit);
1836 gop.value_ptr.* = entry;1837 gop.value_ptr.* = entry;
1837 if (maybe_inst_index == null) try wip_nav.pending_lazy.append(wip_nav.dwarf.gpa, ty.toIntern());1838 if (maybe_inst_index == null) try wip_nav.pending_lazy.types.append(wip_nav.dwarf.gpa, ty.toIntern());
1838 return .{ unit, entry };1839 return .{ unit, entry };
1839 }1840 }
18401841
...@@ -1848,14 +1849,16 @@ pub const WipNav = struct {...@@ -1848,14 +1849,16 @@ pub const WipNav = struct {
1848 const ip = &zcu.intern_pool;1849 const ip = &zcu.intern_pool;
1849 const ty = value.typeOf(zcu);1850 const ty = value.typeOf(zcu);
1850 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);1851 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
1851 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());1852 if (!value.isUndef(zcu)) {
1852 if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);1853 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
1854 if (ip.isFunctionType(ty.toIntern())) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
1855 }
1853 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());1856 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
1854 const unit: Unit.Index = .main;1857 const unit: Unit.Index = .main;
1855 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1858 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1856 const entry = try wip_nav.dwarf.addCommonEntry(unit);1859 const entry = try wip_nav.dwarf.addCommonEntry(unit);
1857 gop.value_ptr.* = entry;1860 gop.value_ptr.* = entry;
1858 try wip_nav.pending_lazy.append(wip_nav.dwarf.gpa, value.toIntern());1861 try wip_nav.pending_lazy.values.append(wip_nav.dwarf.gpa, value.toIntern());
1859 return .{ unit, entry };1862 return .{ unit, entry };
1860 }1863 }
18611864
...@@ -2051,12 +2054,20 @@ pub const WipNav = struct {...@@ -2051,12 +2054,20 @@ pub const WipNav = struct {
2051 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);2054 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);
2052 }2055 }
20532056
2057 const PendingLazy = struct {
2058 types: std.ArrayListUnmanaged(InternPool.Index),
2059 values: std.ArrayListUnmanaged(InternPool.Index),
2060
2061 const empty: PendingLazy = .{ .types = .empty, .values = .empty };
2062 };
2063
2054 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {2064 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {
2055 const ip = &wip_nav.pt.zcu.intern_pool;2065 while (true) if (wip_nav.pending_lazy.types.pop()) |pending_ty|
2056 while (wip_nav.pending_lazy.pop()) |val| switch (ip.typeOf(val)) {2066 try wip_nav.dwarf.updateLazyType(wip_nav.pt, src_loc, pending_ty, &wip_nav.pending_lazy)
2057 .type_type => try wip_nav.dwarf.updateLazyType(wip_nav.pt, src_loc, val, &wip_nav.pending_lazy),2067 else if (wip_nav.pending_lazy.values.pop()) |pending_val|
2058 else => try wip_nav.dwarf.updateLazyValue(wip_nav.pt, src_loc, val, &wip_nav.pending_lazy),2068 try wip_nav.dwarf.updateLazyValue(wip_nav.pt, src_loc, pending_val, &wip_nav.pending_lazy)
2059 };2069 else
2070 break;
2060 }2071 }
2061};2072};
20622073
...@@ -3133,7 +3144,7 @@ fn updateLazyType(...@@ -3133,7 +3144,7 @@ fn updateLazyType(
3133 pt: Zcu.PerThread,3144 pt: Zcu.PerThread,
3134 src_loc: Zcu.LazySrcLoc,3145 src_loc: Zcu.LazySrcLoc,
3135 type_index: InternPool.Index,3146 type_index: InternPool.Index,
3136 pending_lazy: *std.ArrayListUnmanaged(InternPool.Index),3147 pending_lazy: *WipNav.PendingLazy,
3137) UpdateError!void {3148) UpdateError!void {
3138 const zcu = pt.zcu;3149 const zcu = pt.zcu;
3139 const ip = &zcu.intern_pool;3150 const ip = &zcu.intern_pool;
...@@ -3635,7 +3646,7 @@ fn updateLazyValue(...@@ -3635,7 +3646,7 @@ fn updateLazyValue(
3635 pt: Zcu.PerThread,3646 pt: Zcu.PerThread,
3636 src_loc: Zcu.LazySrcLoc,3647 src_loc: Zcu.LazySrcLoc,
3637 value_index: InternPool.Index,3648 value_index: InternPool.Index,
3638 pending_lazy: *std.ArrayListUnmanaged(InternPool.Index),3649 pending_lazy: *WipNav.PendingLazy,
3639) UpdateError!void {3650) UpdateError!void {
3640 const zcu = pt.zcu;3651 const zcu = pt.zcu;
3641 const ip = &zcu.intern_pool;3652 const ip = &zcu.intern_pool;
test/behavior/type.zig+7
...@@ -808,3 +808,10 @@ test "reify enum where fields refers to part of array" {...@@ -808,3 +808,10 @@ test "reify enum where fields refers to part of array" {
808 try testing.expect(b == .bar);808 try testing.expect(b == .bar);
809 try testing.expect(a != b);809 try testing.expect(a != b);
810}810}
811
812test "undefined type value" {
813 const S = struct {
814 const undef_type: type = undefined;
815 };
816 comptime assert(@TypeOf(S.undef_type) == type);
817}