make MPlaceTy non-Copy
This commit is contained in:
parent
77ff1b83cd
commit
da3f0d0eb7
11 changed files with 28 additions and 28 deletions
|
@ -58,7 +58,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||||
ecx.push_stack_frame(
|
ecx.push_stack_frame(
|
||||||
cid.instance,
|
cid.instance,
|
||||||
body,
|
body,
|
||||||
&ret.into(),
|
&ret.clone().into(),
|
||||||
StackPopCleanup::Root { cleanup: false },
|
StackPopCleanup::Root { cleanup: false },
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||||
// Since evaluation had no errors, validate the resulting constant.
|
// Since evaluation had no errors, validate the resulting constant.
|
||||||
// This is a separate `try` block to provide more targeted error reporting.
|
// This is a separate `try` block to provide more targeted error reporting.
|
||||||
let validation: Result<_, InterpErrorInfo<'_>> = try {
|
let validation: Result<_, InterpErrorInfo<'_>> = try {
|
||||||
let mut ref_tracking = RefTracking::new(mplace);
|
let mut ref_tracking = RefTracking::new(mplace.clone());
|
||||||
let mut inner = false;
|
let mut inner = false;
|
||||||
while let Some((mplace, path)) = ref_tracking.todo.pop() {
|
while let Some((mplace, path)) = ref_tracking.todo.pop() {
|
||||||
let mode = match tcx.static_mutability(cid.instance.def_id()) {
|
let mode = match tcx.static_mutability(cid.instance.def_id()) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn branches<'tcx>(
|
||||||
) -> ValTreeCreationResult<'tcx> {
|
) -> ValTreeCreationResult<'tcx> {
|
||||||
let place = match variant {
|
let place = match variant {
|
||||||
Some(variant) => ecx.project_downcast(place, variant).unwrap(),
|
Some(variant) => ecx.project_downcast(place, variant).unwrap(),
|
||||||
None => *place,
|
None => place.clone(),
|
||||||
};
|
};
|
||||||
let variant = variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32()))));
|
let variant = variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32()))));
|
||||||
debug!(?place, ?variant);
|
debug!(?place, ?variant);
|
||||||
|
@ -290,7 +290,7 @@ pub fn valtree_to_const_value<'tcx>(
|
||||||
debug!(?place);
|
debug!(?place);
|
||||||
|
|
||||||
valtree_into_mplace(&mut ecx, &mut place, valtree);
|
valtree_into_mplace(&mut ecx, &mut place, valtree);
|
||||||
dump_place(&ecx, place.into());
|
dump_place(&ecx, place.clone().into());
|
||||||
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
|
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
|
@ -352,7 +352,7 @@ fn valtree_into_mplace<'tcx>(
|
||||||
debug!(?pointee_place);
|
debug!(?pointee_place);
|
||||||
|
|
||||||
valtree_into_mplace(ecx, &mut pointee_place, valtree);
|
valtree_into_mplace(ecx, &mut pointee_place, valtree);
|
||||||
dump_place(ecx, pointee_place.into());
|
dump_place(ecx, pointee_place.clone().into());
|
||||||
intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap();
|
intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap();
|
||||||
|
|
||||||
let imm = match inner_ty.kind() {
|
let imm = match inner_ty.kind() {
|
||||||
|
@ -389,7 +389,7 @@ fn valtree_into_mplace<'tcx>(
|
||||||
Some(variant_idx),
|
Some(variant_idx),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => (*place, branches, None),
|
_ => (place.clone(), branches, None),
|
||||||
};
|
};
|
||||||
debug!(?place_adjusted, ?branches);
|
debug!(?place_adjusted, ?branches);
|
||||||
|
|
||||||
|
|
|
@ -358,7 +358,7 @@ pub fn intern_const_alloc_recursive<
|
||||||
Some(ret.layout.ty),
|
Some(ret.layout.ty),
|
||||||
);
|
);
|
||||||
|
|
||||||
ref_tracking.track((*ret, base_intern_mode), || ());
|
ref_tracking.track((ret.clone(), base_intern_mode), || ());
|
||||||
|
|
||||||
while let Some(((mplace, mode), _)) = ref_tracking.todo.pop() {
|
while let Some(((mplace, mode), _)) = ref_tracking.todo.pop() {
|
||||||
let res = InternVisitor {
|
let res = InternVisitor {
|
||||||
|
@ -464,7 +464,7 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>>
|
||||||
) -> InterpResult<'tcx, ()>,
|
) -> InterpResult<'tcx, ()>,
|
||||||
) -> InterpResult<'tcx, ConstAllocation<'tcx>> {
|
) -> InterpResult<'tcx, ConstAllocation<'tcx>> {
|
||||||
let dest = self.allocate(layout, MemoryKind::Stack)?;
|
let dest = self.allocate(layout, MemoryKind::Stack)?;
|
||||||
f(self, &dest.into())?;
|
f(self, &dest.clone().into())?;
|
||||||
let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1;
|
let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1;
|
||||||
alloc.mutability = Mutability::Not;
|
alloc.mutability = Mutability::Not;
|
||||||
Ok(self.tcx.mk_const_alloc(alloc))
|
Ok(self.tcx.mk_const_alloc(alloc))
|
||||||
|
|
|
@ -476,7 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
|
if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
|
||||||
Right(val)
|
Right(val)
|
||||||
} else {
|
} else {
|
||||||
Left(*mplace)
|
Left(mplace.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Right(val) => Right(val),
|
Right(val) => Right(val),
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub struct MemPlace<Prov: Provenance = AllocId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A MemPlace with its layout. Constructing it is only possible in this module.
|
/// A MemPlace with its layout. Constructing it is only possible in this module.
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
#[derive(Clone, Hash, Eq, PartialEq, Debug)]
|
||||||
pub struct MPlaceTy<'tcx, Prov: Provenance = AllocId> {
|
pub struct MPlaceTy<'tcx, Prov: Provenance = AllocId> {
|
||||||
mplace: MemPlace<Prov>,
|
mplace: MemPlace<Prov>,
|
||||||
pub layout: TyAndLayout<'tcx>,
|
pub layout: TyAndLayout<'tcx>,
|
||||||
|
@ -452,7 +452,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let mplace = self.ref_to_mplace(&val)?;
|
let mplace = self.ref_to_mplace(&val)?;
|
||||||
self.check_mplace(mplace)?;
|
self.check_mplace(&mplace)?;
|
||||||
Ok(mplace)
|
Ok(mplace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if this mplace is dereferenceable and sufficiently aligned.
|
/// Check if this mplace is dereferenceable and sufficiently aligned.
|
||||||
pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
pub fn check_mplace(&self, mplace: &MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
||||||
let (size, _align) = self
|
let (size, _align) = self
|
||||||
.size_and_align_of_mplace(&mplace)?
|
.size_and_align_of_mplace(&mplace)?
|
||||||
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
|
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
|
||||||
|
|
|
@ -634,7 +634,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Ensure the return place is aligned and dereferenceable, and protect it for
|
// Ensure the return place is aligned and dereferenceable, and protect it for
|
||||||
// in-place return value passing.
|
// in-place return value passing.
|
||||||
if let Either::Left(mplace) = destination.as_mplace_or_local() {
|
if let Either::Left(mplace) = destination.as_mplace_or_local() {
|
||||||
self.check_mplace(mplace)?;
|
self.check_mplace(&mplace)?;
|
||||||
} else {
|
} else {
|
||||||
// Nothing to do for locals, they are always properly allocated and aligned.
|
// Nothing to do for locals, they are always properly allocated and aligned.
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,19 +136,19 @@ pub struct RefTracking<T, PATH = ()> {
|
||||||
pub todo: Vec<(T, PATH)>,
|
pub todo: Vec<(T, PATH)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH> {
|
impl<T: Clone + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH> {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
RefTracking { seen: FxHashSet::default(), todo: vec![] }
|
RefTracking { seen: FxHashSet::default(), todo: vec![] }
|
||||||
}
|
}
|
||||||
pub fn new(op: T) -> Self {
|
pub fn new(op: T) -> Self {
|
||||||
let mut ref_tracking_for_consts =
|
let mut ref_tracking_for_consts =
|
||||||
RefTracking { seen: FxHashSet::default(), todo: vec![(op, PATH::default())] };
|
RefTracking { seen: FxHashSet::default(), todo: vec![(op.clone(), PATH::default())] };
|
||||||
ref_tracking_for_consts.seen.insert(op);
|
ref_tracking_for_consts.seen.insert(op);
|
||||||
ref_tracking_for_consts
|
ref_tracking_for_consts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn track(&mut self, op: T, path: impl FnOnce() -> PATH) {
|
pub fn track(&mut self, op: T, path: impl FnOnce() -> PATH) {
|
||||||
if self.seen.insert(op) {
|
if self.seen.insert(op.clone()) {
|
||||||
trace!("Recursing below ptr {:#?}", op);
|
trace!("Recursing below ptr {:#?}", op);
|
||||||
let path = path();
|
let path = path();
|
||||||
// Remember to come back to this later.
|
// Remember to come back to this later.
|
||||||
|
|
|
@ -600,14 +600,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
/// necessary.
|
/// necessary.
|
||||||
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
if let Some(errno_place) = this.active_thread_ref().last_error {
|
if let Some(errno_place) = this.active_thread_ref().last_error.as_ref() {
|
||||||
Ok(errno_place)
|
Ok(errno_place.clone())
|
||||||
} else {
|
} else {
|
||||||
// Allocate new place, set initial value to 0.
|
// Allocate new place, set initial value to 0.
|
||||||
let errno_layout = this.machine.layouts.u32;
|
let errno_layout = this.machine.layouts.u32;
|
||||||
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?;
|
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?;
|
||||||
this.write_scalar(Scalar::from_u32(0), &errno_place)?;
|
this.write_scalar(Scalar::from_u32(0), &errno_place)?;
|
||||||
this.active_thread_mut().last_error = Some(errno_place);
|
this.active_thread_mut().last_error = Some(errno_place.clone());
|
||||||
Ok(errno_place)
|
Ok(errno_place)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -725,7 +725,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
let mplace = MPlaceTy::from_aligned_ptr(ptr, layout);
|
let mplace = MPlaceTy::from_aligned_ptr(ptr, layout);
|
||||||
|
|
||||||
this.check_mplace(mplace)?;
|
this.check_mplace(&mplace)?;
|
||||||
|
|
||||||
Ok(mplace)
|
Ok(mplace)
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,7 +668,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
Self::add_extern_static(
|
Self::add_extern_static(
|
||||||
this,
|
this,
|
||||||
"environ",
|
"environ",
|
||||||
this.machine.env_vars.environ.unwrap().ptr,
|
this.machine.env_vars.environ.as_ref().unwrap().ptr,
|
||||||
);
|
);
|
||||||
// A couple zero-initialized pointer-sized extern statics.
|
// A couple zero-initialized pointer-sized extern statics.
|
||||||
// Most of them are for weak symbols, which we all set to null (indicating that the
|
// Most of them are for weak symbols, which we all set to null (indicating that the
|
||||||
|
@ -685,7 +685,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
Self::add_extern_static(
|
Self::add_extern_static(
|
||||||
this,
|
this,
|
||||||
"environ",
|
"environ",
|
||||||
this.machine.env_vars.environ.unwrap().ptr,
|
this.machine.env_vars.environ.as_ref().unwrap().ptr,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"android" => {
|
"android" => {
|
||||||
|
|
|
@ -87,8 +87,8 @@ impl<'tcx> EnvVars<'tcx> {
|
||||||
ecx.deallocate_ptr(ptr, None, MiriMemoryKind::Runtime.into())?;
|
ecx.deallocate_ptr(ptr, None, MiriMemoryKind::Runtime.into())?;
|
||||||
}
|
}
|
||||||
// Deallocate environ var list.
|
// Deallocate environ var list.
|
||||||
let environ = ecx.machine.env_vars.environ.unwrap();
|
let environ = ecx.machine.env_vars.environ.as_ref().unwrap();
|
||||||
let old_vars_ptr = ecx.read_pointer(&environ)?;
|
let old_vars_ptr = ecx.read_pointer(environ)?;
|
||||||
ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
|
ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -431,8 +431,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
fn update_environ(&mut self) -> InterpResult<'tcx> {
|
fn update_environ(&mut self) -> InterpResult<'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
// Deallocate the old environ list, if any.
|
// Deallocate the old environ list, if any.
|
||||||
if let Some(environ) = this.machine.env_vars.environ {
|
if let Some(environ) = this.machine.env_vars.environ.as_ref() {
|
||||||
let old_vars_ptr = this.read_pointer(&environ)?;
|
let old_vars_ptr = this.read_pointer(environ)?;
|
||||||
this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
|
this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?;
|
||||||
} else {
|
} else {
|
||||||
// No `environ` allocated yet, let's do that.
|
// No `environ` allocated yet, let's do that.
|
||||||
|
@ -459,7 +459,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let place = this.project_field(&vars_place, idx)?;
|
let place = this.project_field(&vars_place, idx)?;
|
||||||
this.write_pointer(var, &place)?;
|
this.write_pointer(var, &place)?;
|
||||||
}
|
}
|
||||||
this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.unwrap())?;
|
this.write_pointer(vars_place.ptr, &this.machine.env_vars.environ.clone().unwrap())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
"_NSGetEnviron" => {
|
"_NSGetEnviron" => {
|
||||||
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
this.write_pointer(
|
this.write_pointer(
|
||||||
this.machine.env_vars.environ.expect("machine must be initialized").ptr,
|
this.machine.env_vars.environ.as_ref().expect("machine must be initialized").ptr,
|
||||||
dest,
|
dest,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue