mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #116102 - cjgillot:indirect-scalar, r=oli-obk
Correct codegen of `ConstValue::Indirect` scalar and scalar pair This concerns 3 tricky cases with `ConstValue::Indirect`: - if we want a non-pointer scalar; - if we have non-zero offset; - if offset points to uninit memory => generate `poison` instead of an ICE. This case could happen in unreachable code, trying to extract a field from the wrong variant. Those cases are not currently emitted by the compiler, but are exercised by https://github.com/rust-lang/rust/pull/116012.
This commit is contained in:
commit
5899a80ae6
@ -135,15 +135,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
||||
assert_eq!(alloc_align, layout.align.abi);
|
||||
|
||||
let read_scalar = |start, size, s: abi::Scalar, ty| {
|
||||
let val = alloc
|
||||
.0
|
||||
.read_scalar(
|
||||
bx,
|
||||
alloc_range(start, size),
|
||||
/*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
|
||||
)
|
||||
.unwrap();
|
||||
bx.scalar_to_backend(val, s, ty)
|
||||
match alloc.0.read_scalar(
|
||||
bx,
|
||||
alloc_range(start, size),
|
||||
/*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
|
||||
) {
|
||||
Ok(val) => bx.scalar_to_backend(val, s, ty),
|
||||
Err(_) => bx.const_poison(ty),
|
||||
}
|
||||
};
|
||||
|
||||
// It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
|
||||
@ -156,7 +155,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
||||
Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
|
||||
let size = s.size(bx);
|
||||
assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
|
||||
let val = read_scalar(Size::ZERO, size, s, bx.type_ptr());
|
||||
let val = read_scalar(offset, size, s, bx.backend_type(layout));
|
||||
OperandRef { val: OperandValue::Immediate(val), layout }
|
||||
}
|
||||
Abi::ScalarPair(
|
||||
@ -164,10 +163,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
|
||||
b @ abi::Scalar::Initialized { .. },
|
||||
) => {
|
||||
let (a_size, b_size) = (a.size(bx), b.size(bx));
|
||||
let b_offset = a_size.align_to(b.align(bx).abi);
|
||||
let b_offset = (offset + a_size).align_to(b.align(bx).abi);
|
||||
assert!(b_offset.bytes() > 0);
|
||||
let a_val = read_scalar(
|
||||
Size::ZERO,
|
||||
offset,
|
||||
a_size,
|
||||
a,
|
||||
bx.scalar_pair_element_backend_type(layout, 0, true),
|
||||
|
Loading…
Reference in New Issue
Block a user