Auto merge of #1487 - pnadon:miri-rename-undef-uninit, r=RalfJung

Miri rename undef uninit

The changes made here are related to [issue #71193 on Rust](https://github.com/rust-lang/rust/issues/71193), and the pull request [74664 on Rust](https://github.com/rust-lang/rust/pull/74664).

1. renamed `ScalarMaybeUninit::not_undef` to `check_init`
2. renamed `Immediate::to_scalar_or_undef` to `Immediate::to_scalar_or_uninit`
This commit is contained in:
bors 2020-07-27 21:31:51 +00:00
commit 345b033c3f
19 changed files with 99 additions and 99 deletions

View File

@ -1 +1 @@
0e11fc8053d32c44e7152865852acc5c3c54efb3
13f9aa190957b993a268fd4a046fce76ca8814ee

View File

@ -234,7 +234,7 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
}
}
}
let return_code = ecx.read_scalar(ret_place.into())?.not_undef()?.to_machine_isize(&ecx)?;
let return_code = ecx.read_scalar(ret_place.into())?.check_init()?.to_machine_isize(&ecx)?;
Ok(return_code)
})();

View File

@ -67,7 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
self.eval_context_mut()
.eval_path_scalar(&["libc", name])?
.not_undef()
.check_init()
}
/// Helper function to get a `libc` constant as an `i32`.
@ -80,7 +80,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn eval_windows(&mut self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
self.eval_context_mut()
.eval_path_scalar(&["std", "sys", "windows", module, name])?
.not_undef()
.check_init()
}
/// Helper function to get a `windows` constant as an `u64`.
@ -407,7 +407,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn get_last_error(&self) -> InterpResult<'tcx, Scalar<Tag>> {
let this = self.eval_context_ref();
let errno_place = this.machine.last_error.unwrap();
this.read_scalar(errno_place.into())?.not_undef()
this.read_scalar(errno_place.into())?.check_init()
}
/// Sets the last OS error using a `std::io::Error`. This function tries to produce the most
@ -467,7 +467,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}
}
fn read_scalar_at_offset(
&self,
op: OpTy<'tcx, Tag>,

View File

@ -32,11 +32,11 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
#[rustfmt::skip]
let eq = match (*left, *right) {
(Immediate::Scalar(left), Immediate::Scalar(right)) => {
self.ptr_eq(left.not_undef()?, right.not_undef()?)?
self.ptr_eq(left.check_init()?, right.check_init()?)?
}
(Immediate::ScalarPair(left1, left2), Immediate::ScalarPair(right1, right2)) => {
self.ptr_eq(left1.not_undef()?, right1.not_undef()?)?
&& self.ptr_eq(left2.not_undef()?, right2.not_undef()?)?
self.ptr_eq(left1.check_init()?, right1.check_init()?)?
&& self.ptr_eq(left2.check_init()?, right2.check_init()?)?
}
_ => bug!("Type system should not allow comparing Scalar with ScalarPair"),
};

View File

@ -69,7 +69,7 @@ impl<'tcx> EnvVars<'tcx> {
}
// Deallocate environ var list.
let environ = ecx.machine.env_vars.environ.unwrap();
let old_vars_ptr = ecx.read_scalar(environ.into())?.not_undef()?;
let old_vars_ptr = ecx.read_scalar(environ.into())?.check_init()?;
ecx.memory.deallocate(ecx.force_ptr(old_vars_ptr)?, None, MiriMemoryKind::Env.into())?;
Ok(())
}
@ -104,7 +104,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let target_os = &this.tcx.sess.target.target.target_os;
assert!(target_os == "linux" || target_os == "macos", "`getenv` is only available for the UNIX target family");
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let name_ptr = this.read_scalar(name_op)?.check_init()?;
let name = this.read_os_str_from_c_str(name_ptr)?;
Ok(match this.machine.env_vars.map.get(name) {
Some(var_ptr) => {
@ -125,7 +125,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetEnvironmentVariableW");
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let name_ptr = this.read_scalar(name_op)?.check_init()?;
let name = this.read_os_str_from_wide_str(name_ptr)?;
Ok(match this.machine.env_vars.map.get(&name) {
Some(var_ptr) => {
@ -135,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let var_ptr = Scalar::from(var_ptr.offset(Size::from_bytes(name_offset_bytes), this)?);
let var = this.read_os_str_from_wide_str(var_ptr)?;
let buf_ptr = this.read_scalar(buf_op)?.not_undef()?;
let buf_ptr = this.read_scalar(buf_op)?.check_init()?;
// `buf_size` represents the size in characters.
let buf_size = u64::from(this.read_scalar(size_op)?.to_u32()?);
windows_check_buffer_size(this.write_os_str_to_wide_str(&var, buf_ptr, buf_size)?)
@ -153,7 +153,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
this.assert_target_os("windows", "GetEnvironmentStringsW");
// Info on layout of environment blocks in Windows:
// Info on layout of environment blocks in Windows:
// https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
let mut env_vars = std::ffi::OsString::new();
for &item in this.machine.env_vars.map.values() {
@ -173,7 +173,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
this.assert_target_os("windows", "FreeEnvironmentStringsW");
let env_block_ptr = this.read_scalar(env_block_op)?.not_undef()?;
let env_block_ptr = this.read_scalar(env_block_op)?.check_init()?;
let result = this.memory.deallocate(this.force_ptr(env_block_ptr)?, None, MiriMemoryKind::Env.into());
// If the function succeeds, the return value is nonzero.
Ok(result.is_ok() as i32)
@ -188,8 +188,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let target_os = &this.tcx.sess.target.target.target_os;
assert!(target_os == "linux" || target_os == "macos", "`setenv` is only available for the UNIX target family");
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let value_ptr = this.read_scalar(value_op)?.not_undef()?;
let name_ptr = this.read_scalar(name_op)?.check_init()?;
let value_ptr = this.read_scalar(value_op)?.check_init()?;
let mut new = None;
if !this.is_null(name_ptr)? {
@ -224,14 +224,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let mut this = self.eval_context_mut();
this.assert_target_os("windows", "SetEnvironmentVariableW");
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let value_ptr = this.read_scalar(value_op)?.not_undef()?;
let name_ptr = this.read_scalar(name_op)?.check_init()?;
let value_ptr = this.read_scalar(value_op)?.check_init()?;
if this.is_null(name_ptr)? {
// ERROR CODE is not clearly explained in docs.. For now, throw UB instead.
throw_ub_format!("pointer to environment variable name is NULL");
}
let name = this.read_os_str_from_wide_str(name_ptr)?;
if name.is_empty() {
throw_unsup_format!("environment variable name is an empty string");
@ -261,7 +261,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let target_os = &this.tcx.sess.target.target.target_os;
assert!(target_os == "linux" || target_os == "macos", "`unsetenv` is only available for the UNIX target family");
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let name_ptr = this.read_scalar(name_op)?.check_init()?;
let mut success = None;
if !this.is_null(name_ptr)? {
let name = this.read_os_str_from_c_str(name_ptr)?.to_owned();
@ -295,7 +295,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("getcwd")?;
let buf = this.read_scalar(buf_op)?.not_undef()?;
let buf = this.read_scalar(buf_op)?.check_init()?;
let size = this.read_scalar(size_op)?.to_machine_usize(&*this.tcx)?;
// If we cannot get the current directory, we return null
match env::current_dir() {
@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("GetCurrentDirectoryW")?;
let size = u64::from(this.read_scalar(size_op)?.to_u32()?);
let buf = this.read_scalar(buf_op)?.not_undef()?;
let buf = this.read_scalar(buf_op)?.check_init()?;
// If we cannot get the current directory, we return 0
match env::current_dir() {
@ -341,7 +341,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("chdir")?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.check_init()?)?;
match env::set_current_dir(path) {
Ok(()) => Ok(0),
@ -362,7 +362,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("SetCurrentDirectoryW")?;
let path = this.read_path_from_wide_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_wide_str(this.read_scalar(path_op)?.check_init()?)?;
match env::set_current_dir(path) {
Ok(()) => Ok(1),
@ -379,7 +379,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
// Deallocate the old environ list, if any.
if let Some(environ) = this.machine.env_vars.environ {
let old_vars_ptr = this.read_scalar(environ.into())?.not_undef()?;
let old_vars_ptr = this.read_scalar(environ.into())?.check_init()?;
this.memory.deallocate(this.force_ptr(old_vars_ptr)?, None, MiriMemoryKind::Env.into())?;
} else {
// No `environ` allocated yet, let's do that.

View File

@ -200,7 +200,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Miri-specific extern functions
"miri_static_root" => {
let &[ptr] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let ptr = this.force_ptr(ptr)?;
if ptr.offset != Size::ZERO {
throw_unsup_format!("pointer passed to miri_static_root must point to beginning of an allocated block");
@ -226,12 +226,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"free" => {
let &[ptr] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
this.free(ptr, MiriMemoryKind::C)?;
}
"realloc" => {
let &[old_ptr, new_size] = check_arg_count(args)?;
let old_ptr = this.read_scalar(old_ptr)?.not_undef()?;
let old_ptr = this.read_scalar(old_ptr)?.check_init()?;
let new_size = this.read_scalar(new_size)?.to_machine_usize(this)?;
let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?;
this.write_scalar(res, dest)?;
@ -268,7 +268,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"__rust_dealloc" => {
let &[ptr, old_size, align] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let old_size = this.read_scalar(old_size)?.to_machine_usize(this)?;
let align = this.read_scalar(align)?.to_machine_usize(this)?;
// No need to check old_size/align; we anyway check that they match the allocation.
@ -281,7 +281,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"__rust_realloc" => {
let &[ptr, old_size, align, new_size] = check_arg_count(args)?;
let ptr = this.force_ptr(this.read_scalar(ptr)?.not_undef()?)?;
let ptr = this.force_ptr(this.read_scalar(ptr)?.check_init()?)?;
let old_size = this.read_scalar(old_size)?.to_machine_usize(this)?;
let align = this.read_scalar(align)?.to_machine_usize(this)?;
let new_size = this.read_scalar(new_size)?.to_machine_usize(this)?;
@ -301,8 +301,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// C memory handling functions
"memcmp" => {
let &[left, right, n] = check_arg_count(args)?;
let left = this.read_scalar(left)?.not_undef()?;
let right = this.read_scalar(right)?.not_undef()?;
let left = this.read_scalar(left)?.check_init()?;
let right = this.read_scalar(right)?.check_init()?;
let n = Size::from_bytes(this.read_scalar(n)?.to_machine_usize(this)?);
let result = {
@ -321,7 +321,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"memrchr" => {
let &[ptr, val, num] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let val = this.read_scalar(val)?.to_i32()? as u8;
let num = this.read_scalar(num)?.to_machine_usize(this)?;
if let Some(idx) = this
@ -339,7 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"memchr" => {
let &[ptr, val, num] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let val = this.read_scalar(val)?.to_i32()? as u8;
let num = this.read_scalar(num)?.to_machine_usize(this)?;
let idx = this
@ -356,7 +356,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"strlen" => {
let &[ptr] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let n = this.memory.read_c_str(ptr)?.len();
this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
}

View File

@ -68,9 +68,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size = elem_layout.size.checked_mul(count, this)
.ok_or_else(|| err_ub_format!("overflow computing total size of `{}`", intrinsic_name))?;
let src = this.read_scalar(src)?.not_undef()?;
let src = this.read_scalar(src)?.check_init()?;
let src = this.memory.check_ptr_access(src, size, elem_align)?;
let dest = this.read_scalar(dest)?.not_undef()?;
let dest = this.read_scalar(dest)?.check_init()?;
let dest = this.memory.check_ptr_access(dest, size, elem_align)?;
if let (Some(src), Some(dest)) = (src, dest) {
@ -105,7 +105,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let ty = instance.substs.type_at(0);
let ty_layout = this.layout_of(ty)?;
let val_byte = this.read_scalar(val_byte)?.to_u8()?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let count = this.read_scalar(count)?.to_machine_usize(this)?;
let byte_count = ty_layout.size.checked_mul(count, this)
.ok_or_else(|| err_ub_format!("overflow computing total size of `write_bytes`"))?;
@ -392,7 +392,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// `binary_op` will bail if either of them is not a scalar.
let eq = this.overflowing_binary_op(mir::BinOp::Eq, old, expect_old)?.0;
let res = Immediate::ScalarPair(old.to_scalar_or_undef(), eq.into());
let res = Immediate::ScalarPair(old.to_scalar_or_uninit(), eq.into());
// Return old value.
this.write_immediate(res, dest)?;
// Update ptr depending on comparison.
@ -503,7 +503,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Other
"assume" => {
let &[cond] = check_arg_count(args)?;
let cond = this.read_scalar(cond)?.not_undef()?.to_bool()?;
let cond = this.read_scalar(cond)?.check_init()?.to_bool()?;
if !cond {
throw_ub_format!("`assume` intrinsic called with `false`");
}

View File

@ -67,14 +67,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let (dest, ret) = ret.unwrap();
let req_align = this
.force_bits(this.read_scalar(align_op)?.not_undef()?, this.pointer_size())?;
.force_bits(this.read_scalar(align_op)?.check_init()?, this.pointer_size())?;
// Stop if the alignment is not a power of two.
if !req_align.is_power_of_two() {
return this.start_panic("align_offset: align is not a power-of-two", unwind);
}
let ptr_scalar = this.read_scalar(ptr_op)?.not_undef()?;
let ptr_scalar = this.read_scalar(ptr_op)?.check_init()?;
// Default: no result.
let mut result = this.machine_usize_max();

View File

@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Get the raw pointer stored in arg[0] (the panic payload).
let &[payload] = check_arg_count(args)?;
let payload = this.read_scalar(payload)?.not_undef()?;
let payload = this.read_scalar(payload)?.check_init()?;
assert!(
this.machine.panic_payload.is_none(),
"the panic runtime should avoid double-panics"
@ -81,9 +81,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Get all the arguments.
let &[try_fn, data, catch_fn] = check_arg_count(args)?;
let try_fn = this.read_scalar(try_fn)?.not_undef()?;
let data = this.read_scalar(data)?.not_undef()?;
let catch_fn = this.read_scalar(catch_fn)?.not_undef()?;
let try_fn = this.read_scalar(try_fn)?.check_init()?;
let data = this.read_scalar(data)?.check_init()?;
let catch_fn = this.read_scalar(catch_fn)?.check_init()?;
// Now we make a function call, and pass `data` as first and only argument.
let f_instance = this.memory.get_fn(try_fn)?.as_instance()?;

View File

@ -65,7 +65,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"read" => {
let &[fd, buf, count] = check_arg_count(args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_scalar(buf)?.not_undef()?;
let buf = this.read_scalar(buf)?.check_init()?;
let count = this.read_scalar(count)?.to_machine_usize(this)?;
let result = if fd == 0 {
@ -109,7 +109,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"write" => {
let &[fd, buf, n] = check_arg_count(args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_scalar(buf)?.not_undef()?;
let buf = this.read_scalar(buf)?.check_init()?;
let count = this.read_scalar(n)?.to_machine_usize(this)?;
trace!("Called write({:?}, {:?}, {:?})", fd, buf, count);
let result = if fd == 0 {
@ -225,7 +225,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"dlsym" => {
let &[handle, symbol] = check_arg_count(args)?;
this.read_scalar(handle)?.to_machine_usize(this)?;
let symbol = this.read_scalar(symbol)?.not_undef()?;
let symbol = this.read_scalar(symbol)?.check_init()?;
let symbol_name = this.memory.read_c_str(symbol)?;
if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.target.target_os)? {
let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));
@ -263,7 +263,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"pthread_key_create" => {
let &[key, dtor] = check_arg_count(args)?;
let key_place = this.deref_operand(key)?;
let dtor = this.read_scalar(dtor)?.not_undef()?;
let dtor = this.read_scalar(dtor)?.check_init()?;
// Extract the function type out of the signature (that seems easier than constructing it ourselves).
let dtor = match this.test_null(dtor)? {
@ -290,23 +290,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"pthread_key_delete" => {
let &[key] = check_arg_count(args)?;
let key = this.force_bits(this.read_scalar(key)?.not_undef()?, key.layout.size)?;
let key = this.force_bits(this.read_scalar(key)?.check_init()?, key.layout.size)?;
this.machine.tls.delete_tls_key(key)?;
// Return success (0)
this.write_null(dest)?;
}
"pthread_getspecific" => {
let &[key] = check_arg_count(args)?;
let key = this.force_bits(this.read_scalar(key)?.not_undef()?, key.layout.size)?;
let key = this.force_bits(this.read_scalar(key)?.check_init()?, key.layout.size)?;
let active_thread = this.get_active_thread();
let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
this.write_scalar(ptr, dest)?;
}
"pthread_setspecific" => {
let &[key, new_ptr] = check_arg_count(args)?;
let key = this.force_bits(this.read_scalar(key)?.not_undef()?, key.layout.size)?;
let key = this.force_bits(this.read_scalar(key)?.check_init()?, key.layout.size)?;
let active_thread = this.get_active_thread();
let new_ptr = this.read_scalar(new_ptr)?.not_undef()?;
let new_ptr = this.read_scalar(new_ptr)?.check_init()?;
this.machine.tls.store_tls(key, active_thread, this.test_null(new_ptr)?)?;
// Return success (`0`).
@ -462,9 +462,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"pthread_atfork" => {
let &[prepare, parent, child] = check_arg_count(args)?;
this.force_bits(this.read_scalar(prepare)?.not_undef()?, this.memory.pointer_size())?;
this.force_bits(this.read_scalar(parent)?.not_undef()?, this.memory.pointer_size())?;
this.force_bits(this.read_scalar(child)?.not_undef()?, this.memory.pointer_size())?;
this.force_bits(this.read_scalar(prepare)?.check_init()?, this.memory.pointer_size())?;
this.force_bits(this.read_scalar(parent)?.check_init()?, this.memory.pointer_size())?;
this.force_bits(this.read_scalar(child)?.check_init()?, this.memory.pointer_size())?;
// We do not support forking, so there is nothing to do here.
this.write_null(dest)?;
}

View File

@ -81,7 +81,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, '
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let path_scalar = this.read_scalar(path_op)?.not_undef()?;
let path_scalar = this.read_scalar(path_op)?.check_init()?;
let path = this.read_path_from_c_str(path_scalar)?.into_owned();
let metadata = match FileMetadata::from_path(this, &path, follow_symlink)? {
@ -334,7 +334,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
throw_unsup_format!("unsupported flags {:#x}", flag & !mirror);
}
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.check_init()?)?;
let fd = options.open(&path).map(|file| {
let fh = &mut this.machine.file_handler;
@ -558,7 +558,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("unlink")?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.check_init()?)?;
let result = remove_file(path).map(|_| 0);
this.try_unwrap_io_result(result)
@ -588,8 +588,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("symlink")?;
let target = this.read_path_from_c_str(this.read_scalar(target_op)?.not_undef()?)?;
let linkpath = this.read_path_from_c_str(this.read_scalar(linkpath_op)?.not_undef()?)?;
let target = this.read_path_from_c_str(this.read_scalar(target_op)?.check_init()?)?;
let linkpath = this.read_path_from_c_str(this.read_scalar(linkpath_op)?.check_init()?)?;
let result = create_link(&target, &linkpath).map(|_| 0);
this.try_unwrap_io_result(result)
@ -651,8 +651,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.assert_target_os("linux", "statx");
this.check_no_isolation("statx")?;
let statxbuf_scalar = this.read_scalar(statxbuf_op)?.not_undef()?;
let pathname_scalar = this.read_scalar(pathname_op)?.not_undef()?;
let statxbuf_scalar = this.read_scalar(statxbuf_op)?.check_init()?;
let pathname_scalar = this.read_scalar(pathname_op)?.check_init()?;
// If the statxbuf or pathname pointers are null, the function fails with `EFAULT`.
if this.is_null(statxbuf_scalar)? || this.is_null(pathname_scalar)? {
@ -810,8 +810,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("rename")?;
let oldpath_scalar = this.read_scalar(oldpath_op)?.not_undef()?;
let newpath_scalar = this.read_scalar(newpath_op)?.not_undef()?;
let oldpath_scalar = this.read_scalar(oldpath_op)?.check_init()?;
let newpath_scalar = this.read_scalar(newpath_op)?.check_init()?;
if this.is_null(oldpath_scalar)? || this.is_null(newpath_scalar)? {
let efault = this.eval_libc("EFAULT")?;
@ -838,12 +838,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
#[cfg_attr(not(unix), allow(unused_variables))]
let mode = if this.tcx.sess.target.target.target_os == "macos" {
u32::from(this.read_scalar(mode_op)?.not_undef()?.to_u16()?)
u32::from(this.read_scalar(mode_op)?.check_init()?.to_u16()?)
} else {
this.read_scalar(mode_op)?.to_u32()?
};
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.check_init()?)?;
#[cfg_attr(not(unix), allow(unused_mut))]
let mut builder = DirBuilder::new();
@ -869,7 +869,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("rmdir")?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.not_undef()?)?;
let path = this.read_path_from_c_str(this.read_scalar(path_op)?.check_init()?)?;
let result = remove_dir(path).map(|_| 0i32);
@ -881,7 +881,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("opendir")?;
let name = this.read_path_from_c_str(this.read_scalar(name_op)?.not_undef()?)?;
let name = this.read_path_from_c_str(this.read_scalar(name_op)?.check_init()?)?;
let result = read_dir(name);

View File

@ -181,7 +181,7 @@ fn getrandom<'tcx>(
flags: OpTy<'tcx, Tag>,
dest: PlaceTy<'tcx, Tag>,
) -> InterpResult<'tcx> {
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let len = this.read_scalar(len)?.to_machine_usize(this)?;
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,

View File

@ -35,7 +35,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
match dlsym {
Dlsym::getentropy => {
let &[ptr, len] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let len = this.read_scalar(len)?.to_machine_usize(this)?;
this.gen_random(ptr, len)?;
this.write_null(dest)?;

View File

@ -98,9 +98,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Thread-local storage
"_tlv_atexit" => {
let &[dtor, data] = check_arg_count(args)?;
let dtor = this.read_scalar(dtor)?.not_undef()?;
let dtor = this.read_scalar(dtor)?.check_init()?;
let dtor = this.memory.get_fn(dtor)?.as_instance()?;
let data = this.read_scalar(data)?.not_undef()?;
let data = this.read_scalar(data)?.check_init()?;
let active_thread = this.get_active_thread();
this.machine.tls.set_macos_thread_dtor(active_thread, dtor, data)?;
}
@ -122,7 +122,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Threading
"pthread_setname_np" => {
let &[name] = check_arg_count(args)?;
let name = this.read_scalar(name)?.not_undef()?;
let name = this.read_scalar(name)?.check_init()?;
this.pthread_setname_np(name)?;
}
@ -131,7 +131,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"mmap" if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
// This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.
let &[addr, _, _, _, _, _] = check_arg_count(args)?;
let addr = this.read_scalar(addr)?.not_undef()?;
let addr = this.read_scalar(addr)?.check_init()?;
this.write_scalar(addr, dest)?;
}

View File

@ -288,7 +288,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = this.read_scalar(kind_op)?.not_undef()?;
let kind = this.read_scalar(kind_op)?.check_init()?;
if kind == this.eval_libc("PTHREAD_MUTEX_NORMAL")? {
// In `glibc` implementation, the numeric values of
// `PTHREAD_MUTEX_NORMAL` and `PTHREAD_MUTEX_DEFAULT` are equal.
@ -337,11 +337,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let attr = this.read_scalar(attr_op)?.not_undef()?;
let attr = this.read_scalar(attr_op)?.check_init()?;
let kind = if this.is_null(attr)? {
this.eval_libc("PTHREAD_MUTEX_DEFAULT")?
} else {
mutexattr_get_kind(this, attr_op)?.not_undef()?
mutexattr_get_kind(this, attr_op)?.check_init()?
};
// Write 0 to use the same code path as the static initializers.
@ -355,7 +355,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn pthread_mutex_lock(&mut self, mutex_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.not_undef()?;
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
let id = mutex_get_or_create_id(this, mutex_op)?;
let active_thread = this.get_active_thread();
@ -392,7 +392,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn pthread_mutex_trylock(&mut self, mutex_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.not_undef()?;
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
let id = mutex_get_or_create_id(this, mutex_op)?;
let active_thread = this.get_active_thread();
@ -425,7 +425,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
fn pthread_mutex_unlock(&mut self, mutex_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let kind = mutex_get_kind(this, mutex_op)?.not_undef()?;
let kind = mutex_get_kind(this, mutex_op)?.check_init()?;
let id = mutex_get_or_create_id(this, mutex_op)?;
let active_thread = this.get_active_thread();
@ -589,7 +589,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let clock_id = this.read_scalar(clock_id_op)?.not_undef()?;
let clock_id = this.read_scalar(clock_id_op)?.check_init()?;
if clock_id == this.eval_libc("CLOCK_REALTIME")?
|| clock_id == this.eval_libc("CLOCK_MONOTONIC")?
{
@ -630,11 +630,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let attr = this.read_scalar(attr_op)?.not_undef()?;
let attr = this.read_scalar(attr_op)?.check_init()?;
let clock_id = if this.is_null(attr)? {
this.eval_libc("CLOCK_REALTIME")?
} else {
condattr_get_clock_id(this, attr_op)?.not_undef()?
condattr_get_clock_id(this, attr_op)?.check_init()?
};
// Write 0 to use the same code path as the static initializers.

View File

@ -29,7 +29,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
thread_info_place.into(),
)?;
let fn_ptr = this.read_scalar(start_routine)?.not_undef()?;
let fn_ptr = this.read_scalar(start_routine)?.check_init()?;
let instance = this.memory.get_fn(fn_ptr)?.as_instance()?;
let func_arg = this.read_immediate(arg)?;
@ -59,7 +59,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
if !this.is_null(this.read_scalar(retval)?.not_undef()?)? {
if !this.is_null(this.read_scalar(retval)?.check_init()?)? {
// FIXME: implement reading the thread function's return place.
throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
}
@ -99,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let option = this.read_scalar(option)?.to_i32()?;
if option == this.eval_libc_i32("PR_SET_NAME")? {
let address = this.read_scalar(arg2)?.not_undef()?;
let address = this.read_scalar(arg2)?.check_init()?;
let mut name = this.memory.read_c_str(address)?.to_owned();
// The name should be no more than 16 bytes, including the null
// byte. Since `read_c_str` returns the string without the null
@ -107,7 +107,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
name.truncate(15);
this.set_active_thread_name(name);
} else if option == this.eval_libc_i32("PR_GET_NAME")? {
let address = this.read_scalar(arg2)?.not_undef()?;
let address = this.read_scalar(arg2)?.check_init()?;
let mut name = this.get_active_thread_name().to_vec();
name.push(0u8);
assert!(name.len() <= 16);

View File

@ -62,7 +62,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("gettimeofday")?;
// Using tz is obsolete and should always be null
let tz = this.read_scalar(tz_op)?.not_undef()?;
let tz = this.read_scalar(tz_op)?.check_init()?;
if !this.is_null(tz)? {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;

View File

@ -237,7 +237,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// we specifically look up the static in libstd that we know is placed
// in that section.
let thread_callback = this.eval_path_scalar(&["std", "sys", "windows", "thread_local_key", "p_thread_callback"])?;
let thread_callback = this.memory.get_fn(thread_callback.not_undef()?)?.as_instance()?;
let thread_callback = this.memory.get_fn(thread_callback.check_init()?)?.as_instance()?;
// The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`.
let reason = this.eval_path_scalar(&["std", "sys", "windows", "c", "DLL_THREAD_DETACH"])?;

View File

@ -67,7 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let &[handle, buf, n, written_ptr, overlapped] = check_arg_count(args)?;
this.read_scalar(overlapped)?.to_machine_usize(this)?; // this is a poiner, that we ignore
let handle = this.read_scalar(handle)?.to_machine_isize(this)?;
let buf = this.read_scalar(buf)?.not_undef()?;
let buf = this.read_scalar(buf)?.check_init()?;
let n = this.read_scalar(n)?.to_u32()?;
let written_place = this.deref_operand(written_ptr)?;
// Spec says to always write `0` first.
@ -111,7 +111,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let &[handle, flags, ptr] = check_arg_count(args)?;
this.read_scalar(handle)?.to_machine_isize(this)?;
this.read_scalar(flags)?.to_u32()?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
this.free(ptr, MiriMemoryKind::WinHeap)?;
this.write_scalar(Scalar::from_i32(1), dest)?;
}
@ -119,7 +119,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let &[handle, flags, ptr, size] = check_arg_count(args)?;
this.read_scalar(handle)?.to_machine_isize(this)?;
this.read_scalar(flags)?.to_u32()?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let size = this.read_scalar(size)?.to_machine_usize(this)?;
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
this.write_scalar(res, dest)?;
@ -128,7 +128,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// errno
"SetLastError" => {
let &[error] = check_arg_count(args)?;
let error = this.read_scalar(error)?.not_undef()?;
let error = this.read_scalar(error)?.check_init()?;
this.set_last_error(error)?;
}
"GetLastError" => {
@ -172,7 +172,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let &[key, new_ptr] = check_arg_count(args)?;
let key = u128::from(this.read_scalar(key)?.to_u32()?);
let active_thread = this.get_active_thread();
let new_ptr = this.read_scalar(new_ptr)?.not_undef()?;
let new_ptr = this.read_scalar(new_ptr)?.check_init()?;
this.machine.tls.store_tls(key, active_thread, this.test_null(new_ptr)?)?;
// Return success (`1`).
@ -212,7 +212,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
#[allow(non_snake_case)]
let &[hModule, lpProcName] = check_arg_count(args)?;
this.read_scalar(hModule)?.to_machine_isize(this)?;
let name = this.memory.read_c_str(this.read_scalar(lpProcName)?.not_undef()?)?;
let name = this.memory.read_c_str(this.read_scalar(lpProcName)?.check_init()?)?;
if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.target.target_os)? {
let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));
this.write_scalar(Scalar::from(ptr), dest)?;
@ -225,7 +225,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"SystemFunction036" => {
// The actual name of 'RtlGenRandom'
let &[ptr, len] = check_arg_count(args)?;
let ptr = this.read_scalar(ptr)?.not_undef()?;
let ptr = this.read_scalar(ptr)?.check_init()?;
let len = this.read_scalar(len)?.to_u32()?;
this.gen_random(ptr, len.into())?;
this.write_scalar(Scalar::from_bool(true), dest)?;