add cast kind of from_exposed_addr (int-to-ptr casts)
This commit is contained in:
parent
5e6bb83268
commit
fafccdced3
10 changed files with 93 additions and 39 deletions
|
@ -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),
|
||||
|
|
|
@ -519,32 +519,30 @@ 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, _, _) => {}
|
||||
|
||||
|
|
|
@ -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)?;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue