Skip to content

Commit 797a82f

Browse files
committed
rustc_codegen_llvm: use different sizes for usize and pointers when generating debuginfo for vtables
1 parent 02c939e commit 797a82f

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,32 +1440,40 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
14401440
) -> &'ll DIType {
14411441
let tcx = cx.tcx;
14421442

1443-
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
1444-
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
1445-
let trait_ref = tcx.erase_and_anonymize_regions(trait_ref);
1446-
1447-
tcx.vtable_entries(trait_ref)
1448-
} else {
1449-
TyCtxt::COMMON_VTABLE_ENTRIES
1450-
};
1451-
14521443
// All function pointers are described as opaque pointers. This could be improved in the future
14531444
// by describing them as actual function pointers.
14541445
let void_pointer_ty = Ty::new_imm_ptr(tcx, tcx.types.unit);
14551446
let void_pointer_type_di_node = type_di_node(cx, void_pointer_ty);
14561447
let usize_di_node = type_di_node(cx, tcx.types.usize);
1448+
let usize_layout = cx.layout_of(tcx.types.usize);
14571449
let pointer_layout = cx.layout_of(void_pointer_ty);
14581450
let pointer_size = pointer_layout.size;
14591451
let pointer_align = pointer_layout.align.abi;
1460-
// If `usize` is not pointer-sized and -aligned then the size and alignment computations
1461-
// for the vtable as a whole would be wrong. Let's make sure this holds even on weird
1462-
// platforms.
1463-
assert_eq!(cx.size_and_align_of(tcx.types.usize), (pointer_size, pointer_align));
1452+
let size_zero = Size::from_bits(0);
1453+
1454+
let vtable_entry_size = |&entry| match entry {
1455+
ty::VtblEntry::MetadataSize | ty::VtblEntry::MetadataAlign => cx.size_of(tcx.types.usize),
1456+
ty::VtblEntry::MetadataDropInPlace
1457+
| ty::VtblEntry::Method(_)
1458+
| ty::VtblEntry::TraitVPtr(_) => pointer_size,
1459+
ty::VtblEntry::Vacant => size_zero,
1460+
};
1461+
1462+
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
1463+
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
1464+
let trait_ref = tcx.erase_and_anonymize_regions(trait_ref);
1465+
1466+
tcx.vtable_entries(trait_ref)
1467+
} else {
1468+
TyCtxt::COMMON_VTABLE_ENTRIES
1469+
};
14641470

14651471
let vtable_type_name =
14661472
compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::Type);
14671473
let unique_type_id = UniqueTypeId::for_vtable_ty(tcx, ty, poly_trait_ref);
1468-
let size = pointer_size * vtable_entries.len() as u64;
1474+
let entries_size = vtable_entries.iter().map(vtable_entry_size).collect::<Vec<_>>();
1475+
let size = entries_size.iter().fold(size_zero, |a, s| a + *s);
1476+
let mut field_offset = size_zero;
14691477

14701478
// This gets mapped to a DW_AT_containing_type attribute which allows GDB to correlate
14711479
// the vtable to the type it is for.
@@ -1488,32 +1496,33 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
14881496
.iter()
14891497
.enumerate()
14901498
.filter_map(|(index, vtable_entry)| {
1491-
let (field_name, field_type_di_node) = match vtable_entry {
1499+
let (field_name, layout, field_type_di_node) = match vtable_entry {
14921500
ty::VtblEntry::MetadataDropInPlace => {
1493-
("drop_in_place".to_string(), void_pointer_type_di_node)
1501+
("drop_in_place".to_string(), pointer_layout, void_pointer_type_di_node)
14941502
}
14951503
ty::VtblEntry::Method(_) => {
14961504
// Note: This code does not try to give a proper name to each method
14971505
// because their might be multiple methods with the same name
14981506
// (coming from different traits).
1499-
(format!("__method{index}"), void_pointer_type_di_node)
1507+
(format!("__method{index}"), pointer_layout, void_pointer_type_di_node)
15001508
}
15011509
ty::VtblEntry::TraitVPtr(_) => {
1502-
(format!("__super_trait_ptr{index}"), void_pointer_type_di_node)
1510+
(format!("__super_trait_ptr{index}"), pointer_layout, void_pointer_type_di_node)
15031511
}
1504-
ty::VtblEntry::MetadataAlign => ("align".to_string(), usize_di_node),
1505-
ty::VtblEntry::MetadataSize => ("size".to_string(), usize_di_node),
1512+
ty::VtblEntry::MetadataAlign => ("align".to_string(), usize_layout, usize_di_node),
1513+
ty::VtblEntry::MetadataSize => ("size".to_string(), usize_layout, usize_di_node),
15061514
ty::VtblEntry::Vacant => return None,
15071515
};
15081516

1509-
let field_offset = pointer_size * index as u64;
1517+
let current_offset = field_offset;
1518+
field_offset += entries_size[index];
15101519

15111520
Some(build_field_di_node(
15121521
cx,
15131522
vtable_type_di_node,
15141523
&field_name,
1515-
pointer_layout,
1516-
field_offset,
1524+
layout,
1525+
current_offset,
15171526
DIFlags::FlagZero,
15181527
field_type_di_node,
15191528
None,

0 commit comments

Comments
 (0)