interpret: ImmTy: tighten sanity checks in offset logic
This commit is contained in:
parent
edbc000fa4
commit
493cf6a7e9
@ -319,6 +319,7 @@ fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayo
|
|||||||
// some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
|
// some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
|
||||||
// to detect those here and also give them no data
|
// to detect those here and also give them no data
|
||||||
_ if matches!(layout.abi, Abi::Aggregate { .. })
|
_ if matches!(layout.abi, Abi::Aggregate { .. })
|
||||||
|
&& matches!(layout.variants, abi::Variants::Single { .. })
|
||||||
&& matches!(&layout.fields, abi::FieldsShape::Arbitrary { offsets, .. } if offsets.len() == 0) =>
|
&& matches!(&layout.fields, abi::FieldsShape::Arbitrary { offsets, .. } if offsets.len() == 0) =>
|
||||||
{
|
{
|
||||||
Immediate::Uninit
|
Immediate::Uninit
|
||||||
@ -328,8 +329,9 @@ fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayo
|
|||||||
assert_eq!(offset.bytes(), 0);
|
assert_eq!(offset.bytes(), 0);
|
||||||
assert!(
|
assert!(
|
||||||
match (self.layout.abi, layout.abi) {
|
match (self.layout.abi, layout.abi) {
|
||||||
(Abi::Scalar(..), Abi::Scalar(..)) => true,
|
(Abi::Scalar(l), Abi::Scalar(r)) => l.size(cx) == r.size(cx),
|
||||||
(Abi::ScalarPair(..), Abi::ScalarPair(..)) => true,
|
(Abi::ScalarPair(l1, l2), Abi::ScalarPair(r1, r2)) =>
|
||||||
|
l1.size(cx) == r1.size(cx) && l2.size(cx) == r2.size(cx),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
"cannot project into {} immediate with equally-sized field {}\nouter ABI: {:#?}\nfield ABI: {:#?}",
|
"cannot project into {} immediate with equally-sized field {}\nouter ABI: {:#?}\nfield ABI: {:#?}",
|
||||||
@ -344,16 +346,23 @@ fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayo
|
|||||||
(Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
|
(Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
|
||||||
assert_matches!(layout.abi, Abi::Scalar(..));
|
assert_matches!(layout.abi, Abi::Scalar(..));
|
||||||
Immediate::from(if offset.bytes() == 0 {
|
Immediate::from(if offset.bytes() == 0 {
|
||||||
debug_assert_eq!(layout.size, a.size(cx));
|
// It is "okay" to transmute from `usize` to a pointer (GVN relies on that).
|
||||||
|
// So only compare the size.
|
||||||
|
assert_eq!(layout.size, a.size(cx));
|
||||||
a_val
|
a_val
|
||||||
} else {
|
} else {
|
||||||
debug_assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi));
|
assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi));
|
||||||
debug_assert_eq!(layout.size, b.size(cx));
|
assert_eq!(layout.size, b.size(cx));
|
||||||
b_val
|
b_val
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// everything else is a bug
|
// everything else is a bug
|
||||||
_ => bug!("invalid field access on immediate {}, layout {:#?}", self, self.layout),
|
_ => bug!(
|
||||||
|
"invalid field access on immediate {} at offset {}, original layout {:#?}",
|
||||||
|
self,
|
||||||
|
offset.bytes(),
|
||||||
|
self.layout
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
ImmTy::from_immediate(inner_val, layout)
|
ImmTy::from_immediate(inner_val, layout)
|
||||||
|
Loading…
Reference in New Issue
Block a user