Skip to content

Commit 3cc68ba

Browse files
committed
Auto merge of #46436 - eddyb:unpacked, r=arielb1,oli-obk
Detect unaligned fields via `aggregate.align < field.align`, instead of a `packed` flag. Closes #46423. cc @oli-obk
2 parents af57ace + 799a83c commit 3cc68ba

26 files changed

+518
-781
lines changed

src/librustc/mir/interpret/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@ mod value;
1010

1111
pub use self::error::{EvalError, EvalResult, EvalErrorKind};
1212

13-
pub use self::value::{PrimVal, PrimValKind, Value, Pointer, PtrAndAlign, bytes_to_f32, bytes_to_f64};
13+
pub use self::value::{PrimVal, PrimValKind, Value, Pointer, bytes_to_f32, bytes_to_f64};
1414

1515
use std::collections::BTreeMap;
16-
use ty::layout::HasDataLayout;
1716
use std::fmt;
18-
use ty::layout;
1917
use mir;
2018
use ty;
19+
use ty::layout::{self, Align, HasDataLayout};
2120
use middle::region;
2221
use std::iter;
2322

@@ -166,7 +165,7 @@ pub struct Allocation {
166165
/// Denotes undefined memory. Reading from undefined memory is forbidden in miri
167166
pub undef_mask: UndefMask,
168167
/// The alignment of the allocation to detect unaligned reads.
169-
pub align: u64,
168+
pub align: Align,
170169
}
171170

172171
impl Allocation {
@@ -177,7 +176,7 @@ impl Allocation {
177176
bytes: slice.to_owned(),
178177
relocations: BTreeMap::new(),
179178
undef_mask,
180-
align: 1,
179+
align: Align::from_bytes(1, 1).unwrap(),
181180
}
182181
}
183182
}

src/librustc/mir/interpret/value.rs

+2-28
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,11 @@
11
#![allow(unknown_lints)]
22

3-
use ty::layout::HasDataLayout;
3+
use ty::layout::{Align, HasDataLayout};
44

55
use super::{EvalResult, MemoryPointer, PointerArithmetic};
66
use syntax::ast::FloatTy;
77
use rustc_const_math::ConstFloat;
88

9-
#[derive(Copy, Clone, Debug)]
10-
pub struct PtrAndAlign {
11-
pub ptr: Pointer,
12-
/// Remember whether this place is *supposed* to be aligned.
13-
pub aligned: bool,
14-
}
15-
16-
impl PtrAndAlign {
17-
pub fn to_ptr<'tcx>(self) -> EvalResult<'tcx, MemoryPointer> {
18-
self.ptr.to_ptr()
19-
}
20-
pub fn offset<'tcx, C: HasDataLayout>(self, i: u64, cx: C) -> EvalResult<'tcx, Self> {
21-
Ok(PtrAndAlign {
22-
ptr: self.ptr.offset(i, cx)?,
23-
aligned: self.aligned,
24-
})
25-
}
26-
}
27-
289
pub fn bytes_to_f32(bits: u128) -> ConstFloat {
2910
ConstFloat {
3011
bits,
@@ -50,7 +31,7 @@ pub fn bytes_to_f64(bits: u128) -> ConstFloat {
5031
/// operations and fat pointers. This idea was taken from rustc's trans.
5132
#[derive(Clone, Copy, Debug)]
5233
pub enum Value {
53-
ByRef(PtrAndAlign),
34+
ByRef(Pointer, Align),
5435
ByVal(PrimVal),
5536
ByValPair(PrimVal, PrimVal),
5637
}
@@ -182,13 +163,6 @@ pub enum PrimValKind {
182163
Char,
183164
}
184165

185-
impl<'a, 'tcx: 'a> Value {
186-
#[inline]
187-
pub fn by_ref(ptr: Pointer) -> Self {
188-
Value::ByRef(PtrAndAlign { ptr, aligned: true })
189-
}
190-
}
191-
192166
impl<'tcx> PrimVal {
193167
pub fn from_u128(n: u128) -> Self {
194168
PrimVal::Bytes(n)

src/librustc/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ pub struct InterpretInterner<'tcx> {
895895
/// Allows checking whether a constant already has an allocation
896896
///
897897
/// The pointers are to the beginning of an `alloc_by_id` allocation
898-
alloc_cache: FxHashMap<interpret::GlobalId<'tcx>, interpret::PtrAndAlign>,
898+
alloc_cache: FxHashMap<interpret::GlobalId<'tcx>, interpret::Pointer>,
899899

900900
/// A cache for basic byte allocations keyed by their contents. This is used to deduplicate
901901
/// allocations for string and bytestring literals.
@@ -931,14 +931,14 @@ impl<'tcx> InterpretInterner<'tcx> {
931931
pub fn get_cached(
932932
&self,
933933
global_id: interpret::GlobalId<'tcx>,
934-
) -> Option<interpret::PtrAndAlign> {
934+
) -> Option<interpret::Pointer> {
935935
self.alloc_cache.get(&global_id).cloned()
936936
}
937937

938938
pub fn cache(
939939
&mut self,
940940
global_id: interpret::GlobalId<'tcx>,
941-
ptr: interpret::PtrAndAlign,
941+
ptr: interpret::Pointer,
942942
) {
943943
if let Some(old) = self.alloc_cache.insert(global_id, ptr) {
944944
bug!("tried to cache {:?}, but was already existing as {:#?}", global_id, old);

src/librustc/ty/layout.rs

+11-52
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,6 @@ pub enum Abi {
778778
Aggregate {
779779
/// If true, the size is exact, otherwise it's only a lower bound.
780780
sized: bool,
781-
packed: bool
782781
}
783782
}
784783

@@ -790,18 +789,7 @@ impl Abi {
790789
Abi::Scalar(_) |
791790
Abi::ScalarPair(..) |
792791
Abi::Vector { .. } => false,
793-
Abi::Aggregate { sized, .. } => !sized
794-
}
795-
}
796-
797-
/// Returns true if the fields of the layout are packed.
798-
pub fn is_packed(&self) -> bool {
799-
match *self {
800-
Abi::Uninhabited |
801-
Abi::Scalar(_) |
802-
Abi::ScalarPair(..) |
803-
Abi::Vector { .. } => false,
804-
Abi::Aggregate { packed, .. } => packed
792+
Abi::Aggregate { sized } => !sized
805793
}
806794
}
807795
}
@@ -1077,10 +1065,7 @@ impl<'a, 'tcx> LayoutDetails {
10771065
}
10781066

10791067
let size = min_size.abi_align(align);
1080-
let mut abi = Abi::Aggregate {
1081-
sized,
1082-
packed
1083-
};
1068+
let mut abi = Abi::Aggregate { sized };
10841069

10851070
// Unpack newtype ABIs and find scalar pairs.
10861071
if sized && size.bytes() > 0 {
@@ -1254,10 +1239,7 @@ impl<'a, 'tcx> LayoutDetails {
12541239
stride: element.size,
12551240
count
12561241
},
1257-
abi: Abi::Aggregate {
1258-
sized: true,
1259-
packed: false
1260-
},
1242+
abi: Abi::Aggregate { sized: true },
12611243
align: element.align,
12621244
size
12631245
})
@@ -1270,10 +1252,7 @@ impl<'a, 'tcx> LayoutDetails {
12701252
stride: element.size,
12711253
count: 0
12721254
},
1273-
abi: Abi::Aggregate {
1274-
sized: false,
1275-
packed: false
1276-
},
1255+
abi: Abi::Aggregate { sized: false },
12771256
align: element.align,
12781257
size: Size::from_bytes(0)
12791258
})
@@ -1285,10 +1264,7 @@ impl<'a, 'tcx> LayoutDetails {
12851264
stride: Size::from_bytes(1),
12861265
count: 0
12871266
},
1288-
abi: Abi::Aggregate {
1289-
sized: false,
1290-
packed: false
1291-
},
1267+
abi: Abi::Aggregate { sized: false },
12921268
align: dl.i8_align,
12931269
size: Size::from_bytes(0)
12941270
})
@@ -1302,7 +1278,7 @@ impl<'a, 'tcx> LayoutDetails {
13021278
let mut unit = univariant_uninterned(&[], &ReprOptions::default(),
13031279
StructKind::AlwaysSized)?;
13041280
match unit.abi {
1305-
Abi::Aggregate { ref mut sized, .. } => *sized = false,
1281+
Abi::Aggregate { ref mut sized } => *sized = false,
13061282
_ => bug!()
13071283
}
13081284
tcx.intern_layout(unit)
@@ -1418,10 +1394,7 @@ impl<'a, 'tcx> LayoutDetails {
14181394
return Ok(tcx.intern_layout(LayoutDetails {
14191395
variants: Variants::Single { index: 0 },
14201396
fields: FieldPlacement::Union(variants[0].len()),
1421-
abi: Abi::Aggregate {
1422-
sized: true,
1423-
packed
1424-
},
1397+
abi: Abi::Aggregate { sized: true },
14251398
align,
14261399
size: size.abi_align(align)
14271400
}));
@@ -1525,15 +1498,10 @@ impl<'a, 'tcx> LayoutDetails {
15251498
let abi = if offset.bytes() == 0 && niche.value.size(dl) == size {
15261499
Abi::Scalar(niche.clone())
15271500
} else {
1528-
let mut packed = st[i].abi.is_packed();
15291501
if offset.abi_align(niche_align) != offset {
1530-
packed = true;
15311502
niche_align = dl.i8_align;
15321503
}
1533-
Abi::Aggregate {
1534-
sized: true,
1535-
packed
1536-
}
1504+
Abi::Aggregate { sized: true }
15371505
};
15381506
align = align.max(niche_align);
15391507

@@ -1681,10 +1649,7 @@ impl<'a, 'tcx> LayoutDetails {
16811649
let abi = if discr.value.size(dl) == size {
16821650
Abi::Scalar(discr.clone())
16831651
} else {
1684-
Abi::Aggregate {
1685-
sized: true,
1686-
packed: false
1687-
}
1652+
Abi::Aggregate { sized: true }
16881653
};
16891654
tcx.intern_layout(LayoutDetails {
16901655
variants: Variants::Tagged {
@@ -2277,19 +2242,14 @@ impl<'a, 'tcx> TyLayout<'tcx> {
22772242
self.abi.is_unsized()
22782243
}
22792244

2280-
/// Returns true if the fields of the layout are packed.
2281-
pub fn is_packed(&self) -> bool {
2282-
self.abi.is_packed()
2283-
}
2284-
22852245
/// Returns true if the type is a ZST and not unsized.
22862246
pub fn is_zst(&self) -> bool {
22872247
match self.abi {
22882248
Abi::Uninhabited => true,
22892249
Abi::Scalar(_) |
22902250
Abi::ScalarPair(..) |
22912251
Abi::Vector { .. } => false,
2292-
Abi::Aggregate { sized, .. } => sized && self.size.bytes() == 0
2252+
Abi::Aggregate { sized } => sized && self.size.bytes() == 0
22932253
}
22942254
}
22952255

@@ -2452,8 +2412,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Abi {
24522412
element.hash_stable(hcx, hasher);
24532413
count.hash_stable(hcx, hasher);
24542414
}
2455-
Aggregate { packed, sized } => {
2456-
packed.hash_stable(hcx, hasher);
2415+
Aggregate { sized } => {
24572416
sized.hash_stable(hcx, hasher);
24582417
}
24592418
}

0 commit comments

Comments
 (0)