diff --git a/rust-version b/rust-version index d0c938c53faf..211af60b88aa 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -0e11fc8053d32c44e7152865852acc5c3c54efb3 +13f9aa190957b993a268fd4a046fce76ca8814ee diff --git a/src/eval.rs b/src/eval.rs index 24cf0cbf06be..8561edcc05b9 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -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) })(); diff --git a/src/helpers.rs b/src/helpers.rs index 473da84aeea3..d271b845c215 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -67,7 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar> { 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> { 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> { 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>, diff --git a/src/operator.rs b/src/operator.rs index bfc8e908dc15..5b86b9a76f6b 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -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"), }; diff --git a/src/shims/env.rs b/src/shims/env.rs index 4a2bec28bd17..86a7a58ac4aa 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -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. diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 7323a664bda8..98e66db92da3 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -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)?; } diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index f542bebd82ad..ee64b1ffca44 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -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`"); } diff --git a/src/shims/mod.rs b/src/shims/mod.rs index 56754a9ebde5..05dd4059eb1b 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -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(); diff --git a/src/shims/panic.rs b/src/shims/panic.rs index 8e291c201215..45a41b9b7be0 100644 --- a/src/shims/panic.rs +++ b/src/shims/panic.rs @@ -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()?; diff --git a/src/shims/posix/foreign_items.rs b/src/shims/posix/foreign_items.rs index 80611a18e4fc..4bb94ae89449 100644 --- a/src/shims/posix/foreign_items.rs +++ b/src/shims/posix/foreign_items.rs @@ -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)?; } diff --git a/src/shims/posix/fs.rs b/src/shims/posix/fs.rs index a43e86dcc5b5..a50228a4847c 100644 --- a/src/shims/posix/fs.rs +++ b/src/shims/posix/fs.rs @@ -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); diff --git a/src/shims/posix/linux/foreign_items.rs b/src/shims/posix/linux/foreign_items.rs index ff30609d9ab2..ccb0ef8226e6 100644 --- a/src/shims/posix/linux/foreign_items.rs +++ b/src/shims/posix/linux/foreign_items.rs @@ -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, diff --git a/src/shims/posix/macos/dlsym.rs b/src/shims/posix/macos/dlsym.rs index 8256c10b0d39..0236b10e5fc8 100644 --- a/src/shims/posix/macos/dlsym.rs +++ b/src/shims/posix/macos/dlsym.rs @@ -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)?; diff --git a/src/shims/posix/macos/foreign_items.rs b/src/shims/posix/macos/foreign_items.rs index ef649c3e8406..2e7258c800ac 100644 --- a/src/shims/posix/macos/foreign_items.rs +++ b/src/shims/posix/macos/foreign_items.rs @@ -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)?; } diff --git a/src/shims/posix/sync.rs b/src/shims/posix/sync.rs index cce0ddc930df..28a45b194771 100644 --- a/src/shims/posix/sync.rs +++ b/src/shims/posix/sync.rs @@ -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. diff --git a/src/shims/posix/thread.rs b/src/shims/posix/thread.rs index e5d3a9f0d6f8..7c9c489e6fb4 100644 --- a/src/shims/posix/thread.rs +++ b/src/shims/posix/thread.rs @@ -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); diff --git a/src/shims/time.rs b/src/shims/time.rs index e26d2ce2e39d..193c87f7f099 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -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)?; diff --git a/src/shims/tls.rs b/src/shims/tls.rs index d2d5522c4023..8d05442ad6bc 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -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"])?; diff --git a/src/shims/windows/foreign_items.rs b/src/shims/windows/foreign_items.rs index e8937bbb3085..fc1093b64fb4 100644 --- a/src/shims/windows/foreign_items.rs +++ b/src/shims/windows/foreign_items.rs @@ -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)?;