don't inhibit random field reordering on repr(packed(1))
This commit is contained in:
parent
e875391458
commit
37aeb75eb6
6 changed files with 14 additions and 19 deletions
|
@ -970,7 +970,7 @@ fn univariant<
|
|||
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||
let mut max_repr_align = repr.align;
|
||||
let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
|
||||
let optimize = !repr.inhibit_struct_field_reordering_opt();
|
||||
let optimize = !repr.inhibit_struct_field_reordering();
|
||||
if optimize && fields.len() > 1 {
|
||||
let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
|
||||
let optimizing = &mut inverse_memory_index.raw[..end];
|
||||
|
@ -1007,13 +1007,15 @@ fn univariant<
|
|||
// Calculates a sort key to group fields by their alignment or possibly some
|
||||
// size-derived pseudo-alignment.
|
||||
let alignment_group_key = |layout: &F| {
|
||||
// The two branches here return values that cannot be meaningfully compared with
|
||||
// each other. However, we know that consistently for all executions of
|
||||
// `alignment_group_key`, one or the other branch will be taken, so this is okay.
|
||||
if let Some(pack) = pack {
|
||||
// Return the packed alignment in bytes.
|
||||
layout.align.abi.min(pack).bytes()
|
||||
} else {
|
||||
// Returns `log2(effective-align)`. This is ok since `pack` applies to all
|
||||
// fields equally. The calculation assumes that size is an integer multiple of
|
||||
// align, except for ZSTs.
|
||||
// Returns `log2(effective-align)`. The calculation assumes that size is an
|
||||
// integer multiple of align, except for ZSTs.
|
||||
let align = layout.align.abi.bytes();
|
||||
let size = layout.size.bytes();
|
||||
let niche_size = layout.largest_niche.map(|n| n.available(dl)).unwrap_or(0);
|
||||
|
|
|
@ -137,23 +137,16 @@ impl ReprOptions {
|
|||
self.c() || self.int.is_some()
|
||||
}
|
||||
|
||||
/// Returns `true` if this `#[repr()]` should inhibit struct field reordering
|
||||
/// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
|
||||
pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
|
||||
if let Some(pack) = self.pack {
|
||||
if pack.bytes() == 1 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `#[repr()]` guarantees a fixed field order,
|
||||
/// e.g. `repr(C)` or `repr(<int>)`.
|
||||
pub fn inhibit_struct_field_reordering(&self) -> bool {
|
||||
self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
|
||||
}
|
||||
|
||||
/// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
|
||||
/// was enabled for its declaration crate.
|
||||
pub fn can_randomize_type_layout(&self) -> bool {
|
||||
!self.inhibit_struct_field_reordering_opt()
|
||||
&& self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
|
||||
!self.inhibit_struct_field_reordering() && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
|
||||
}
|
||||
|
||||
/// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue