pass typecheck
This commit is contained in:
parent
30496f5dd2
commit
03aa8765b1
5 changed files with 67 additions and 56 deletions
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::ty::layout::{Align, LayoutOf};
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use rustc::mir;
|
||||
use syntax::attr;
|
||||
|
|
@ -111,7 +111,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
if size == 0 {
|
||||
self.write_null(dest, dest_ty)?;
|
||||
} else {
|
||||
let align = self.memory.pointer_size();
|
||||
let align = self.tcx.data_layout.pointer_align;
|
||||
let ptr = self.memory.allocate(size, align, Some(MemoryKind::C.into()))?;
|
||||
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
|
||||
}
|
||||
|
|
@ -307,7 +307,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
// +1 for the null terminator
|
||||
let value_copy = self.memory.allocate(
|
||||
(value.len() + 1) as u64,
|
||||
1,
|
||||
Align::from_bytes(1, 1).unwrap(),
|
||||
Some(MemoryKind::Env.into()),
|
||||
)?;
|
||||
self.memory.write_bytes(value_copy.into(), &value)?;
|
||||
|
|
@ -369,6 +369,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
|
||||
"sysconf" => {
|
||||
let name = self.value_to_primval(args[0])?.to_u64()?;
|
||||
let name_align = self.layout_of(args[0].ty)?.align;
|
||||
|
||||
trace!("sysconf() called with name {}", name);
|
||||
// cache the sysconf integers via miri's global cache
|
||||
let paths = &[
|
||||
|
|
@ -387,7 +389,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
Some(ptr) => ptr,
|
||||
None => eval_body(self.tcx, instance, ty::ParamEnv::empty(traits::Reveal::All))?.0,
|
||||
};
|
||||
let val = self.value_to_primval(ValTy { value: Value::ByRef(val), ty: args[0].ty })?.to_u64()?;
|
||||
let val = self.value_to_primval(ValTy { value: Value::ByRef(val, name_align),
|
||||
ty: args[0].ty })?.to_u64()?;
|
||||
if val == name {
|
||||
result = Some(path_value);
|
||||
break;
|
||||
|
|
@ -406,6 +409,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
// Hook pthread calls that go to the thread-local storage memory subsystem
|
||||
"pthread_key_create" => {
|
||||
let key_ptr = self.into_ptr(args[0].value)?;
|
||||
let key_align = self.layout_of(args[0].ty)?.align;
|
||||
|
||||
// Extract the function type out of the signature (that seems easier than constructing it ourselves...)
|
||||
let dtor = match self.into_ptr(args[1].value)?.into_inner_primval() {
|
||||
|
|
@ -427,6 +431,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
}
|
||||
self.memory.write_primval(
|
||||
key_ptr.to_ptr()?,
|
||||
key_align,
|
||||
PrimVal::Bytes(key),
|
||||
key_size.bytes(),
|
||||
false,
|
||||
|
|
@ -559,7 +564,9 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
if !align.is_power_of_two() {
|
||||
return err!(HeapAllocNonPowerOfTwoAlignment(align));
|
||||
}
|
||||
let ptr = self.memory.allocate(size, align, Some(MemoryKind::Rust.into()))?;
|
||||
let ptr = self.memory.allocate(size,
|
||||
Align::from_bytes(align, align).unwrap(),
|
||||
Some(MemoryKind::Rust.into()))?;
|
||||
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
|
||||
}
|
||||
"alloc::heap::::__rust_alloc_zeroed" => {
|
||||
|
|
@ -571,7 +578,9 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
if !align.is_power_of_two() {
|
||||
return err!(HeapAllocNonPowerOfTwoAlignment(align));
|
||||
}
|
||||
let ptr = self.memory.allocate(size, align, Some(MemoryKind::Rust.into()))?;
|
||||
let ptr = self.memory.allocate(size,
|
||||
Align::from_bytes(align, align).unwrap(),
|
||||
Some(MemoryKind::Rust.into()))?;
|
||||
self.memory.write_repeat(ptr.into(), 0, size)?;
|
||||
self.write_primval(dest, PrimVal::Ptr(ptr), dest_ty)?;
|
||||
}
|
||||
|
|
@ -587,7 +596,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
}
|
||||
self.memory.deallocate(
|
||||
ptr,
|
||||
Some((old_size, align)),
|
||||
Some((old_size, Align::from_bytes(align, align).unwrap())),
|
||||
MemoryKind::Rust.into(),
|
||||
)?;
|
||||
}
|
||||
|
|
@ -609,9 +618,9 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
let new_ptr = self.memory.reallocate(
|
||||
ptr,
|
||||
old_size,
|
||||
old_align,
|
||||
Align::from_bytes(old_align, old_align).unwrap(),
|
||||
new_size,
|
||||
new_align,
|
||||
Align::from_bytes(new_align, new_align).unwrap(),
|
||||
MemoryKind::Rust.into(),
|
||||
)?;
|
||||
self.write_primval(dest, PrimVal::Ptr(new_ptr), dest_ty)?;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use rustc::traits::Reveal;
|
|||
use rustc::ty::layout::{TyLayout, LayoutOf};
|
||||
use rustc::ty;
|
||||
|
||||
use rustc::mir::interpret::{EvalResult, PrimVal, PrimValKind, Value, Pointer, AccessKind, PtrAndAlign};
|
||||
use rustc::mir::interpret::{EvalResult, PrimVal, PrimValKind, Value, Pointer};
|
||||
use rustc_mir::interpret::{Place, PlaceExtra, HasMemory, EvalContext, ValTy};
|
||||
|
||||
use helpers::EvalContextExt as HelperEvalContextExt;
|
||||
|
|
@ -87,8 +87,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"atomic_load_acq" |
|
||||
"volatile_load" => {
|
||||
let ptr = self.into_ptr(args[0].value)?;
|
||||
let align = self.layout_of(args[0].ty)?.align;
|
||||
|
||||
let valty = ValTy {
|
||||
value: Value::by_ref(ptr),
|
||||
value: Value::ByRef(ptr, align),
|
||||
ty: substs.type_at(0),
|
||||
};
|
||||
self.write_value(valty, dest)?;
|
||||
|
|
@ -99,8 +101,9 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"atomic_store_rel" |
|
||||
"volatile_store" => {
|
||||
let ty = substs.type_at(0);
|
||||
let align = self.layout_of(ty)?.align;
|
||||
let dest = self.into_ptr(args[0].value)?;
|
||||
self.write_value_to_ptr(args[1].value, dest, ty)?;
|
||||
self.write_value_to_ptr(args[1].value, dest, align, ty)?;
|
||||
}
|
||||
|
||||
"atomic_fence_acq" => {
|
||||
|
|
@ -109,9 +112,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
|
||||
_ if intrinsic_name.starts_with("atomic_xchg") => {
|
||||
let ty = substs.type_at(0);
|
||||
let align = self.layout_of(ty)?.align;
|
||||
let ptr = self.into_ptr(args[0].value)?;
|
||||
let change = self.value_to_primval(args[1])?;
|
||||
let old = self.read_value(ptr, ty)?;
|
||||
let old = self.read_value(ptr, align, ty)?;
|
||||
let old = match old {
|
||||
Value::ByVal(val) => val,
|
||||
Value::ByRef { .. } => bug!("just read the value, can't be byref"),
|
||||
|
|
@ -119,7 +123,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
};
|
||||
self.write_primval(dest, old, ty)?;
|
||||
self.write_primval(
|
||||
Place::from_primval_ptr(ptr),
|
||||
Place::from_primval_ptr(ptr, align),
|
||||
change,
|
||||
ty,
|
||||
)?;
|
||||
|
|
@ -127,10 +131,11 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
|
||||
_ if intrinsic_name.starts_with("atomic_cxchg") => {
|
||||
let ty = substs.type_at(0);
|
||||
let align = self.layout_of(ty)?.align;
|
||||
let ptr = self.into_ptr(args[0].value)?;
|
||||
let expect_old = self.value_to_primval(args[1])?;
|
||||
let change = self.value_to_primval(args[2])?;
|
||||
let old = self.read_value(ptr, ty)?;
|
||||
let old = self.read_value(ptr, align, ty)?;
|
||||
let old = match old {
|
||||
Value::ByVal(val) => val,
|
||||
Value::ByRef { .. } => bug!("just read the value, can't be byref"),
|
||||
|
|
@ -143,7 +148,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
};
|
||||
self.write_value(valty, dest)?;
|
||||
self.write_primval(
|
||||
Place::from_primval_ptr(ptr),
|
||||
Place::from_primval_ptr(ptr, dest_layout.align),
|
||||
change,
|
||||
ty,
|
||||
)?;
|
||||
|
|
@ -175,9 +180,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"atomic_xsub_acqrel" |
|
||||
"atomic_xsub_relaxed" => {
|
||||
let ty = substs.type_at(0);
|
||||
let align = self.layout_of(ty)?.align;
|
||||
let ptr = self.into_ptr(args[0].value)?;
|
||||
let change = self.value_to_primval(args[1])?;
|
||||
let old = self.read_value(ptr, ty)?;
|
||||
let old = self.read_value(ptr, align, ty)?;
|
||||
let old = match old {
|
||||
Value::ByVal(val) => val,
|
||||
Value::ByRef { .. } => bug!("just read the value, can't be byref"),
|
||||
|
|
@ -196,7 +202,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
};
|
||||
// FIXME: what do atomics do on overflow?
|
||||
let (val, _) = self.binary_op(op, old, ty, change, ty)?;
|
||||
self.write_primval(Place::from_primval_ptr(ptr), val, ty)?;
|
||||
self.write_primval(Place::from_primval_ptr(ptr, dest_layout.align), val, ty)?;
|
||||
}
|
||||
|
||||
"breakpoint" => unimplemented!(), // halt miri
|
||||
|
|
@ -210,14 +216,16 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
if count * elem_size != 0 {
|
||||
// TODO: We do not even validate alignment for the 0-bytes case. libstd relies on this in vec::IntoIter::next.
|
||||
// Also see the write_bytes intrinsic.
|
||||
let elem_align = elem_layout.align.abi();
|
||||
let elem_align = elem_layout.align;
|
||||
let src = self.into_ptr(args[0].value)?;
|
||||
let src_align = self.layout_of(args[0].ty)?.align;
|
||||
let dest = self.into_ptr(args[1].value)?;
|
||||
self.memory.copy(
|
||||
src,
|
||||
src_align,
|
||||
dest,
|
||||
count * elem_size,
|
||||
elem_align,
|
||||
count * elem_size,
|
||||
intrinsic_name.ends_with("_nonoverlapping"),
|
||||
)?;
|
||||
}
|
||||
|
|
@ -241,7 +249,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"discriminant_value" => {
|
||||
let ty = substs.type_at(0);
|
||||
let adt_ptr = self.into_ptr(args[0].value)?;
|
||||
let place = Place::from_primval_ptr(adt_ptr);
|
||||
let adt_align = self.layout_of(args[0].ty)?.align;
|
||||
let place = Place::from_primval_ptr(adt_ptr, adt_align);
|
||||
let discr_val = self.read_discriminant_value(place, ty)?;
|
||||
self.write_primval(dest, PrimVal::Bytes(discr_val), dest_layout.ty)?;
|
||||
}
|
||||
|
|
@ -312,7 +321,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
let size = dest_layout.size.bytes();
|
||||
let init = |this: &mut Self, val: Value| {
|
||||
let zero_val = match val {
|
||||
Value::ByRef(PtrAndAlign { ptr, .. }) => {
|
||||
Value::ByRef(ptr, _) => {
|
||||
// These writes have no alignment restriction anyway.
|
||||
this.memory.write_repeat(ptr, 0, size)?;
|
||||
val
|
||||
|
|
@ -326,7 +335,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
let ptr = this.alloc_ptr(dest_layout.ty)?;
|
||||
let ptr = Pointer::from(PrimVal::Ptr(ptr));
|
||||
this.memory.write_repeat(ptr, 0, size)?;
|
||||
Value::by_ref(ptr)
|
||||
Value::ByRef(ptr, dest_layout.align)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -340,12 +349,11 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
match dest {
|
||||
Place::Local { frame, local } => self.modify_local(frame, local, init)?,
|
||||
Place::Ptr {
|
||||
ptr: PtrAndAlign { ptr, aligned: true },
|
||||
ptr: ptr,
|
||||
align: _align,
|
||||
extra: PlaceExtra::None,
|
||||
} => self.memory.write_repeat(ptr, 0, size)?,
|
||||
Place::Ptr { .. } => {
|
||||
bug!("init intrinsic tried to write to fat or unaligned ptr target")
|
||||
}
|
||||
_ => bug!("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +375,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"move_val_init" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ptr = self.into_ptr(args[0].value)?;
|
||||
self.write_value_to_ptr(args[1].value, ptr, ty)?;
|
||||
let align = self.layout_of(args[0].ty)?.align;
|
||||
self.write_value_to_ptr(args[1].value, ptr, align, ty)?;
|
||||
}
|
||||
|
||||
"needs_drop" => {
|
||||
|
|
@ -533,14 +542,10 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
|
||||
"transmute" => {
|
||||
let src_ty = substs.type_at(0);
|
||||
let src_align = self.layout_of(src_ty)?.align;
|
||||
let ptr = self.force_allocation(dest)?.to_ptr()?;
|
||||
self.write_maybe_aligned_mut(
|
||||
/*aligned*/
|
||||
false,
|
||||
|ectx| {
|
||||
ectx.write_value_to_ptr(args[0].value, ptr.into(), src_ty)
|
||||
},
|
||||
)?;
|
||||
let dest_align = self.layout_of(substs.type_at(1))?.align;
|
||||
self.write_value_to_ptr(args[0].value, ptr.into(), dest_align, src_ty);
|
||||
}
|
||||
|
||||
"unchecked_shl" => {
|
||||
|
|
@ -612,7 +617,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
"uninit" => {
|
||||
let size = dest_layout.size.bytes();
|
||||
let uninit = |this: &mut Self, val: Value| match val {
|
||||
Value::ByRef(PtrAndAlign { ptr, .. }) => {
|
||||
Value::ByRef(ptr, _) => {
|
||||
this.memory.mark_definedness(ptr, size, false)?;
|
||||
Ok(val)
|
||||
}
|
||||
|
|
@ -621,12 +626,11 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
match dest {
|
||||
Place::Local { frame, local } => self.modify_local(frame, local, uninit)?,
|
||||
Place::Ptr {
|
||||
ptr: PtrAndAlign { ptr, aligned: true },
|
||||
ptr: ptr,
|
||||
align: _align,
|
||||
extra: PlaceExtra::None,
|
||||
} => self.memory.mark_definedness(ptr, size, false)?,
|
||||
Place::Ptr { .. } => {
|
||||
bug!("uninit intrinsic tried to write to fat or unaligned ptr target")
|
||||
}
|
||||
_ => bug!("todo"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +643,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
if count > 0 {
|
||||
// HashMap relies on write_bytes on a NULL ptr with count == 0 to work
|
||||
// TODO: Should we, at least, validate the alignment? (Also see the copy intrinsic)
|
||||
self.memory.check_align(ptr, ty_layout.align.abi(), Some(AccessKind::Write))?;
|
||||
self.memory.check_align(ptr, ty_layout.align)?;
|
||||
self.memory.write_repeat(ptr, val_byte, ty_layout.size.bytes() * count)?;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
miri/lib.rs
22
miri/lib.rs
|
|
@ -20,7 +20,6 @@ extern crate lazy_static;
|
|||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty::layout::{TyLayout, LayoutOf};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::mir;
|
||||
use rustc::traits;
|
||||
|
||||
|
|
@ -87,7 +86,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
|
||||
// Return value
|
||||
let size = ecx.tcx.data_layout.pointer_size.bytes();
|
||||
let align = ecx.tcx.data_layout.pointer_align.abi();
|
||||
let align = ecx.tcx.data_layout.pointer_align;
|
||||
let ret_ptr = ecx.memory_mut().allocate(size, align, Some(MemoryKind::Stack))?;
|
||||
cleanup_ptr = Some(ret_ptr);
|
||||
|
||||
|
|
@ -96,7 +95,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
start_instance,
|
||||
start_mir.span,
|
||||
start_mir,
|
||||
Place::from_ptr(ret_ptr),
|
||||
Place::from_ptr(ret_ptr, align),
|
||||
StackPopCleanup::None,
|
||||
)?;
|
||||
|
||||
|
|
@ -126,8 +125,9 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
let ty = ecx.tcx.mk_imm_ptr(ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8));
|
||||
let foo = ecx.memory.allocate_cached(b"foo\0");
|
||||
let ptr_size = ecx.memory.pointer_size();
|
||||
let foo_ptr = ecx.memory.allocate(ptr_size * 1, ptr_size, None)?;
|
||||
ecx.memory.write_primval(foo_ptr.into(), PrimVal::Ptr(foo.into()), ptr_size, false)?;
|
||||
let ptr_align = ecx.tcx.data_layout.pointer_align;
|
||||
let foo_ptr = ecx.memory.allocate(ptr_size, ptr_align, None)?;
|
||||
ecx.memory.write_primval(foo_ptr, ptr_align, PrimVal::Ptr(foo.into()), ptr_size, false)?;
|
||||
ecx.memory.mark_static_initalized(foo_ptr.alloc_id, Mutability::Immutable)?;
|
||||
ecx.write_ptr(dest, foo_ptr.into(), ty)?;
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
let mut ecx = EvalContext::new(tcx, ty::ParamEnv::empty(traits::Reveal::All), limits, Default::default(), Default::default(), Substs::empty());
|
||||
let mut ecx = EvalContext::new(tcx, ty::ParamEnv::empty(traits::Reveal::All), limits, Default::default(), Default::default());
|
||||
match run_main(&mut ecx, main_id, start_wrapper) {
|
||||
Ok(()) => {
|
||||
let leaks = ecx.memory().leak_report();
|
||||
|
|
@ -310,22 +310,20 @@ impl<'tcx> Machine<'tcx> for Evaluator<'tcx> {
|
|||
// FIXME: check that it's `#[linkage = "extern_weak"]`
|
||||
trace!("Initializing an extern global with NULL");
|
||||
let ptr_size = ecx.memory.pointer_size();
|
||||
let ptr_align = ecx.tcx.data_layout.pointer_align;
|
||||
let ptr = ecx.memory.allocate(
|
||||
ptr_size,
|
||||
ptr_size,
|
||||
ptr_align,
|
||||
None,
|
||||
)?;
|
||||
ecx.memory.write_ptr_sized_unsigned(ptr, PrimVal::Bytes(0))?;
|
||||
ecx.memory.write_ptr_sized_unsigned(ptr, ptr_align, PrimVal::Bytes(0))?;
|
||||
ecx.memory.mark_static_initalized(ptr.alloc_id, mutability)?;
|
||||
ecx.tcx.interpret_interner.borrow_mut().cache(
|
||||
GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
},
|
||||
PtrAndAlign {
|
||||
ptr: ptr.into(),
|
||||
aligned: true,
|
||||
},
|
||||
ptr.into(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
map_to_primval(left.overflowing_offset(right as u64, self)),
|
||||
|
||||
BitAnd if !signed => {
|
||||
let base_mask : u64 = !(self.memory.get(left.alloc_id)?.align - 1);
|
||||
let base_mask : u64 = !(self.memory.get(left.alloc_id)?.align.abi() - 1);
|
||||
let right = right as u64;
|
||||
if right & base_mask == base_mask {
|
||||
// Case 1: The base address bits are all preserved, i.e., right is all-1 there
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
// Check alignment and non-NULLness
|
||||
let (_, align) = self.size_and_align_of_dst(pointee_ty, val)?;
|
||||
let ptr = self.into_ptr(val)?;
|
||||
self.memory.check_align(ptr, align.abi(), None)?;
|
||||
self.memory.check_align(ptr, align)?;
|
||||
|
||||
// Recurse
|
||||
let pointee_place = self.val_to_place(val, pointee_ty)?;
|
||||
|
|
@ -567,7 +567,7 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator<'
|
|||
// Tracking the same state for locals not backed by memory would just duplicate too
|
||||
// much machinery.
|
||||
// FIXME: We ignore alignment.
|
||||
let (ptr, extra) = self.force_allocation(query.place.1)?.to_ptr_extra_aligned();
|
||||
let (ptr, _, extra) = self.force_allocation(query.place.1)?.to_ptr_align_extra();
|
||||
// Determine the size
|
||||
// FIXME: Can we reuse size_and_align_of_dst for Places?
|
||||
let layout = self.layout_of(query.ty)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue