diff --git a/rust-version b/rust-version index 1c3f12298f..dd16aa7af9 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -660326e9791d5caf3186b14521498c2584a494ab +57e1da59cd0761330b4ea8d47b16340a78eeafa9 diff --git a/src/helpers.rs b/src/helpers.rs index ecb3a5d8bc..169bb42056 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -18,7 +18,7 @@ use crate::*; impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} /// Gets an instance for a path. -fn resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> InterpResult<'tcx, DefId> { +fn try_resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> Option { tcx.crates() .iter() .find(|&&krate| tcx.original_crate_name(krate).as_str() == path[0]) @@ -41,19 +41,47 @@ fn resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> InterpResult<'tc } None }) - .ok_or_else(|| { - let path = path.iter().map(|&s| s.to_owned()).collect(); - err_unsup!(PathNotFound(path)).into() - }) } pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { /// Gets an instance for a path. - fn resolve_path(&self, path: &[&str]) -> InterpResult<'tcx, ty::Instance<'tcx>> { - Ok(ty::Instance::mono( - self.eval_context_ref().tcx.tcx, - resolve_did(self.eval_context_ref().tcx.tcx, path)?, - )) + fn resolve_path(&self, path: &[&str]) -> ty::Instance<'tcx> { + let did = try_resolve_did(self.eval_context_ref().tcx.tcx, path) + .unwrap_or_else(|| panic!("failed to find required Rust item: {:?}", path)); + ty::Instance::mono(self.eval_context_ref().tcx.tcx, did) + } + + /// Evaluates the scalar at the specified path. Returns Some(val) + /// if the path could be resolved, and None otherwise + fn eval_path_scalar( + &mut self, + path: &[&str], + ) -> InterpResult<'tcx, ScalarMaybeUndef> { + let this = self.eval_context_mut(); + let instance = this.resolve_path(path); + let cid = GlobalId { instance, promoted: None }; + let const_val = this.const_eval_raw(cid)?; + let const_val = this.read_scalar(const_val.into())?; + return Ok(const_val); + } + + /// Helper function to get a `libc` constant as a `Scalar`. + fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar> { + self.eval_context_mut() + .eval_path_scalar(&["libc", name])? + .not_undef() + } + + /// Helper function to get a `libc` constant as an `i32`. + fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> { + self.eval_libc(name)?.to_i32() + } + + /// Helper function to get the `TyLayout` of a `libc` type + fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> { + let this = self.eval_context_mut(); + let ty = this.resolve_path(&["libc", name]).monomorphic_ty(*this.tcx); + this.layout_of(ty) } /// Write a 0 of the appropriate size to `dest`. @@ -98,7 +126,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx if this.machine.communicate { // Fill the buffer using the host's rng. getrandom::getrandom(&mut data) - .map_err(|err| err_unsup_format!("getrandom failed: {}", err))?; + .map_err(|err| err_unsup_format!("host getrandom failed: {}", err))?; } else { let rng = this.memory.extra.rng.get_mut(); rng.fill_bytes(&mut data); @@ -313,26 +341,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } } - /// Helper function to get a `libc` constant as a `Scalar`. - fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar> { - self.eval_context_mut() - .eval_path_scalar(&["libc", name])? - .ok_or_else(|| err_unsup_format!("Path libc::{} cannot be resolved.", name))? - .not_undef() - } - - /// Helper function to get a `libc` constant as an `i32`. - fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> { - self.eval_libc(name)?.to_i32() - } - - /// Helper function to get the `TyLayout` of a `libc` type - fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> { - let this = self.eval_context_mut(); - let ty = this.resolve_path(&["libc", name])?.monomorphic_ty(*this.tcx); - this.layout_of(ty) - } - // Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack // different values into a struct. fn write_packed_immediates( @@ -360,7 +368,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx fn check_no_isolation(&self, name: &str) -> InterpResult<'tcx> { if !self.eval_context_ref().machine.communicate { throw_unsup_format!( - "`{}` not available when isolation is enabled. Pass the flag `-Zmiri-disable-isolation` to disable it.", + "`{}` not available when isolation is enabled (pass the flag `-Zmiri-disable-isolation` to disable isolation)", name, ) } @@ -416,13 +424,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx AlreadyExists => "EEXIST", WouldBlock => "EWOULDBLOCK", _ => { - throw_unsup_format!("The {} error cannot be transformed into a raw os error", e) + throw_unsup_format!("io error {} cannot be transformed into a raw os error", e) } })? } else { // FIXME: we have to implement the Windows equivalent of this. throw_unsup_format!( - "Setting the last OS error from an io::Error is unsupported for {}.", + "setting the last OS error from an io::Error is unsupported for {}.", target.target_os ) }; @@ -531,7 +539,7 @@ pub fn immty_from_int_checked<'tcx>( ) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> { let int = int.into(); Ok(ImmTy::try_from_int(int, layout).ok_or_else(|| { - err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits()) + err_unsup_format!("signed value {:#x} does not fit in {} bits", int, layout.size.bits()) })?) } @@ -541,6 +549,6 @@ pub fn immty_from_uint_checked<'tcx>( ) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> { let int = int.into(); Ok(ImmTy::try_from_uint(int, layout).ok_or_else(|| { - err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits()) + err_unsup_format!("unsigned value {:#x} does not fit in {} bits", int, layout.size.bits()) })?) } diff --git a/src/intptrcast.rs b/src/intptrcast.rs index 91d9f4e84e..20a3b79980 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -43,10 +43,6 @@ impl<'mir, 'tcx> GlobalState { int: u64, memory: &Memory<'mir, 'tcx, Evaluator<'tcx>>, ) -> InterpResult<'tcx, Pointer> { - if int == 0 { - throw_unsup!(InvalidNullPointerUsage); - } - let global_state = memory.extra.intptrcast.borrow(); let pos = global_state.int_to_ptr_map.binary_search_by_key(&int, |(addr, _)| *addr); @@ -57,7 +53,7 @@ impl<'mir, 'tcx> GlobalState { // zero. The pointer is untagged because it was created from a cast Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged) } - Err(0) => throw_unsup!(DanglingPointerDeref), + Err(0) => throw_ub!(InvalidIntPointerUsage(int)), Err(pos) => { // This is the largest of the adresses smaller than `int`, // i.e. the greatest lower bound (glb) @@ -69,7 +65,7 @@ impl<'mir, 'tcx> GlobalState { // This pointer is untagged because it was created from a cast Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged) } else { - throw_unsup!(DanglingPointerDeref) + throw_ub!(InvalidIntPointerUsage(int)) } } }) diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs index 9027a97cf5..b0e1850ec5 100644 --- a/src/shims/dlsym.rs +++ b/src/shims/dlsym.rs @@ -15,7 +15,7 @@ impl Dlsym { Ok(match name { "getentropy" => Some(GetEntropy), "__pthread_get_minstack" => None, - _ => throw_unsup_format!("Unsupported dlsym: {}", name), + _ => throw_unsup_format!("unsupported dlsym: {}", name), }) } } diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index deabbdd608..fab90e3cc5 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -165,7 +165,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx .expect("No panic runtime found!"); let panic_runtime = tcx.crate_name(*panic_runtime); let start_panic_instance = - this.resolve_path(&[&*panic_runtime.as_str(), link_name])?; + this.resolve_path(&[&*panic_runtime.as_str(), link_name]); return Ok(Some(&*this.load_mir(start_panic_instance.def, None)?)); } _ => {} @@ -222,12 +222,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "__rust_alloc" => { let size = this.read_scalar(args[0])?.to_machine_usize(this)?; let align = this.read_scalar(args[1])?.to_machine_usize(this)?; - if size == 0 { - throw_unsup!(HeapAllocZeroBytes); - } - if !align.is_power_of_two() { - throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align)); - } + Self::check_alloc_request(size, align)?; let ptr = this.memory.allocate( Size::from_bytes(size), Align::from_bytes(align).unwrap(), @@ -238,12 +233,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "__rust_alloc_zeroed" => { let size = this.read_scalar(args[0])?.to_machine_usize(this)?; let align = this.read_scalar(args[1])?.to_machine_usize(this)?; - if size == 0 { - throw_unsup!(HeapAllocZeroBytes); - } - if !align.is_power_of_two() { - throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align)); - } + Self::check_alloc_request(size, align)?; let ptr = this.memory.allocate( Size::from_bytes(size), Align::from_bytes(align).unwrap(), @@ -257,12 +247,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let ptr = this.read_scalar(args[0])?.not_undef()?; let old_size = this.read_scalar(args[1])?.to_machine_usize(this)?; let align = this.read_scalar(args[2])?.to_machine_usize(this)?; - if old_size == 0 { - throw_unsup!(HeapAllocZeroBytes); - } - if !align.is_power_of_two() { - throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align)); - } + // No need to check old_size/align; we anyway check that they match the allocation. let ptr = this.force_ptr(ptr)?; this.memory.deallocate( ptr, @@ -274,12 +259,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let old_size = this.read_scalar(args[1])?.to_machine_usize(this)?; let align = this.read_scalar(args[2])?.to_machine_usize(this)?; let new_size = this.read_scalar(args[3])?.to_machine_usize(this)?; - if old_size == 0 || new_size == 0 { - throw_unsup!(HeapAllocZeroBytes); - } - if !align.is_power_of_two() { - throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align)); - } + Self::check_alloc_request(new_size, align)?; + // No need to check old_size; we anyway check that they match the allocation. let ptr = this.force_ptr(this.read_scalar(args[0])?.not_undef()?)?; let align = Align::from_bytes(align).unwrap(); let new_ptr = this.memory.reallocate( @@ -455,26 +436,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx _ => match this.tcx.sess.target.target.target_os.as_str() { "linux" | "macos" => return posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret), "windows" => return windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret), - target => throw_unsup_format!("The {} target platform is not supported", target), + target => throw_unsup_format!("the {} target platform is not supported", target), } }; Ok(true) } - /// Evaluates the scalar at the specified path. Returns Some(val) - /// if the path could be resolved, and None otherwise - fn eval_path_scalar( - &mut self, - path: &[&str], - ) -> InterpResult<'tcx, Option>> { - let this = self.eval_context_mut(); - if let Ok(instance) = this.resolve_path(path) { - let cid = GlobalId { instance, promoted: None }; - let const_val = this.const_eval_raw(cid)?; - let const_val = this.read_scalar(const_val.into())?; - return Ok(Some(const_val)); + /// Check some basic requirements for this allocation request: + /// non-zero size, power-of-two alignment. + fn check_alloc_request(size: u64, align: u64) -> InterpResult<'tcx> { + if size == 0 { + throw_ub_format!("creating allocation with size 0"); + } + if !align.is_power_of_two() { + throw_ub_format!("creating allocation with non-power-of-two alignment {}", align); } - return Ok(None); + Ok(()) } } diff --git a/src/shims/foreign_items/posix.rs b/src/shims/foreign_items/posix.rs index f73ec28828..85e9b88b6e 100644 --- a/src/shims/foreign_items/posix.rs +++ b/src/shims/foreign_items/posix.rs @@ -138,7 +138,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let size = this.read_scalar(args[2])?.to_machine_usize(this)?; // Align must be power of 2, and also at least ptr-sized (POSIX rules). if !align.is_power_of_two() { - throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align)); + throw_ub_format!("posix_memalign: alignment must be a power of two, but is {}", align); } if align < this.pointer_size().bytes() { throw_ub_format!( @@ -185,7 +185,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }; // Figure out how large a pthread TLS key actually is. - // This is `libc::pthread_key_t`. + // To this end, deref the argument type. This is `libc::pthread_key_t`. let key_type = args[0].layout.ty .builtin_deref(true) .ok_or_else(|| err_ub_format!( @@ -195,12 +195,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let key_layout = this.layout_of(key_type)?; // Create key and write it into the memory where `key_ptr` wants it. - let key = this.machine.tls.create_tls_key(dtor) as u128; - if key_layout.size.bits() < 128 && key >= (1u128 << key_layout.size.bits() as u128) - { - throw_unsup!(OutOfTls); - } - + let key = this.machine.tls.create_tls_key(dtor, key_layout.size)?; this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?; // Return success (`0`). @@ -294,28 +289,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx trace!("sysconf() called with name {}", name); // TODO: Cache the sysconf integers via Miri's global cache. - let paths = &[ - (&["libc", "_SC_PAGESIZE"], Scalar::from_int(PAGE_SIZE, dest.layout.size)), - (&["libc", "_SC_GETPW_R_SIZE_MAX"], Scalar::from_int(-1, dest.layout.size)), - ( - &["libc", "_SC_NPROCESSORS_ONLN"], - Scalar::from_int(NUM_CPUS, dest.layout.size), - ), + let sysconfs = &[ + ("_SC_PAGESIZE", Scalar::from_int(PAGE_SIZE, dest.layout.size)), + ("_SC_GETPW_R_SIZE_MAX", Scalar::from_int(-1, dest.layout.size)), + ("_SC_NPROCESSORS_ONLN", Scalar::from_int(NUM_CPUS, dest.layout.size)), ]; let mut result = None; - for &(path, path_value) in paths { - if let Some(val) = this.eval_path_scalar(path)? { - let val = val.to_i32()?; - if val == name { - result = Some(path_value); - break; - } + for &(sysconf_name, value) in sysconfs { + let sysconf_name = this.eval_libc_i32(sysconf_name)?; + if sysconf_name == name { + result = Some(value); + break; } } if let Some(result) = result { this.write_scalar(result, dest)?; } else { - throw_unsup_format!("Unimplemented sysconf name: {}", name) + throw_unsup_format!("unimplemented sysconf name: {}", name) } } diff --git a/src/shims/foreign_items/posix/linux.rs b/src/shims/foreign_items/posix/linux.rs index 023fee4ca7..82928c9bc1 100644 --- a/src/shims/foreign_items/posix/linux.rs +++ b/src/shims/foreign_items/posix/linux.rs @@ -56,13 +56,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "syscall" => { let sys_getrandom = this - .eval_path_scalar(&["libc", "SYS_getrandom"])? - .expect("Failed to get libc::SYS_getrandom") + .eval_libc("SYS_getrandom")? .to_machine_usize(this)?; let sys_statx = this - .eval_path_scalar(&["libc", "SYS_statx"])? - .expect("Failed to get libc::SYS_statx") + .eval_libc("SYS_statx")? .to_machine_usize(this)?; match this.read_scalar(args[0])?.to_machine_usize(this)? { diff --git a/src/shims/foreign_items/windows.rs b/src/shims/foreign_items/windows.rs index 306d2f7b0e..a35734573f 100644 --- a/src/shims/foreign_items/windows.rs +++ b/src/shims/foreign_items/windows.rs @@ -154,14 +154,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // This just creates a key; Windows does not natively support TLS destructors. // Create key and return it. - let key = this.machine.tls.create_tls_key(None) as u128; - - // Figure out how large a TLS key actually is. This is `c::DWORD`. - if dest.layout.size.bits() < 128 - && key >= (1u128 << dest.layout.size.bits() as u128) - { - throw_unsup!(OutOfTls); - } + let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; } "TlsGetValue" => { diff --git a/src/shims/fs.rs b/src/shims/fs.rs index 7c755143f2..cb429109a4 100644 --- a/src/shims/fs.rs +++ b/src/shims/fs.rs @@ -198,7 +198,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, ' } Err(e) => return match e.raw_os_error() { Some(error) => Ok(error), - None => throw_unsup_format!("The error {} couldn't be converted to a return value", e), + None => throw_unsup_format!("the error {} couldn't be converted to a return value", e), } } } @@ -261,7 +261,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // windows. We need to check that in fact the access mode flags for the current platform // only use these two bits, otherwise we are in an unsupported platform and should error. if (o_rdonly | o_wronly | o_rdwr) & !0b11 != 0 { - throw_unsup_format!("Access mode flags on this platform are unsupported"); + throw_unsup_format!("access mode flags on this platform are unsupported"); } let mut writable = true; @@ -276,7 +276,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } else if access_mode == o_rdwr { options.read(true).write(true); } else { - throw_unsup_format!("Unsupported access mode {:#x}", access_mode); + throw_unsup_format!("unsupported access mode {:#x}", access_mode); } // We need to check that there aren't unsupported options in `flag`. For this we try to // reproduce the content of `flag` in the `mirror` variable using only the supported @@ -351,7 +351,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor, // thus they can share the same implementation here. if fd < MIN_NORMAL_FILE_FD { - throw_unsup_format!("Duplicating file descriptors for stdin, stdout, or stderr is not supported") + throw_unsup_format!("duplicating file descriptors for stdin, stdout, or stderr is not supported") } let start_op = start_op.ok_or_else(|| { err_unsup_format!( @@ -369,7 +369,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }); this.try_unwrap_io_result(fd_result) } else { - throw_unsup_format!("The {:#x} command is not supported for `fcntl`)", cmd); + throw_unsup_format!("the {:#x} command is not supported for `fcntl`)", cmd); } } @@ -643,7 +643,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // FIXME: This long path is required because `libc::statx` is an struct and also a // function and `resolve_path` is returning the latter. let statx_ty = this - .resolve_path(&["libc", "unix", "linux_like", "linux", "gnu", "statx"])? + .resolve_path(&["libc", "unix", "linux_like", "linux", "gnu", "statx"]) .monomorphic_ty(*this.tcx); let statxbuf_ty = this.tcx.mk_mut_ptr(statx_ty); let statxbuf_layout = this.layout_of(statxbuf_ty)?; @@ -655,13 +655,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // `flags` should be a `c_int` but the `syscall` function provides an `isize`. let flags: i32 = this.read_scalar(flags_op)?.to_machine_isize(&*this.tcx)?.try_into().map_err(|e| { - err_unsup_format!("Failed to convert pointer sized operand to integer: {}", e) + err_unsup_format!("failed to convert pointer sized operand to integer: {}", e) })?; let empty_path_flag = flags & this.eval_libc("AT_EMPTY_PATH")?.to_i32()? != 0; // `dirfd` should be a `c_int` but the `syscall` function provides an `isize`. let dirfd: i32 = this.read_scalar(dirfd_op)?.to_machine_isize(&*this.tcx)?.try_into().map_err(|e| { - err_unsup_format!("Failed to convert pointer sized operand to integer: {}", e) + err_unsup_format!("failed to convert pointer sized operand to integer: {}", e) })?; // We only support: // * interpreting `path` as an absolute directory, @@ -676,7 +676,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx (path.as_os_str().is_empty() && empty_path_flag) ) { throw_unsup_format!( - "Using statx is only supported with absolute paths, relative paths with the file \ + "using statx is only supported with absolute paths, relative paths with the file \ descriptor `AT_FDCWD`, and empty paths with the `AT_EMPTY_PATH` flag set and any \ file descriptor" ) @@ -886,7 +886,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?; let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| { - err_unsup_format!("The DIR pointer passed to readdir64_r did not come from opendir") + err_unsup_format!("the DIR pointer passed to readdir64_r did not come from opendir") })?; match dir_iter.next() { Some(Ok(dir_entry)) => { @@ -913,7 +913,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx name_place.layout.size.bytes(), )?; if !name_fits { - throw_unsup_format!("A directory entry had a name too large to fit in libc::dirent64"); + throw_unsup_format!("a directory entry had a name too large to fit in libc::dirent64"); } let entry_place = this.deref_operand(entry_op)?; @@ -953,7 +953,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // return positive error number on error Some(error) => Ok(error), None => { - throw_unsup_format!("The error {} couldn't be converted to a return value", e) + throw_unsup_format!("the error {} couldn't be converted to a return value", e) } }, } @@ -973,7 +973,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?; let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| { - err_unsup_format!("The DIR pointer passed to readdir_r did not come from opendir") + err_unsup_format!("the DIR pointer passed to readdir_r did not come from opendir") })?; match dir_iter.next() { Some(Ok(dir_entry)) => { @@ -1001,7 +1001,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx name_place.layout.size.bytes(), )?; if !name_fits { - throw_unsup_format!("A directory entry had a name too large to fit in libc::dirent"); + throw_unsup_format!("a directory entry had a name too large to fit in libc::dirent"); } let entry_place = this.deref_operand(entry_op)?; @@ -1042,7 +1042,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // return positive error number on error Some(error) => Ok(error), None => { - throw_unsup_format!("The error {} couldn't be converted to a return value", e) + throw_unsup_format!("the error {} couldn't be converted to a return value", e) } }, } diff --git a/src/shims/time.rs b/src/shims/time.rs index d761698e0d..627478eaaa 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -12,7 +12,7 @@ fn get_time<'tcx>() -> InterpResult<'tcx, Duration> { /// Returns the time elapsed between the provided time and the unix epoch as a `Duration`. pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> { time.duration_since(SystemTime::UNIX_EPOCH) - .map_err(|_| err_unsup_format!("Times before the Unix epoch are not supported").into()) + .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into()) } impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} diff --git a/src/shims/tls.rs b/src/shims/tls.rs index cdfc0bcda8..094b58d99a 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; -use rustc::{ty, ty::layout::HasDataLayout}; +use rustc::{ty, ty::layout::{Size, HasDataLayout}}; use rustc_target::abi::LayoutOf; use crate::{HelpersEvalContextExt, InterpResult, MPlaceTy, Scalar, StackPopCleanup, Tag}; @@ -37,12 +37,18 @@ impl<'tcx> Default for TlsData<'tcx> { } impl<'tcx> TlsData<'tcx> { - pub fn create_tls_key(&mut self, dtor: Option>) -> TlsKey { + /// Generate a new TLS key with the given destructor. + /// `max_size` determines the integer size the key has to fit in. + pub fn create_tls_key(&mut self, dtor: Option>, max_size: Size) -> InterpResult<'tcx, TlsKey> { let new_key = self.next_key; self.next_key += 1; self.keys.insert(new_key, TlsEntry { data: None, dtor }).unwrap_none(); trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor); - new_key + + if max_size.bits() < 128 && new_key >= (1u128 << max_size.bits() as u128) { + throw_unsup_format!("we ran out of TLS key space"); + } + Ok(new_key) } pub fn delete_tls_key(&mut self, key: TlsKey) -> InterpResult<'tcx> { @@ -51,7 +57,7 @@ impl<'tcx> TlsData<'tcx> { trace!("TLS key {} removed", key); Ok(()) } - None => throw_unsup!(TlsOutOfBounds), + None => throw_ub_format!("removing a non-existig TLS key: {}", key), } } @@ -65,7 +71,7 @@ impl<'tcx> TlsData<'tcx> { trace!("TLS key {} loaded: {:?}", key, data); Ok(data.unwrap_or_else(|| Scalar::ptr_null(cx).into())) } - None => throw_unsup!(TlsOutOfBounds), + None => throw_ub_format!("loading from a non-existing TLS key: {}", key), } } @@ -76,7 +82,7 @@ impl<'tcx> TlsData<'tcx> { *data = new_data; Ok(()) } - None => throw_unsup!(TlsOutOfBounds), + None => throw_ub_format!("storing to a non-existing TLS key: {}", key), } } diff --git a/tests/compile-fail/alignment.rs b/tests/compile-fail/alignment.rs index 4faaa359df..bac1b92075 100644 --- a/tests/compile-fail/alignment.rs +++ b/tests/compile-fail/alignment.rs @@ -5,7 +5,7 @@ fn main() { let x_ptr: *mut u8 = &mut x[0]; let y_ptr = x_ptr as *mut u64; unsafe { - *y_ptr = 42; //~ ERROR tried to access memory with alignment 1, but alignment + *y_ptr = 42; //~ ERROR accessing memory with alignment 1, but alignment } panic!("unreachable in miri"); } diff --git a/tests/compile-fail/atomic_unaligned.rs b/tests/compile-fail/atomic_unaligned.rs index 5d2347c03f..bdec0ff504 100644 --- a/tests/compile-fail/atomic_unaligned.rs +++ b/tests/compile-fail/atomic_unaligned.rs @@ -7,6 +7,6 @@ fn main() { let zptr = &z as *const _ as *const u64; unsafe { ::std::intrinsics::atomic_load(zptr); - //~^ ERROR tried to access memory with alignment 4, but alignment 8 is required + //~^ ERROR accessing memory with alignment 4, but alignment 8 is required } } diff --git a/tests/compile-fail/cast_box_int_to_fn_ptr.rs b/tests/compile-fail/cast_box_int_to_fn_ptr.rs index 6dad2a4727..9eea9d92dc 100644 --- a/tests/compile-fail/cast_box_int_to_fn_ptr.rs +++ b/tests/compile-fail/cast_box_int_to_fn_ptr.rs @@ -7,5 +7,5 @@ fn main() { std::mem::transmute::<&Box, &fn(i32)>(&b) }; - (*g)(42) //~ ERROR tried to treat a memory pointer as a function pointer + (*g)(42) //~ ERROR it does not point to a function } diff --git a/tests/compile-fail/cast_fn_ptr1.rs b/tests/compile-fail/cast_fn_ptr1.rs index 0add977bf9..057cc64e9e 100644 --- a/tests/compile-fail/cast_fn_ptr1.rs +++ b/tests/compile-fail/cast_fn_ptr1.rs @@ -1,9 +1,9 @@ fn main() { - fn f() {} + fn f() {} //~ ERROR calling a function with more arguments than it expected let g = unsafe { std::mem::transmute::(f) }; - g(42) //~ ERROR tried to call a function with incorrect number of arguments + g(42) } diff --git a/tests/compile-fail/cast_fn_ptr2.rs b/tests/compile-fail/cast_fn_ptr2.rs index 5af527016f..39f0867489 100644 --- a/tests/compile-fail/cast_fn_ptr2.rs +++ b/tests/compile-fail/cast_fn_ptr2.rs @@ -5,5 +5,5 @@ fn main() { std::mem::transmute::(f) }; - g(42) //~ ERROR tried to call a function with argument of type (i32, i32) passing data of type i32 + g(42) //~ ERROR calling a function with argument of type (i32, i32) passing data of type i32 } diff --git a/tests/compile-fail/cast_fn_ptr3.rs b/tests/compile-fail/cast_fn_ptr3.rs index 29507e7c7c..3523db24fa 100644 --- a/tests/compile-fail/cast_fn_ptr3.rs +++ b/tests/compile-fail/cast_fn_ptr3.rs @@ -5,6 +5,6 @@ fn main() { std::mem::transmute::(f) }; - g() //~ ERROR tried to call a function with incorrect number of arguments + g() //~ ERROR calling a function with fewer arguments than it requires } diff --git a/tests/compile-fail/cast_fn_ptr4.rs b/tests/compile-fail/cast_fn_ptr4.rs index f9a2cf9f69..22a36a71ce 100644 --- a/tests/compile-fail/cast_fn_ptr4.rs +++ b/tests/compile-fail/cast_fn_ptr4.rs @@ -5,5 +5,5 @@ fn main() { std::mem::transmute::(f) }; - g(&42 as *const i32) //~ ERROR tried to call a function with argument of type *const [i32] passing data of type *const i32 + g(&42 as *const i32) //~ ERROR calling a function with argument of type *const [i32] passing data of type *const i32 } diff --git a/tests/compile-fail/cast_fn_ptr5.rs b/tests/compile-fail/cast_fn_ptr5.rs index e4ac95e676..ff2a73d5a4 100644 --- a/tests/compile-fail/cast_fn_ptr5.rs +++ b/tests/compile-fail/cast_fn_ptr5.rs @@ -1,9 +1,9 @@ fn main() { - fn f() -> u32 { 42 } + fn f() -> u32 { 42 } //~ ERROR calling a function with return type u32 passing return place of type () let g = unsafe { std::mem::transmute:: u32, fn()>(f) }; - g() //~ ERROR tried to call a function with return type u32 passing return place of type () + g() } diff --git a/tests/compile-fail/cast_int_to_fn_ptr.rs b/tests/compile-fail/cast_int_to_fn_ptr.rs index 4fd14751a2..3000779a93 100644 --- a/tests/compile-fail/cast_int_to_fn_ptr.rs +++ b/tests/compile-fail/cast_int_to_fn_ptr.rs @@ -6,5 +6,5 @@ fn main() { std::mem::transmute::(42) }; - g(42) //~ ERROR dangling pointer was dereferenced + g(42) //~ ERROR invalid use of 42 as a pointer } diff --git a/tests/compile-fail/copy_unaligned.rs b/tests/compile-fail/copy_unaligned.rs index 1a2692978f..a2a4762239 100644 --- a/tests/compile-fail/copy_unaligned.rs +++ b/tests/compile-fail/copy_unaligned.rs @@ -1,4 +1,4 @@ -//error-pattern: tried to access memory with alignment 1, but alignment 2 is required +//error-pattern: accessing memory with alignment 1, but alignment 2 is required #![feature(intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd diff --git a/tests/compile-fail/dangling_pointer_deref.rs b/tests/compile-fail/dangling_pointer_deref.rs index e807207730..f2c7ec584f 100644 --- a/tests/compile-fail/dangling_pointer_deref.rs +++ b/tests/compile-fail/dangling_pointer_deref.rs @@ -3,6 +3,6 @@ fn main() { let b = Box::new(42); &*b as *const i32 }; - let x = unsafe { *p }; //~ ERROR dangling pointer was dereferenced + let x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/dangling_zst_deref.rs b/tests/compile-fail/dangling_zst_deref.rs index 0a8480675f..13e5f9d321 100644 --- a/tests/compile-fail/dangling_zst_deref.rs +++ b/tests/compile-fail/dangling_zst_deref.rs @@ -3,5 +3,5 @@ fn main() { let b = Box::new(42); &*b as *const i32 as *const () }; - let _x = unsafe { *p }; //~ ERROR dangling pointer was dereferenced + let _x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed } diff --git a/tests/compile-fail/deallocate-bad-alignment.rs b/tests/compile-fail/deallocate-bad-alignment.rs index 8763399197..f2cd87bac6 100644 --- a/tests/compile-fail/deallocate-bad-alignment.rs +++ b/tests/compile-fail/deallocate-bad-alignment.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::alloc::Global; use std::alloc::{AllocRef, Layout}; -// error-pattern: incorrect alloc info: expected size 1 and align 2, got size 1 and align 1 +// error-pattern: allocation has size 1 and alignment 1, but gave size 1 and alignment 2 fn main() { unsafe { diff --git a/tests/compile-fail/deallocate-bad-size.rs b/tests/compile-fail/deallocate-bad-size.rs index 3b7b3cc6a7..498a662518 100644 --- a/tests/compile-fail/deallocate-bad-size.rs +++ b/tests/compile-fail/deallocate-bad-size.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::alloc::Global; use std::alloc::{AllocRef, Layout}; -// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1 +// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1 fn main() { unsafe { diff --git a/tests/compile-fail/deallocate-twice.rs b/tests/compile-fail/deallocate-twice.rs index ee4c5dbedf..a851d75b9d 100644 --- a/tests/compile-fail/deallocate-twice.rs +++ b/tests/compile-fail/deallocate-twice.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::alloc::Global; use std::alloc::{AllocRef, Layout}; -// error-pattern: tried to deallocate dangling pointer +// error-pattern: dereferenced after this allocation got freed fn main() { unsafe { diff --git a/tests/compile-fail/deref-invalid-ptr.rs b/tests/compile-fail/deref-invalid-ptr.rs index 2a8be87e12..561017293a 100644 --- a/tests/compile-fail/deref-invalid-ptr.rs +++ b/tests/compile-fail/deref-invalid-ptr.rs @@ -3,5 +3,5 @@ fn main() { let x = 2usize as *const u32; - let _y = unsafe { &*x as *const u32 }; //~ ERROR dangling pointer was dereferenced + let _y = unsafe { &*x as *const u32 }; //~ ERROR invalid use of 2 as a pointer } diff --git a/tests/compile-fail/deref-partially-dangling.rs b/tests/compile-fail/deref-partially-dangling.rs index 221e585c5f..a6d3aae414 100644 --- a/tests/compile-fail/deref-partially-dangling.rs +++ b/tests/compile-fail/deref-partially-dangling.rs @@ -3,6 +3,6 @@ fn main() { let x = (1, 13); let xptr = &x as *const _ as *const (i32, i32, i32); - let val = unsafe { (*xptr).1 }; //~ ERROR pointer must be in-bounds at offset 12, but is outside bounds of allocation + let val = unsafe { (*xptr).1 }; //~ ERROR pointer must be in-bounds at offset 12, but is outside bounds of alloc assert_eq!(val, 13); } diff --git a/tests/compile-fail/deref_fn_ptr.rs b/tests/compile-fail/deref_fn_ptr.rs index ed2ac60f43..e604f96ea1 100644 --- a/tests/compile-fail/deref_fn_ptr.rs +++ b/tests/compile-fail/deref_fn_ptr.rs @@ -2,7 +2,7 @@ fn f() {} fn main() { let x: u8 = unsafe { - *std::mem::transmute::(f) //~ ERROR tried to dereference a function pointer + *std::mem::transmute::(f) //~ ERROR contains a function }; panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/environ-gets-deallocated.rs b/tests/compile-fail/environ-gets-deallocated.rs index 6131613fc0..dd00aef450 100644 --- a/tests/compile-fail/environ-gets-deallocated.rs +++ b/tests/compile-fail/environ-gets-deallocated.rs @@ -20,5 +20,5 @@ fn main() { let pointer = get_environ(); let _x = unsafe { *pointer }; std::env::set_var("FOO", "BAR"); - let _y = unsafe { *pointer }; //~ ERROR dangling pointer was dereferenced + let _y = unsafe { *pointer }; //~ ERROR dereferenced after this allocation got freed } diff --git a/tests/compile-fail/execute_memory.rs b/tests/compile-fail/execute_memory.rs index 295756ef0f..2e6b58a753 100644 --- a/tests/compile-fail/execute_memory.rs +++ b/tests/compile-fail/execute_memory.rs @@ -7,6 +7,6 @@ fn main() { let x = box 42; unsafe { let f = std::mem::transmute::, fn()>(x); - f() //~ ERROR tried to treat a memory pointer as a function pointer + f() //~ ERROR function pointer but it does not point to a function } } diff --git a/tests/compile-fail/fn_ptr_offset.rs b/tests/compile-fail/fn_ptr_offset.rs index 9d29316fe2..7e509d53c2 100644 --- a/tests/compile-fail/fn_ptr_offset.rs +++ b/tests/compile-fail/fn_ptr_offset.rs @@ -10,5 +10,5 @@ fn main() { let y : *mut u8 = unsafe { mem::transmute(x) }; let y = y.wrapping_offset(1); let x : fn() = unsafe { mem::transmute(y) }; - x(); //~ ERROR tried to use a function pointer after offsetting it + x(); //~ ERROR function pointer but it does not point to a function } diff --git a/tests/compile-fail/generator-pinned-moved.rs b/tests/compile-fail/generator-pinned-moved.rs index 70ceacd8ca..8f873f37a5 100644 --- a/tests/compile-fail/generator-pinned-moved.rs +++ b/tests/compile-fail/generator-pinned-moved.rs @@ -11,7 +11,7 @@ fn firstn() -> impl Generator { let num = &mut num; yield *num; - *num += 1; //~ ERROR dangling pointer was dereferenced + *num += 1; //~ ERROR dereferenced after this allocation got freed } } diff --git a/tests/compile-fail/intptrcast_alignment_check.rs b/tests/compile-fail/intptrcast_alignment_check.rs index fcf613ace4..1a8df5eace 100644 --- a/tests/compile-fail/intptrcast_alignment_check.rs +++ b/tests/compile-fail/intptrcast_alignment_check.rs @@ -7,6 +7,6 @@ fn main() { let base_addr = x as *mut _ as usize; let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr+1 }; let u16_ptr = base_addr_aligned as *mut u16; - unsafe { *u16_ptr = 2; } //~ ERROR tried to access memory with alignment 1, but alignment 2 is required + unsafe { *u16_ptr = 2; } //~ ERROR memory with alignment 1, but alignment 2 is required println!("{:?}", x); } diff --git a/tests/compile-fail/invalid_bool.rs b/tests/compile-fail/invalid_bool.rs index e80dc15efa..6ccea35316 100644 --- a/tests/compile-fail/invalid_bool.rs +++ b/tests/compile-fail/invalid_bool.rs @@ -3,5 +3,5 @@ fn main() { let b = unsafe { std::mem::transmute::(2) }; - let _x = b == true; //~ ERROR invalid boolean value read + let _x = b == true; //~ ERROR interpreting an invalid 8-bit value as a bool: 2 } diff --git a/tests/compile-fail/invalid_char.rs b/tests/compile-fail/invalid_char.rs index b67ed9ba52..ed61fcbe9d 100644 --- a/tests/compile-fail/invalid_char.rs +++ b/tests/compile-fail/invalid_char.rs @@ -4,5 +4,5 @@ fn main() { assert!(std::char::from_u32(-1_i32 as u32).is_none()); let c = unsafe { std::mem::transmute::(-1) }; - let _x = c == 'x'; //~ ERROR tried to interpret an invalid 32-bit value as a char + let _x = c == 'x'; //~ ERROR interpreting an invalid 32-bit value as a char } diff --git a/tests/compile-fail/modifying_constants.rs b/tests/compile-fail/modifying_constants.rs index 9770917b62..2d18dccd31 100644 --- a/tests/compile-fail/modifying_constants.rs +++ b/tests/compile-fail/modifying_constants.rs @@ -4,6 +4,6 @@ fn main() { let x = &1; // the `&1` is promoted to a constant, but it used to be that only the pointer is marked static, not the pointee let y = unsafe { &mut *(x as *const i32 as *mut i32) }; - *y = 42; //~ ERROR tried to modify constant memory + *y = 42; //~ ERROR read-only assert_eq!(*x, 42); } diff --git a/tests/compile-fail/out_of_bounds_ptr_1.rs b/tests/compile-fail/out_of_bounds_ptr_1.rs index b466093053..20bcc36f04 100644 --- a/tests/compile-fail/out_of_bounds_ptr_1.rs +++ b/tests/compile-fail/out_of_bounds_ptr_1.rs @@ -1,4 +1,4 @@ -// error-pattern: must be in-bounds at offset 5, but is outside bounds of allocation +// error-pattern: must be in-bounds at offset 5, but is outside bounds of alloc fn main() { let v = [0i8; 4]; let x = &v as *const i8; diff --git a/tests/compile-fail/out_of_bounds_read1.rs b/tests/compile-fail/out_of_bounds_read1.rs index 1ab2d97147..0c175af526 100644 --- a/tests/compile-fail/out_of_bounds_read1.rs +++ b/tests/compile-fail/out_of_bounds_read1.rs @@ -1,5 +1,5 @@ fn main() { let v: Vec = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of allocation + let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/out_of_bounds_read2.rs b/tests/compile-fail/out_of_bounds_read2.rs index 1ab2d97147..0c175af526 100644 --- a/tests/compile-fail/out_of_bounds_read2.rs +++ b/tests/compile-fail/out_of_bounds_read2.rs @@ -1,5 +1,5 @@ fn main() { let v: Vec = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of allocation + let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/overflowing-unchecked-rsh.rs b/tests/compile-fail/overflowing-unchecked-rsh.rs index f59773f7e3..730d01597f 100644 --- a/tests/compile-fail/overflowing-unchecked-rsh.rs +++ b/tests/compile-fail/overflowing-unchecked-rsh.rs @@ -2,7 +2,7 @@ use std::intrinsics::*; -//error-pattern: Overflowing shift by 64 in `unchecked_shr` +//error-pattern: overflowing shift by 64 in `unchecked_shr` fn main() { unsafe { diff --git a/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs b/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs index 5c0d5b463d..d8182aaae6 100644 --- a/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs +++ b/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs @@ -6,6 +6,6 @@ fn main() { // "attempted to interpret some raw bytes as a pointer address" instead of // "attempted to read undefined bytes" } - let x = *p; //~ ERROR attempted to read undefined bytes + let x = *p; //~ ERROR this operation requires initialized memory panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/pointer_byte_read.rs b/tests/compile-fail/pointer_byte_read.rs index ddb9bc1f99..dcb0fd3fb9 100644 --- a/tests/compile-fail/pointer_byte_read.rs +++ b/tests/compile-fail/pointer_byte_read.rs @@ -3,5 +3,5 @@ fn main() { let y = &x; let z = &y as *const &i32 as *const u8; // the deref fails, because we are reading only a part of the pointer - let _val = unsafe { *z }; //~ ERROR tried to access part of a pointer value as raw bytes + let _val = unsafe { *z }; //~ ERROR unable to turn pointer into raw bytes } diff --git a/tests/compile-fail/ptr_offset_int_plus_int.rs b/tests/compile-fail/ptr_offset_int_plus_int.rs index 051874696b..f0cf00884e 100644 --- a/tests/compile-fail/ptr_offset_int_plus_int.rs +++ b/tests/compile-fail/ptr_offset_int_plus_int.rs @@ -1,4 +1,4 @@ -// error-pattern: dangling pointer was dereferenced +// error-pattern: invalid use of 1 as a pointer fn main() { // Can't offset an integer pointer by non-zero offset. diff --git a/tests/compile-fail/ptr_offset_int_plus_ptr.rs b/tests/compile-fail/ptr_offset_int_plus_ptr.rs index bd90d06909..705ca68970 100644 --- a/tests/compile-fail/ptr_offset_int_plus_ptr.rs +++ b/tests/compile-fail/ptr_offset_int_plus_ptr.rs @@ -1,4 +1,4 @@ -// error-pattern: dangling pointer was dereferenced +// error-pattern: invalid use of 1 as a pointer fn main() { let ptr = Box::into_raw(Box::new(0u32)); diff --git a/tests/compile-fail/ptr_offset_ptr_plus_0.rs b/tests/compile-fail/ptr_offset_ptr_plus_0.rs index a089a8b821..d07ecc4dc7 100644 --- a/tests/compile-fail/ptr_offset_ptr_plus_0.rs +++ b/tests/compile-fail/ptr_offset_ptr_plus_0.rs @@ -1,4 +1,4 @@ -// error-pattern: outside bounds of allocation +// error-pattern: outside bounds of alloc fn main() { let x = Box::into_raw(Box::new(0u32)); diff --git a/tests/compile-fail/rc_as_raw.rs b/tests/compile-fail/rc_as_raw.rs index 086467eea3..cb50ca5fce 100644 --- a/tests/compile-fail/rc_as_raw.rs +++ b/tests/compile-fail/rc_as_raw.rs @@ -17,5 +17,5 @@ fn main() { drop(strong); // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to // undefined behaviour. - assert_eq!(42, **unsafe { &*Weak::as_raw(&weak) }); //~ ERROR dangling pointer + assert_eq!(42, **unsafe { &*Weak::as_raw(&weak) }); //~ ERROR dereferenced after this allocation got freed } diff --git a/tests/compile-fail/reading_half_a_pointer.rs b/tests/compile-fail/reading_half_a_pointer.rs index f8e9e5781e..6e765a1b0b 100644 --- a/tests/compile-fail/reading_half_a_pointer.rs +++ b/tests/compile-fail/reading_half_a_pointer.rs @@ -24,6 +24,6 @@ fn main() { // starts 1 byte to the right, so using it would actually be wrong! let d_alias = &mut w.data as *mut _ as *mut *const u8; unsafe { - let _x = *d_alias; //~ ERROR tried to access part of a pointer value as raw bytes + let _x = *d_alias; //~ ERROR unable to turn pointer into raw bytes } } diff --git a/tests/compile-fail/reallocate-bad-size.rs b/tests/compile-fail/reallocate-bad-size.rs index f7117dbb64..a62c1adae7 100644 --- a/tests/compile-fail/reallocate-bad-size.rs +++ b/tests/compile-fail/reallocate-bad-size.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::alloc::Global; use std::alloc::{AllocRef, Layout}; -// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1 +// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1 fn main() { unsafe { diff --git a/tests/compile-fail/reallocate-change-alloc.rs b/tests/compile-fail/reallocate-change-alloc.rs index df517f9c81..0d4b60e0a3 100644 --- a/tests/compile-fail/reallocate-change-alloc.rs +++ b/tests/compile-fail/reallocate-change-alloc.rs @@ -9,6 +9,6 @@ fn main() { unsafe { let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0; Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap(); - let _z = *(x.as_ptr() as *mut u8); //~ ERROR dangling pointer was dereferenced + let _z = *(x.as_ptr() as *mut u8); //~ ERROR dereferenced after this allocation got freed } } diff --git a/tests/compile-fail/reallocate-dangling.rs b/tests/compile-fail/reallocate-dangling.rs index 19a9017e71..9661d7e966 100644 --- a/tests/compile-fail/reallocate-dangling.rs +++ b/tests/compile-fail/reallocate-dangling.rs @@ -5,7 +5,7 @@ extern crate alloc; use alloc::alloc::Global; use std::alloc::{AllocRef, Layout}; -// error-pattern: dangling pointer was dereferenced +// error-pattern: dereferenced after this allocation got freed fn main() { unsafe { diff --git a/tests/compile-fail/reference_to_packed.rs b/tests/compile-fail/reference_to_packed.rs index 030353c2ce..08104e917d 100644 --- a/tests/compile-fail/reference_to_packed.rs +++ b/tests/compile-fail/reference_to_packed.rs @@ -15,5 +15,5 @@ fn main() { y: 99, }; let p = unsafe { &foo.x }; - let i = *p; //~ ERROR tried to access memory with alignment 1, but alignment 4 is required + let i = *p; //~ ERROR memory with alignment 1, but alignment 4 is required } diff --git a/tests/compile-fail/stack_free.rs b/tests/compile-fail/stack_free.rs index b8ed2e3f1f..ea09d3e2b4 100644 --- a/tests/compile-fail/stack_free.rs +++ b/tests/compile-fail/stack_free.rs @@ -1,7 +1,7 @@ // Validation/SB changes why we fail // compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -// error-pattern: tried to deallocate `Stack` memory but gave `Machine(Rust)` as the kind +// error-pattern: deallocating `Stack` memory using `Machine(Rust)` deallocation operation fn main() { let x = 42; diff --git a/tests/compile-fail/stacked_borrows/issue-miri-1050-2.rs b/tests/compile-fail/stacked_borrows/issue-miri-1050-2.rs index 74aab153ea..69f19651e5 100644 --- a/tests/compile-fail/stacked_borrows/issue-miri-1050-2.rs +++ b/tests/compile-fail/stacked_borrows/issue-miri-1050-2.rs @@ -1,4 +1,4 @@ -// error-pattern: dangling pointer was dereferenced +// error-pattern: invalid use of 4 as a pointer use std::ptr::NonNull; fn main() { unsafe { diff --git a/tests/compile-fail/static_memory_modification1.rs b/tests/compile-fail/static_memory_modification1.rs index a7bb33431e..6284fec160 100644 --- a/tests/compile-fail/static_memory_modification1.rs +++ b/tests/compile-fail/static_memory_modification1.rs @@ -6,7 +6,7 @@ static X: usize = 5; #[allow(mutable_transmutes)] fn main() { unsafe { - *std::mem::transmute::<&usize, &mut usize>(&X) = 6; //~ ERROR tried to modify constant memory + *std::mem::transmute::<&usize, &mut usize>(&X) = 6; //~ ERROR read-only assert_eq!(X, 6); } } diff --git a/tests/compile-fail/static_memory_modification2.rs b/tests/compile-fail/static_memory_modification2.rs index 065206a60d..558070d8a7 100644 --- a/tests/compile-fail/static_memory_modification2.rs +++ b/tests/compile-fail/static_memory_modification2.rs @@ -7,6 +7,6 @@ use std::mem::transmute; fn main() { unsafe { let s = "this is a test"; - transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; //~ ERROR tried to modify constant memory + transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; //~ ERROR read-only } } diff --git a/tests/compile-fail/static_memory_modification3.rs b/tests/compile-fail/static_memory_modification3.rs index 94f8820507..93df1c5945 100644 --- a/tests/compile-fail/static_memory_modification3.rs +++ b/tests/compile-fail/static_memory_modification3.rs @@ -7,6 +7,6 @@ use std::mem::transmute; fn main() { unsafe { let bs = b"this is a test"; - transmute::<&[u8], &mut [u8]>(bs)[4] = 42; //~ ERROR tried to modify constant memory + transmute::<&[u8], &mut [u8]>(bs)[4] = 42; //~ ERROR read-only } } diff --git a/tests/compile-fail/storage_dead_dangling.rs b/tests/compile-fail/storage_dead_dangling.rs index 3047f086bd..bf2503917c 100644 --- a/tests/compile-fail/storage_dead_dangling.rs +++ b/tests/compile-fail/storage_dead_dangling.rs @@ -8,7 +8,7 @@ fn fill(v: &mut i32) { } fn evil() { - unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dangling pointer was dereferenced + unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dereferenced after this allocation got freed } fn main() { diff --git a/tests/compile-fail/transmute-pair-undef.rs b/tests/compile-fail/transmute-pair-undef.rs index 43f1eed42d..0f02697f26 100644 --- a/tests/compile-fail/transmute-pair-undef.rs +++ b/tests/compile-fail/transmute-pair-undef.rs @@ -18,5 +18,5 @@ fn main() { } let v = unsafe { *z.offset(first_undef) }; if v == 0 {} - //~^ ERROR attempted to read undefined bytes + //~^ ERROR this operation requires initialized memory } diff --git a/tests/compile-fail/transmute_fat1.rs b/tests/compile-fail/transmute_fat1.rs index ddc78c8bf1..da45dad7b7 100644 --- a/tests/compile-fail/transmute_fat1.rs +++ b/tests/compile-fail/transmute_fat1.rs @@ -10,5 +10,5 @@ fn main() { let bad = unsafe { std::mem::transmute::<&[u8], [u8; 8]>(&[1u8]) }; - let _val = bad[0] + bad[bad.len()-1]; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes + let _val = bad[0] + bad[bad.len()-1]; //~ ERROR unable to turn pointer into raw bytes } diff --git a/tests/compile-fail/unaligned_ptr1.rs b/tests/compile-fail/unaligned_ptr1.rs index bcc4192d7d..ee1a130042 100644 --- a/tests/compile-fail/unaligned_ptr1.rs +++ b/tests/compile-fail/unaligned_ptr1.rs @@ -5,5 +5,5 @@ fn main() { let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. let x = &x[0] as *const _ as *const u32; // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. - let _x = unsafe { *x }; //~ ERROR tried to access memory with alignment 2, but alignment 4 is required + let _x = unsafe { *x }; //~ ERROR memory with alignment 2, but alignment 4 is required } diff --git a/tests/compile-fail/unaligned_ptr2.rs b/tests/compile-fail/unaligned_ptr2.rs index 225bd14ade..853d890ecf 100644 --- a/tests/compile-fail/unaligned_ptr2.rs +++ b/tests/compile-fail/unaligned_ptr2.rs @@ -6,5 +6,5 @@ fn main() { let x = (x.as_ptr() as *const u8).wrapping_offset(3) as *const u32; // This must fail because alignment is violated: the offset is not sufficiently aligned. // Also make the offset not a power of 2, that used to ICE. - let _x = unsafe { *x }; //~ ERROR tried to access memory with alignment 1, but alignment 4 is required + let _x = unsafe { *x }; //~ ERROR memory with alignment 1, but alignment 4 is required } diff --git a/tests/compile-fail/unaligned_ptr3.rs b/tests/compile-fail/unaligned_ptr3.rs index f33a80d458..43f6b472da 100644 --- a/tests/compile-fail/unaligned_ptr3.rs +++ b/tests/compile-fail/unaligned_ptr3.rs @@ -7,5 +7,5 @@ fn main() { // This must fail because alignment is violated. Test specifically for loading pointers, // which have special code in miri's memory. let _x = unsafe { *x }; - //~^ ERROR tried to access memory with alignment 2, but alignment + //~^ ERROR memory with alignment 2, but alignment } diff --git a/tests/compile-fail/unaligned_ptr_zst.rs b/tests/compile-fail/unaligned_ptr_zst.rs index 127ec04027..31f88c8381 100644 --- a/tests/compile-fail/unaligned_ptr_zst.rs +++ b/tests/compile-fail/unaligned_ptr_zst.rs @@ -6,5 +6,5 @@ fn main() { let x = x as *const _ as *const [u32; 0]; // This must fail because alignment is violated. Test specifically for loading ZST. let _x = unsafe { *x }; - //~^ ERROR tried to access memory with alignment 2, but alignment 4 is required + //~^ ERROR memory with alignment 2, but alignment 4 is required } diff --git a/tests/compile-fail/unchecked_add1.rs b/tests/compile-fail/unchecked_add1.rs index eb5a41fdfa..f48b91422c 100644 --- a/tests/compile-fail/unchecked_add1.rs +++ b/tests/compile-fail/unchecked_add1.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MAX overflow - unsafe { std::intrinsics::unchecked_add(40000u16, 30000); } //~ ERROR Overflow executing `unchecked_add` + unsafe { std::intrinsics::unchecked_add(40000u16, 30000); } //~ ERROR overflow executing `unchecked_add` } diff --git a/tests/compile-fail/unchecked_add2.rs b/tests/compile-fail/unchecked_add2.rs index fa6a232aed..150986541c 100644 --- a/tests/compile-fail/unchecked_add2.rs +++ b/tests/compile-fail/unchecked_add2.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MIN overflow - unsafe { std::intrinsics::unchecked_add(-30000i16, -8000); } //~ ERROR Overflow executing `unchecked_add` + unsafe { std::intrinsics::unchecked_add(-30000i16, -8000); } //~ ERROR overflow executing `unchecked_add` } diff --git a/tests/compile-fail/unchecked_div1.rs b/tests/compile-fail/unchecked_div1.rs index b42b34ff46..53d8000764 100644 --- a/tests/compile-fail/unchecked_div1.rs +++ b/tests/compile-fail/unchecked_div1.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MIN/-1 cannot be represented - unsafe { std::intrinsics::unchecked_div(i16::MIN, -1); } //~ ERROR Overflow executing `unchecked_div` + unsafe { std::intrinsics::unchecked_div(i16::MIN, -1); } //~ ERROR overflow executing `unchecked_div` } diff --git a/tests/compile-fail/unchecked_mul1.rs b/tests/compile-fail/unchecked_mul1.rs index a3681a57df..050e3ff243 100644 --- a/tests/compile-fail/unchecked_mul1.rs +++ b/tests/compile-fail/unchecked_mul1.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MAX overflow - unsafe { std::intrinsics::unchecked_mul(300u16, 250u16); } //~ ERROR Overflow executing `unchecked_mul` + unsafe { std::intrinsics::unchecked_mul(300u16, 250u16); } //~ ERROR overflow executing `unchecked_mul` } diff --git a/tests/compile-fail/unchecked_mul2.rs b/tests/compile-fail/unchecked_mul2.rs index 8fe677f8de..4fb77783b4 100644 --- a/tests/compile-fail/unchecked_mul2.rs +++ b/tests/compile-fail/unchecked_mul2.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MIN overflow - unsafe { std::intrinsics::unchecked_mul(1_000_000_000i32, -4); } //~ ERROR Overflow executing `unchecked_mul` + unsafe { std::intrinsics::unchecked_mul(1_000_000_000i32, -4); } //~ ERROR overflow executing `unchecked_mul` } diff --git a/tests/compile-fail/unchecked_sub1.rs b/tests/compile-fail/unchecked_sub1.rs index 230607f033..69b32dd319 100644 --- a/tests/compile-fail/unchecked_sub1.rs +++ b/tests/compile-fail/unchecked_sub1.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MIN overflow - unsafe { std::intrinsics::unchecked_sub(14u32, 22); } //~ ERROR Overflow executing `unchecked_sub` + unsafe { std::intrinsics::unchecked_sub(14u32, 22); } //~ ERROR overflow executing `unchecked_sub` } diff --git a/tests/compile-fail/unchecked_sub2.rs b/tests/compile-fail/unchecked_sub2.rs index 1ea41a3c0f..5609ea7a3e 100644 --- a/tests/compile-fail/unchecked_sub2.rs +++ b/tests/compile-fail/unchecked_sub2.rs @@ -1,5 +1,5 @@ #![feature(core_intrinsics)] fn main() { // MAX overflow - unsafe { std::intrinsics::unchecked_sub(30000i16, -7000); } //~ ERROR Overflow executing `unchecked_sub` + unsafe { std::intrinsics::unchecked_sub(30000i16, -7000); } //~ ERROR overflow executing `unchecked_sub` } diff --git a/tests/compile-fail/undefined_byte_read.rs b/tests/compile-fail/undefined_byte_read.rs index fca749ef9c..36c14137bd 100644 --- a/tests/compile-fail/undefined_byte_read.rs +++ b/tests/compile-fail/undefined_byte_read.rs @@ -1,6 +1,6 @@ fn main() { let v: Vec = Vec::with_capacity(10); let undef = unsafe { *v.get_unchecked(5) }; - let x = undef + 1; //~ ERROR attempted to read undefined bytes + let x = undef + 1; //~ ERROR this operation requires initialized memory panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/validity/dangling_ref1.rs b/tests/compile-fail/validity/dangling_ref1.rs index 194445b1ad..034510f3b2 100644 --- a/tests/compile-fail/validity/dangling_ref1.rs +++ b/tests/compile-fail/validity/dangling_ref1.rs @@ -1,5 +1,5 @@ use std::mem; fn main() { - let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR dangling reference (not entirely in bounds) + let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR reference to unallocated address 16 } diff --git a/tests/compile-fail/validity/dangling_ref2.rs b/tests/compile-fail/validity/dangling_ref2.rs index 0dc9c3a182..4ad9b8135d 100644 --- a/tests/compile-fail/validity/dangling_ref2.rs +++ b/tests/compile-fail/validity/dangling_ref2.rs @@ -3,5 +3,5 @@ use std::mem; fn main() { let val = 14; let ptr = (&val as *const i32).wrapping_offset(1); - let _x: &i32 = unsafe { mem::transmute(ptr) }; //~ ERROR dangling reference (not entirely in bounds) + let _x: &i32 = unsafe { mem::transmute(ptr) }; //~ ERROR dangling reference (going beyond the bounds of its allocation) } diff --git a/tests/compile-fail/validity/dangling_ref3.rs b/tests/compile-fail/validity/dangling_ref3.rs new file mode 100644 index 0000000000..46e17375a8 --- /dev/null +++ b/tests/compile-fail/validity/dangling_ref3.rs @@ -0,0 +1,10 @@ +use std::mem; + +fn dangling() -> *const u8 { + let x = 0u8; + &x as *const _ +} + +fn main() { + let _x: &i32 = unsafe { mem::transmute(dangling()) }; //~ ERROR dangling reference (use-after-free) +} diff --git a/tests/compile-fail/wild_pointer_deref.rs b/tests/compile-fail/wild_pointer_deref.rs index ae32f7d556..5780cccdb8 100644 --- a/tests/compile-fail/wild_pointer_deref.rs +++ b/tests/compile-fail/wild_pointer_deref.rs @@ -1,5 +1,5 @@ fn main() { let p = 44 as *const i32; - let x = unsafe { *p }; //~ ERROR dangling pointer was dereferenced + let x = unsafe { *p }; //~ ERROR invalid use of 44 as a pointer panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/zst2.rs b/tests/compile-fail/zst2.rs index 950f7b3d60..907337dcdb 100644 --- a/tests/compile-fail/zst2.rs +++ b/tests/compile-fail/zst2.rs @@ -8,5 +8,5 @@ fn main() { let mut x_box = Box::new(1u8); let x = &mut *x_box as *mut _ as *mut [u8; 0]; drop(x_box); - unsafe { *x = zst_val; } //~ ERROR dangling pointer was dereferenced + unsafe { *x = zst_val; } //~ ERROR dereferenced after this allocation got freed }