diff options
| author | Ralf Jung <post@ralfj.de> | 2022-06-02 09:05:37 -0400 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-06-02 10:46:13 -0400 |
| commit | fafccdced349d655db83e0ec30e91b85dcf65cf7 (patch) | |
| tree | ac2824389ec482db03424576e022e3e304ef54a2 /compiler/rustc_const_eval | |
| parent | 5e6bb83268518dcd74c96b5504f485b71e604e4c (diff) | |
| download | rust-fafccdced349d655db83e0ec30e91b85dcf65cf7.tar.gz rust-fafccdced349d655db83e0ec30e91b85dcf65cf7.zip | |
add cast kind of from_exposed_addr (int-to-ptr casts)
Diffstat (limited to 'compiler/rustc_const_eval')
3 files changed, 34 insertions, 21 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 520ae409e6b..73cc59ad1e6 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -37,6 +37,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(res, dest)?; } + PointerFromExposedAddress => { + let src = self.read_immediate(src)?; + let res = self.pointer_from_exposed_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)?; @@ -201,6 +207,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into()) } + pub fn pointer_from_exposed_address_cast( + &mut self, + src: &ImmTy<'tcx, M::PointerTag>, + cast_ty: Ty<'tcx>, + ) -> InterpResult<'tcx, Immediate<M::PointerTag>> { + assert!(src.layout.ty.is_integral()); + assert_matches!(cast_ty.kind(), ty::RawPtr(_)); + + // First cast to usize. + let scalar = src.to_scalar()?; + let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?; + let addr = addr.to_machine_usize(self)?; + + // Then turn address into pointer. + let ptr = M::ptr_from_addr_cast(&self, addr); + Ok(Scalar::from_maybe_pointer(ptr, self).into()) + } + pub fn cast_from_int_like( &self, scalar: Scalar<M::PointerTag>, // input value (there is no ScalarTy so we separate data+layout) @@ -225,16 +249,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Scalar::from_uint(v, size) } - RawPtr(_) => { - assert!(src_layout.ty.is_integral()); - - let size = self.pointer_size(); - let addr = u64::try_from(size.truncate(v)).unwrap(); - - let ptr = M::ptr_from_addr_cast(&self, addr); - Scalar::from_maybe_pointer(ptr, self) - } - Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value), Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value), Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index c07680515f4..4b98e19376d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -520,31 +520,29 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } Rvalue::Cast( - CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), - _, - _, - ) => {} - - Rvalue::Cast( CastKind::Pointer( - PointerCast::UnsafeFnPointer + PointerCast::MutToConstPointer + | PointerCast::ArrayToPointer + | PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer, ), _, _, ) => { - // Nothing to do here. Function pointer casts are allowed now. + // These are all okay; they only change the type, not the data. } Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => { - // Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur - // in the type of any local, which also excludes casts). + // Unsizing is implemented for CTFE. } Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { self.check_op(ops::RawPtrToIntCast); } + Rvalue::Cast(CastKind::PointerFromExposedAddress, _, _) => { + // Since no pointer can ever get exposed (rejected above), this is easy to support. + } Rvalue::Cast(CastKind::Misc, _, _) => {} diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index cf5d7b6c70a..4879e8de100 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -504,7 +504,8 @@ impl<'tcx> Validator<'_, 'tcx> { // ptr-to-int casts are not possible in consts and thus not promotable Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable), - // int-to-ptr casts are fine, they just use the integer value at pointer type. + // all ohter casts including int-to-ptr casts are fine, they just use the integer value + // at pointer type. Rvalue::Cast(_, operand, _) => { self.validate_operand(operand)?; } |
