diff options
| author | bors <bors@rust-lang.org> | 2019-11-05 12:46:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-05 12:46:29 +0000 |
| commit | 3a1b3b30c6cdd674049b144a3ced7b711de962b2 (patch) | |
| tree | b28aa0b22f11b2adc83b52c6eea06fc63236ed18 /src/librustc_mir | |
| parent | d1fff4a4b213b3341c1ff994061b7965a5932c70 (diff) | |
| parent | a593b5419901774c134e18433452c4dd5f7ff648 (diff) | |
| download | rust-3a1b3b30c6cdd674049b144a3ced7b711de962b2.tar.gz rust-3a1b3b30c6cdd674049b144a3ced7b711de962b2.zip | |
Auto merge of #66083 - RalfJung:miri-offset-from, r=oli-obk
fix Miri offset_from This is needed to make https://github.com/rust-lang/miri/pull/1032 pass.
Diffstat (limited to 'src/librustc_mir')
| -rw-r--r-- | src/librustc_mir/interpret/intrinsics.rs | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index c08e4c89609..04032847385 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -251,8 +251,28 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } "ptr_offset_from" => { - let a = self.read_immediate(args[0])?.to_scalar()?.to_ptr()?; - let b = self.read_immediate(args[1])?.to_scalar()?.to_ptr()?; + let isize_layout = self.layout_of(self.tcx.types.isize)?; + let a = self.read_immediate(args[0])?.to_scalar()?; + let b = self.read_immediate(args[1])?.to_scalar()?; + + // Special case: if both scalars are *equal integers* + // and not NULL, we pretend there is an allocation of size 0 right there, + // and their offset is 0. (There's never a valid object at NULL, making it an + // exception from the exception.) + // This is the dual to the special exception for offset-by-0 + // in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`). + if a.is_bits() && b.is_bits() { + let a = a.to_usize(self)?; + let b = b.to_usize(self)?; + if a == b && a != 0 { + self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?; + return Ok(true); + } + } + + // General case: we need two pointers. + let a = self.force_ptr(a)?; + let b = self.force_ptr(b)?; if a.alloc_id != b.alloc_id { throw_ub_format!( "ptr_offset_from cannot compute offset of pointers into different \ @@ -266,7 +286,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { BinOp::Sub, a_offset, b_offset, )?; let pointee_layout = self.layout_of(substs.type_at(0))?; - let isize_layout = self.layout_of(self.tcx.types.isize)?; let val = ImmTy::from_scalar(val, isize_layout); let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout); self.exact_div(val, size, dest)?; |
