about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-26 19:04:32 +0000
committerbors <bors@rust-lang.org>2023-09-26 19:04:32 +0000
commit5899a80ae60ec0959dcd4a7eca6eb02ce2866632 (patch)
treedfecc4852f43a1cba570e833a989bb6bc5369159 /compiler/rustc_codegen_ssa/src
parent6710e3312d54f03f6462481199b9e72367a2568b (diff)
parentac0683b78310bba9c3c601cfd81bbda4a10be322 (diff)
downloadrust-5899a80ae60ec0959dcd4a7eca6eb02ce2866632.tar.gz
rust-5899a80ae60ec0959dcd4a7eca6eb02ce2866632.zip
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.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs23
1 files changed, 11 insertions, 12 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 9205acc527e..0ab2b7ecd9c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -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),