diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-05-31 00:00:00 +0000 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-05-31 00:00:00 +0000 |
| commit | dff602fc18be295d1b87196a6eee1c72673e6bb8 (patch) | |
| tree | 3c08934e4fe11ed94c9875185f3e61bcdd1a2484 /compiler/rustc_const_eval/src/interpret | |
| parent | d35d972e6974d40d30362344ea619a5b560aae20 (diff) | |
| download | rust-dff602fc18be295d1b87196a6eee1c72673e6bb8.tar.gz rust-dff602fc18be295d1b87196a6eee1c72673e6bb8.zip | |
Add a pointer to address cast kind
A pointer to address cast are often special-cased. Introduce a dedicated cast kind to make them easy distinguishable.
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/cast.rs | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index be34a77bdba..af563c1450e 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,3 +1,4 @@ +use std::assert_matches::assert_matches; use std::convert::TryFrom; use rustc_apfloat::ieee::{Double, Single}; @@ -30,6 +31,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.unsize_into(src, cast_ty, dest)?; } + PointerAddress => { + let src = self.read_immediate(src)?; + let res = self.pointer_address_cast(&src, cast_ty)?; + self.write_immediate(res, dest)?; + } + Misc => { let src = self.read_immediate(src)?; let res = self.misc_cast(&src, cast_ty)?; @@ -174,23 +181,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // # The remaining source values are scalar and "int-like". let scalar = src.to_scalar()?; + Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) + } - // If we are casting from a pointer to something - // that is not a pointer, mark the pointer as exposed - if src.layout.ty.is_any_ptr() && !cast_ty.is_any_ptr() { - let ptr = self.scalar_to_ptr(scalar)?; - - match ptr.into_pointer_or_addr() { - Ok(ptr) => { - M::expose_ptr(self, ptr)?; - } - Err(_) => { - // do nothing, exposing an invalid pointer - // has no meaning - } - }; - } + pub fn pointer_address_cast( + &mut self, + src: &ImmTy<'tcx, M::PointerTag>, + cast_ty: Ty<'tcx>, + ) -> InterpResult<'tcx, Immediate<M::PointerTag>> { + assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_)); + assert!(cast_ty.is_integral()); + let scalar = src.to_scalar()?; + let ptr = self.scalar_to_ptr(scalar)?; + match ptr.into_pointer_or_addr() { + Ok(ptr) => M::expose_ptr(self, ptr)?, + Err(_) => {} // do nothing, exposing an invalid pointer has no meaning + }; Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) } |
