diff options
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operand.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/traits.rs | 19 |
3 files changed, 46 insertions, 18 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9c032c55fe5..f3f3c5bf946 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -908,11 +908,15 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> { } impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> { - pub fn read_scalar(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> { + pub fn read_scalar( + &self, + range: AllocRange, + read_provenance: bool, + ) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> { let range = self.range.subrange(range); let res = self .alloc - .read_scalar(&self.tcx, range) + .read_scalar(&self.tcx, range, read_provenance) .map_err(|e| e.to_interp_error(self.alloc_id))?; debug!( "read_scalar in {} at {:#x}, size {}: {:?}", @@ -924,8 +928,19 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> { Ok(res) } - pub fn read_ptr_sized(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> { - self.read_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size)) + pub fn read_integer( + &self, + offset: Size, + size: Size, + ) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> { + self.read_scalar(alloc_range(offset, size), /*read_provenance*/ false) + } + + pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> { + self.read_scalar( + alloc_range(offset, self.tcx.data_layout().pointer_size), + /*read_provenance*/ true, + ) } pub fn check_bytes( diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index f5e1ee4e233..ea553feb186 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -15,8 +15,8 @@ use rustc_target::abi::{VariantIdx, Variants}; use super::{ alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, GlobalId, - InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Provenance, - Scalar, ScalarMaybeUninit, + InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, + PointerArithmetic, Provenance, Scalar, ScalarMaybeUninit, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -284,11 +284,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Abi::Scalar(s) if force => Some(s.primitive()), _ => None, }; - if let Some(_s) = scalar_layout { + let number_may_have_provenance = !M::enforce_number_no_provenance(self); + if let Some(s) = scalar_layout { //FIXME(#96185): let size = s.size(self); //FIXME(#96185): assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size"); let size = mplace.layout.size; //FIXME(#96185): remove this line - let scalar = alloc.read_scalar(alloc_range(Size::ZERO, size))?; + let scalar = alloc.read_scalar( + alloc_range(Size::ZERO, size), + s.is_ptr() || (number_may_have_provenance && size == self.pointer_size()), + )?; return Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout })); } let scalar_pair_layout = match mplace.layout.abi { @@ -306,8 +310,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (a_size, b_size) = (a.size(self), b.size(self)); let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields - let a_val = alloc.read_scalar(alloc_range(Size::ZERO, a_size))?; - let b_val = alloc.read_scalar(alloc_range(b_offset, b_size))?; + let a_val = alloc.read_scalar( + alloc_range(Size::ZERO, a_size), + a.is_ptr() || (number_may_have_provenance && a_size == self.pointer_size()), + )?; + let b_val = alloc.read_scalar( + alloc_range(b_offset, b_size), + b.is_ptr() || (number_may_have_provenance && b_size == self.pointer_size()), + )?; return Ok(Some(ImmTy { imm: Immediate::ScalarPair(a_val, b_val), layout: mplace.layout, diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index c4d1074e437..9c48f3e8337 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -50,7 +50,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let vtable_slot = self .get_ptr_alloc(vtable_slot, ptr_size, self.tcx.data_layout.pointer_align.abi)? .expect("cannot be a ZST"); - let fn_ptr = self.scalar_to_ptr(vtable_slot.read_ptr_sized(Size::ZERO)?.check_init()?)?; + let fn_ptr = self.scalar_to_ptr(vtable_slot.read_pointer(Size::ZERO)?.check_init()?)?; self.get_ptr_fn(fn_ptr) } @@ -69,9 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )? .expect("cannot be a ZST"); let drop_fn = vtable - .read_ptr_sized( - pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_DROPINPLACE).unwrap(), - )? + .read_pointer(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_DROPINPLACE).unwrap())? .check_init()?; // We *need* an instance here, no other kind of function value, to be able // to determine the type. @@ -104,12 +102,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )? .expect("cannot be a ZST"); let size = vtable - .read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap())? + .read_integer( + pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap(), + pointer_size, + )? .check_init()?; let size = size.to_machine_usize(self)?; let size = Size::from_bytes(size); let align = vtable - .read_ptr_sized(pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap())? + .read_integer( + pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap(), + pointer_size, + )? .check_init()?; let align = align.to_machine_usize(self)?; let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?; @@ -132,8 +136,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .get_ptr_alloc(vtable_slot, pointer_size, self.tcx.data_layout.pointer_align.abi)? .expect("cannot be a ZST"); - let new_vtable = - self.scalar_to_ptr(new_vtable.read_ptr_sized(Size::ZERO)?.check_init()?)?; + let new_vtable = self.scalar_to_ptr(new_vtable.read_pointer(Size::ZERO)?.check_init()?)?; Ok(new_vtable) } |
