Rollup merge of #95340 - RalfJung:pnvi, r=oli-obk
interpret: with enforce_number_validity, ensure integers are truly Scalar::Int (i.e., no pointers) This is required for https://github.com/rust-lang/miri/pull/2040 r? ```@oli-obk```
This commit is contained in:
commit
178a09e672
2 changed files with 8 additions and 4 deletions
|
@ -444,6 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
match scalar.try_to_int() {
|
match scalar.try_to_int() {
|
||||||
Ok(int) => int.is_null(),
|
Ok(int) => int.is_null(),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
// Can only happen during CTFE.
|
||||||
let ptr = self.scalar_to_ptr(scalar);
|
let ptr = self.scalar_to_ptr(scalar);
|
||||||
match self.memory.ptr_try_get_alloc(ptr) {
|
match self.memory.ptr_try_get_alloc(ptr) {
|
||||||
Ok((alloc_id, offset, _)) => {
|
Ok((alloc_id, offset, _)) => {
|
||||||
|
@ -455,7 +456,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Note that one-past-the-end (offset == size) is still inbounds, and never null.
|
// Note that one-past-the-end (offset == size) is still inbounds, and never null.
|
||||||
offset > size
|
offset > size
|
||||||
}
|
}
|
||||||
Err(offset) => offset == 0,
|
Err(_offset) => bug!("a non-int scalar is always a pointer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use std::hash::Hash;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
alloc_range, CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine,
|
alloc_range, CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine,
|
||||||
MemPlaceMeta, OpTy, ScalarMaybeUninit, ValueVisitor,
|
MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! throw_validation_failure {
|
macro_rules! throw_validation_failure {
|
||||||
|
@ -521,8 +521,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||||
// NOTE: Keep this in sync with the array optimization for int/float
|
// NOTE: Keep this in sync with the array optimization for int/float
|
||||||
// types below!
|
// types below!
|
||||||
if M::enforce_number_validity(self.ecx) {
|
if M::enforce_number_validity(self.ecx) {
|
||||||
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
|
// Integers/floats with number validity: Must be scalar bits, pointers are dangerous.
|
||||||
let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
|
// As a special exception we *do* match on a `Scalar` here, since we truly want
|
||||||
|
// to know its underlying representation (and *not* cast it to an integer).
|
||||||
|
let is_bits =
|
||||||
|
value.check_init().map_or(false, |v| matches!(v, Scalar::Int(..)));
|
||||||
if !is_bits {
|
if !is_bits {
|
||||||
throw_validation_failure!(self.path,
|
throw_validation_failure!(self.path,
|
||||||
{ "{:x}", value } expected { "initialized plain (non-pointer) bytes" }
|
{ "{:x}", value } expected { "initialized plain (non-pointer) bytes" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue