diff --git a/miri b/miri index f1eae220e0d..47ff5024fc6 100755 --- a/miri +++ b/miri @@ -11,6 +11,9 @@ working directory. ./miri build : Just build miri. are passed to `cargo build`. +./miri check : +Just check miri. are passed to `cargo check`. + ./miri test : Build miri, set up a sysroot and then run the test suite. are passed to the final `cargo test` invocation. @@ -99,6 +102,10 @@ install|install-debug) # "--offline" to avoid querying the registry (for yanked packages). exec cargo install $CARGO_INSTALL_FLAGS --path "$(dirname "$0")" --force --locked --offline "$@" ;; +check|check-debug) + # Check, and let caller control flags. + exec cargo check $CARGO_BUILD_FLAGS "$@" + ;; build|build-debug) # Build, and let caller control flags. exec cargo build $CARGO_BUILD_FLAGS "$@" diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index a08c8a56cf2..9a6bd58ba42 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -4,7 +4,7 @@ use std::convert::TryFrom; use rustc::mir; use rustc::mir::interpret::{InterpResult, PointerArithmetic}; use rustc::ty; -use rustc::ty::layout::{Align, LayoutOf, Size}; +use rustc::ty::layout::{Align, LayoutOf}; use rustc_apfloat::Float; use rustc_span::source_map::Span; @@ -226,11 +226,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx => { let elem_ty = substs.type_at(0); let elem_layout = this.layout_of(elem_ty)?; - let elem_size = elem_layout.size.bytes(); let count = this.read_scalar(args[2])?.to_machine_usize(this)?; let elem_align = elem_layout.align.abi; - let size = Size::from_bytes(count) * elem_size; + 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(args[0])?.not_undef()?; let src = this.memory.check_ptr_access(src, size, elem_align)?; let dest = this.read_scalar(args[1])?.not_undef()?; @@ -493,7 +493,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let val_byte = this.read_scalar(args[1])?.to_u8()?; let ptr = this.read_scalar(args[0])?.not_undef()?; let count = this.read_scalar(args[2])?.to_machine_usize(this)?; - let byte_count = ty_layout.size * count; + let byte_count = ty_layout.size.checked_mul(count, this) + .ok_or_else(|| err_ub_format!("overflow computing total size of `write_bytes`"))?; this.memory .write_bytes(ptr, iter::repeat(val_byte).take(byte_count.bytes() as usize))?; } diff --git a/tests/compile-fail/copy_null.rs b/tests/compile-fail/copy_null.rs index ce2fbe170e4..b14bdc4b386 100644 --- a/tests/compile-fail/copy_null.rs +++ b/tests/compile-fail/copy_null.rs @@ -1,4 +1,3 @@ -//error-pattern: invalid use of NULL pointer #![feature(intrinsics)] // Directly call intrinsic to avoid debug assertions in libstd @@ -10,5 +9,5 @@ fn main() { let mut data = [0u16; 4]; let ptr = &mut data[0] as *mut u16; // Even copying 0 elements from NULL should error. - unsafe { copy_nonoverlapping(std::ptr::null(), ptr, 0); } + unsafe { copy_nonoverlapping(std::ptr::null(), ptr, 0); } //~ ERROR: invalid use of NULL pointer } diff --git a/tests/compile-fail/copy_overflow.rs b/tests/compile-fail/copy_overflow.rs new file mode 100644 index 00000000000..c75cf6917b1 --- /dev/null +++ b/tests/compile-fail/copy_overflow.rs @@ -0,0 +1,10 @@ +// error-pattern: overflow computing total size of `copy` +use std::mem; + +fn main() { + let x = 0; + let mut y = 0; + unsafe { + (&mut y as *mut i32).copy_from(&x, 1usize << (mem::size_of::() * 8 - 1)); + } +} diff --git a/tests/compile-fail/write_bytes_null.rs b/tests/compile-fail/write_bytes_null.rs new file mode 100644 index 00000000000..e80222162ee --- /dev/null +++ b/tests/compile-fail/write_bytes_null.rs @@ -0,0 +1,10 @@ +#![feature(intrinsics)] + +// Directly call intrinsic to avoid debug assertions in libstd +extern "rust-intrinsic" { + fn write_bytes(dst: *mut T, val: u8, count: usize); +} + +fn main() { + unsafe { write_bytes::(std::ptr::null_mut(), 0, 0) }; //~ ERROR invalid use of NULL pointer +} diff --git a/tests/compile-fail/write_bytes_overflow.rs b/tests/compile-fail/write_bytes_overflow.rs new file mode 100644 index 00000000000..a6bf2acb16f --- /dev/null +++ b/tests/compile-fail/write_bytes_overflow.rs @@ -0,0 +1,9 @@ +// error-pattern: overflow computing total size of `write_bytes` +use std::mem; + +fn main() { + let mut y = 0; + unsafe { + (&mut y as *mut i32).write_bytes(0u8, 1usize << (mem::size_of::() * 8 - 1)); + } +}