diff options
Diffstat (limited to 'compiler/rustc_abi/src')
| -rw-r--r-- | compiler/rustc_abi/src/layout.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_abi/src/lib.rs | 14 |
2 files changed, 25 insertions, 29 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 75c64aabfbb..aea88641f82 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -40,7 +40,7 @@ pub trait LayoutCalculator { largest_niche, align, size, - repr_align: None, + max_repr_align: None, unadjusted_abi_align: align.abi, } } @@ -124,7 +124,7 @@ pub trait LayoutCalculator { largest_niche: None, align: dl.i8_align, size: Size::ZERO, - repr_align: None, + max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, } } @@ -293,6 +293,7 @@ pub trait LayoutCalculator { } let mut align = dl.aggregate_align; + let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align.abi; let mut variant_layouts = variants @@ -302,6 +303,7 @@ pub trait LayoutCalculator { st.variants = Variants::Single { index: j }; align = align.max(st.align); + max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); Some(st) @@ -429,7 +431,7 @@ pub trait LayoutCalculator { largest_niche, size, align, - repr_align: repr.align, + max_repr_align, unadjusted_abi_align, }; @@ -465,6 +467,7 @@ pub trait LayoutCalculator { let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max); let mut align = dl.aggregate_align; + let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align.abi; let mut size = Size::ZERO; @@ -509,6 +512,7 @@ pub trait LayoutCalculator { } size = cmp::max(size, st.size); align = align.max(st.align); + max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); Some(st) }) @@ -703,7 +707,7 @@ pub trait LayoutCalculator { abi, align, size, - repr_align: repr.align, + max_repr_align, unadjusted_abi_align, }; @@ -744,6 +748,7 @@ pub trait LayoutCalculator { let dl = self.current_data_layout(); let dl = dl.borrow(); let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align }; + let mut max_repr_align = repr.align; // If all the non-ZST fields have the same ABI and union ABI optimizations aren't // disabled, we can use that common ABI for the union as a whole. @@ -761,6 +766,7 @@ pub trait LayoutCalculator { assert!(field.0.is_sized()); align = align.max(field.align()); + max_repr_align = max_repr_align.max(field.max_repr_align()); size = cmp::max(size, field.size()); if field.0.is_zst() { @@ -827,7 +833,7 @@ pub trait LayoutCalculator { largest_niche: None, align, size: size.align_to(align.abi), - repr_align: repr.align, + max_repr_align, unadjusted_abi_align, }) } @@ -849,6 +855,7 @@ fn univariant( ) -> Option<LayoutS> { let pack = repr.pack; 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(); if optimize && fields.len() > 1 { @@ -1017,6 +1024,7 @@ fn univariant( }; offset = offset.align_to(field_align.abi); align = align.max(field_align); + max_repr_align = max_repr_align.max(field.max_repr_align()); debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i] = offset; @@ -1133,28 +1141,16 @@ fn univariant( abi = Abi::Uninhabited; } - let (repr_align, unadjusted_abi_align) = if repr.transparent() { + let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { - Some(l) => (l.repr_align(), l.unadjusted_abi_align()), + Some(l) => l.unadjusted_abi_align(), None => { // `repr(transparent)` with all ZST fields. - // - // Using `None` for `repr_align` here is technically incorrect, since one of - // the ZSTs could have `repr(align(1))`. It's an interesting question, if you have - // `#{repr(transparent)] struct Foo((), ZstWithReprAlign1)`, which of those ZSTs' - // ABIs is forwarded by `repr(transparent)`? The answer to that question determines - // whether we should use `None` or `Some(align 1)` here. Thanksfully, two things - // together mean this doesn't matter: - // - You're not allowed to have a `repr(transparent)` struct that contains - // `repr(align)` > 1 ZSTs. See error E0691. - // - MSVC never treats requested align 1 differently from natural align 1. - // (And the `repr_align` field is only used on i686-windows, see `LayoutS` docs.) - // So just use `None` for now. - (None, align.abi) + align.abi } } } else { - (repr.align, unadjusted_abi_align) + unadjusted_abi_align }; Some(LayoutS { @@ -1164,7 +1160,7 @@ fn univariant( largest_niche, align, size, - repr_align, + max_repr_align, unadjusted_abi_align, }) } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index b2138dcefae..ef0c763ac20 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1532,10 +1532,10 @@ pub struct LayoutS { pub align: AbiAndPrefAlign, pub size: Size, - /// The alignment explicitly requested with `repr(align)`. + /// The largest alignment explicitly requested with `repr(align)` on this type or any field. /// Only used on i686-windows, where the argument passing ABI is different when alignment is /// requested, even if the requested alignment is equal to the natural alignment. - pub repr_align: Option<Align>, + pub max_repr_align: Option<Align>, /// The alignment the type would have, ignoring any `repr(align)` but including `repr(packed)`. /// Only used on aarch64-linux, where the argument passing ABI ignores the requested alignment @@ -1555,7 +1555,7 @@ impl LayoutS { largest_niche, size, align, - repr_align: None, + max_repr_align: None, unadjusted_abi_align: align.abi, } } @@ -1573,7 +1573,7 @@ impl fmt::Debug for LayoutS { fields, largest_niche, variants, - repr_align, + max_repr_align, unadjusted_abi_align, } = self; f.debug_struct("Layout") @@ -1583,7 +1583,7 @@ impl fmt::Debug for LayoutS { .field("fields", fields) .field("largest_niche", largest_niche) .field("variants", variants) - .field("repr_align", repr_align) + .field("max_repr_align", max_repr_align) .field("unadjusted_abi_align", unadjusted_abi_align) .finish() } @@ -1625,8 +1625,8 @@ impl<'a> Layout<'a> { self.0.0.size } - pub fn repr_align(self) -> Option<Align> { - self.0.0.repr_align + pub fn max_repr_align(self) -> Option<Align> { + self.0.0.max_repr_align } pub fn unadjusted_abi_align(self) -> Align { |
