diff options
| author | bors <bors@rust-lang.org> | 2023-09-26 19:04:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-09-26 19:04:32 +0000 |
| commit | 5899a80ae60ec0959dcd4a7eca6eb02ce2866632 (patch) | |
| tree | dfecc4852f43a1cba570e833a989bb6bc5369159 /compiler/rustc_codegen_ssa/src | |
| parent | 6710e3312d54f03f6462481199b9e72367a2568b (diff) | |
| parent | ac0683b78310bba9c3c601cfd81bbda4a10be322 (diff) | |
| download | rust-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.rs | 23 |
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), |
