authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-09-09 08:14:27-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-09-10 13:06:08-04:00
logfaafc4132731e854a471ad4c4bb231efb525ea9a
treee83d85f4e99df16c3d479344712c43963f67d6ed
parent0f0142527a0f2adc8f2348f0c97db80b0a24d330

Dwarf: prevent crash on missing field inits

Workaround for #21362

1 files changed, 51 insertions(+), 27 deletions(-)

src/link/Dwarf.zig+51-27
...@@ -2643,8 +2643,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2643,8 +2643,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2643 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);2643 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
2644 for (0..loaded_struct.field_types.len) |field_index| {2644 for (0..loaded_struct.field_types.len) |field_index| {
2645 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);2645 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2646 const field_init = loaded_struct.fieldInit(ip, field_index);2646 const field_init = if (loaded_struct.haveFieldInits(ip))
2647 assert(!(is_comptime and field_init == .none));2647 loaded_struct.fieldInit(ip, field_index)
2648 else
2649 .none;
2648 try wip_nav.abbrevCode(if (is_comptime)2650 try wip_nav.abbrevCode(if (is_comptime)
2649 .struct_field_comptime2651 .struct_field_comptime
2650 else if (field_init != .none)2652 else if (field_init != .none)
...@@ -2656,14 +2658,20 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2656,14 +2658,20 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2656 defer dwarf.gpa.free(field_name);2658 defer dwarf.gpa.free(field_name);
2657 try wip_nav.strp(field_name);2659 try wip_nav.strp(field_name);
2658 }2660 }
2659 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);2661 if (is_comptime and field_init == .none) {
2660 try wip_nav.refType(field_type);2662 // workaround frontend bug
2661 if (!is_comptime) {2663 try wip_nav.refType(Type.void);
2662 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);2664 try wip_nav.blockValue(nav_src_loc, Value.void);
2663 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse2665 } else {
2664 field_type.abiAlignment(zcu).toByteUnits().?);2666 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2667 try wip_nav.refType(field_type);
2668 if (!is_comptime) {
2669 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
2670 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
2671 field_type.abiAlignment(zcu).toByteUnits().?);
2672 }
2673 if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init));
2665 }2674 }
2666 if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init));
2667 }2675 }
2668 try uleb128(diw, @intFromEnum(AbbrevCode.null));2676 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2669 }2677 }
...@@ -3503,8 +3511,10 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3503,8 +3511,10 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3503 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);3511 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3504 for (0..loaded_struct.field_types.len) |field_index| {3512 for (0..loaded_struct.field_types.len) |field_index| {
3505 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);3513 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
3506 const field_init = loaded_struct.fieldInit(ip, field_index);3514 const field_init = if (loaded_struct.haveFieldInits(ip))
3507 assert(!(is_comptime and field_init == .none));3515 loaded_struct.fieldInit(ip, field_index)
3516 else
3517 .none;
3508 try wip_nav.abbrevCode(if (is_comptime)3518 try wip_nav.abbrevCode(if (is_comptime)
3509 .struct_field_comptime3519 .struct_field_comptime
3510 else if (field_init != .none)3520 else if (field_init != .none)
...@@ -3516,14 +3526,20 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3516,14 +3526,20 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3516 defer dwarf.gpa.free(field_name);3526 defer dwarf.gpa.free(field_name);
3517 try wip_nav.strp(field_name);3527 try wip_nav.strp(field_name);
3518 }3528 }
3519 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);3529 if (is_comptime and field_init == .none) {
3520 try wip_nav.refType(field_type);3530 // workaround frontend bug
3521 if (!is_comptime) {3531 try wip_nav.refType(Type.void);
3522 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);3532 try wip_nav.blockValue(ty_src_loc, Value.void);
3523 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse3533 } else {
3524 field_type.abiAlignment(zcu).toByteUnits().?);3534 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3535 try wip_nav.refType(field_type);
3536 if (!is_comptime) {
3537 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
3538 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
3539 field_type.abiAlignment(zcu).toByteUnits().?);
3540 }
3541 if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
3525 }3542 }
3526 if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
3527 }3543 }
3528 try uleb128(diw, @intFromEnum(AbbrevCode.null));3544 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3529 }3545 }
...@@ -3579,8 +3595,10 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3579,8 +3595,10 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3579 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);3595 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3580 for (0..loaded_struct.field_types.len) |field_index| {3596 for (0..loaded_struct.field_types.len) |field_index| {
3581 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);3597 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
3582 const field_init = loaded_struct.fieldInit(ip, field_index);3598 const field_init = if (loaded_struct.haveFieldInits(ip))
3583 assert(!(is_comptime and field_init == .none));3599 loaded_struct.fieldInit(ip, field_index)
3600 else
3601 .none;
3584 try wip_nav.abbrevCode(if (is_comptime)3602 try wip_nav.abbrevCode(if (is_comptime)
3585 .struct_field_comptime3603 .struct_field_comptime
3586 else if (field_init != .none)3604 else if (field_init != .none)
...@@ -3592,14 +3610,20 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3592,14 +3610,20 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3592 defer dwarf.gpa.free(field_name);3610 defer dwarf.gpa.free(field_name);
3593 try wip_nav.strp(field_name);3611 try wip_nav.strp(field_name);
3594 }3612 }
3595 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);3613 if (is_comptime and field_init == .none) {
3596 try wip_nav.refType(field_type);3614 // workaround frontend bug
3597 if (!is_comptime) {3615 try wip_nav.refType(Type.void);
3598 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);3616 try wip_nav.blockValue(ty_src_loc, Value.void);
3599 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse3617 } else {
3600 field_type.abiAlignment(zcu).toByteUnits().?);3618 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3619 try wip_nav.refType(field_type);
3620 if (!is_comptime) {
3621 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
3622 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
3623 field_type.abiAlignment(zcu).toByteUnits().?);
3624 }
3625 if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
3601 }3626 }
3602 if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init));
3603 }3627 }
3604 try uleb128(diw, @intFromEnum(AbbrevCode.null));3628 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3605 }3629 }