+++ /dev/null
-fn main() {
- // miri always gives allocations the worst possible alignment, so a `u8` array is guaranteed
- // to be at the virtual location 1 (so one byte offset from the ultimate alignemnt location 0)
- let mut x = [0u8; 20];
- let x_ptr: *mut u8 = &mut x[0];
- let y_ptr = x_ptr as *mut u64;
- unsafe {
- *y_ptr = 42; //~ ERROR accessing memory with alignment 1, but alignment
- }
- panic!("unreachable in miri");
-}
--- /dev/null
+use std::alloc::{alloc, dealloc, Layout};
+
+// error-pattern: allocation has size 1 and alignment 1, but gave size 1 and alignment 2
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ dealloc(x, Layout::from_size_align_unchecked(1, 2));
+ }
+}
--- /dev/null
+use std::alloc::{alloc, dealloc, Layout};
+
+// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ dealloc(x, Layout::from_size_align_unchecked(2, 1));
+ }
+}
--- /dev/null
+use std::alloc::{alloc, dealloc, Layout};
+
+// error-pattern: dereferenced after this allocation got freed
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ dealloc(x, Layout::from_size_align_unchecked(1, 1));
+ dealloc(x, Layout::from_size_align_unchecked(1, 1));
+ }
+}
--- /dev/null
+use std::alloc::{alloc, realloc, Layout};
+
+// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
+ }
+}
--- /dev/null
+use std::alloc::{alloc, realloc, Layout};
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
+ let _z = *x; //~ ERROR dereferenced after this allocation got freed
+ }
+}
--- /dev/null
+use std::alloc::{alloc, dealloc, realloc, Layout};
+
+// error-pattern: dereferenced after this allocation got freed
+
+fn main() {
+ unsafe {
+ let x = alloc(Layout::from_size_align_unchecked(1, 1));
+ dealloc(x, Layout::from_size_align_unchecked(1, 1));
+ realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
+ }
+}
--- /dev/null
+// Validation/SB changes why we fail
+// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
+
+// error-pattern: deallocating stack variable memory using Rust heap deallocation operation
+
+fn main() {
+ let x = 42;
+ let bad_box = unsafe { std::mem::transmute::<&i32, Box<i32>>(&x) };
+ drop(bad_box);
+}
+++ /dev/null
-#![feature(core_intrinsics)]
-
-fn main() {
- let x = 5;
- unsafe {
- std::intrinsics::assume(x < 10);
- std::intrinsics::assume(x > 1);
- std::intrinsics::assume(x > 42); //~ `assume` intrinsic called with `false`
- }
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-
-fn main() {
- // Do a 4-aligned u64 atomic access. That should be UB on all platforms,
- // even if u64 only has alignment 4.
- let z = [0u32; 2];
- let zptr = &z as *const _ as *const u64;
- unsafe {
- ::std::intrinsics::atomic_load(zptr);
- //~^ ERROR accessing memory with alignment 4, but alignment 8 is required
- }
-}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let b = Box::new(42);
- let g = unsafe {
- std::mem::transmute::<&Box<usize>, &fn(i32)>(&b)
- };
-
- (*g)(42) //~ ERROR it does not point to a function
-}
+++ /dev/null
-fn main() {
- fn f() {}
-
- let g = unsafe {
- std::mem::transmute::<fn(), fn(i32)>(f)
- };
-
- g(42) //~ ERROR calling a function with more arguments than it expected
-}
+++ /dev/null
-fn main() {
- fn f(_ : (i32,i32)) {}
-
- let g = unsafe {
- std::mem::transmute::<fn((i32,i32)), fn(i32)>(f)
- };
-
- g(42) //~ ERROR calling a function with argument of type (i32, i32) passing data of type i32
-}
+++ /dev/null
-fn main() {
- fn f(_ : (i32,i32)) {}
-
- let g = unsafe {
- std::mem::transmute::<fn((i32,i32)), fn()>(f)
- };
-
- g() //~ ERROR calling a function with fewer arguments than it requires
-}
-
+++ /dev/null
-fn main() {
- fn f(_ : *const [i32]) {}
-
- let g = unsafe {
- std::mem::transmute::<fn(*const [i32]), fn(*const i32)>(f)
- };
-
- g(&42 as *const i32) //~ ERROR calling a function with argument of type *const [i32] passing data of type *const i32
-}
+++ /dev/null
-fn main() {
- fn f() -> u32 { 42 }
-
- let g = unsafe {
- std::mem::transmute::<fn() -> u32, fn()>(f)
- };
-
- g() //~ ERROR calling a function with return type u32 passing return place of type ()
-}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let g = unsafe {
- std::mem::transmute::<usize, fn(i32)>(42)
- };
-
- g(42) //~ ERROR invalid use of 42 as a pointer
-}
+++ /dev/null
-#![feature(intrinsics)]
-
-// Directly call intrinsic to avoid debug assertions in libstd
-extern "rust-intrinsic" {
- fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-}
-
-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); } //~ ERROR: invalid use of NULL pointer
-}
+++ /dev/null
-// 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::<usize>() * 8 - 1));
- }
-}
+++ /dev/null
-//error-pattern: copy_nonoverlapping called on overlapping ranges
-#![feature(intrinsics)]
-
-// Directly call intrinsic to avoid debug assertions in libstd
-extern "rust-intrinsic" {
- fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-}
-
-fn main() {
- let mut data = [0u8; 16];
- unsafe {
- let a = data.as_mut_ptr();
- let b = a.wrapping_offset(1) as *mut _;
- copy_nonoverlapping(a, b, 2);
- }
-}
+++ /dev/null
-//error-pattern: accessing memory with alignment 1, but alignment 2 is required
-#![feature(intrinsics)]
-
-// Directly call intrinsic to avoid debug assertions in libstd
-extern "rust-intrinsic" {
- fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-}
-
-fn main() {
- let mut data = [0u16; 8];
- let ptr = (&mut data[0] as *mut u16 as *mut u8).wrapping_add(1) as *mut u16;
- // Even copying 0 elements to something unaligned should error
- unsafe { copy_nonoverlapping(&data[5], ptr, 0); }
-}
+++ /dev/null
-#![feature(intrinsics)]
-
-mod rusti {
- extern "rust-intrinsic" {
- pub fn ctlz_nonzero<T>(x: T) -> T;
- }
-}
-
-pub fn main() {
- unsafe {
- use crate::rusti::*;
-
- ctlz_nonzero(0u8); //~ ERROR `ctlz_nonzero` called on 0
- }
-}
+++ /dev/null
-#![feature(intrinsics)]
-
-mod rusti {
- extern "rust-intrinsic" {
- pub fn cttz_nonzero<T>(x: T) -> T;
- }
-}
-
-pub fn main() {
- unsafe {
- use crate::rusti::*;
-
- cttz_nonzero(0u8); //~ ERROR `cttz_nonzero` called on 0
- }
-}
+++ /dev/null
-fn main() {
- let p = {
- let b = Box::new(42);
- &*b as *const i32
- };
- let x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed
- panic!("this should never print: {}", x);
-}
--- /dev/null
+fn main() {
+ let p = {
+ let b = Box::new(42);
+ &*b as *const i32
+ };
+ let x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed
+ panic!("this should never print: {}", x);
+}
--- /dev/null
+fn main() {
+ let p = {
+ let b = Box::new(42);
+ &*b as *const i32 as *const ()
+ };
+ let _x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed
+}
--- /dev/null
+// This should fail even without validation.
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let x = 16usize as *const u32;
+ let _y = unsafe { &*x as *const u32 }; //~ ERROR invalid use of 16 as a pointer
+}
--- /dev/null
+// Deref a raw ptr to access a field of a large struct, where the field
+// is allocated but not the entire struct is.
+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 alloc
+ assert_eq!(val, 13);
+}
--- /dev/null
+fn main() {
+ // This pointer *could* be NULL so we cannot load from it, not even at ZST
+ let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *const ();
+ let _x: () = unsafe { *ptr }; //~ ERROR outside bounds
+}
--- /dev/null
+fn main() {
+ // This pointer *could* be NULL so we cannot load from it, not even at ZST.
+ // Not using the () type here, as writes of that type do not even have MIR generated.
+ // Also not assigning directly as that's array initialization, not assignment.
+ let zst_val = [1u8; 0];
+ let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *mut [u8; 0];
+ unsafe { *ptr = zst_val; } //~ ERROR outside bounds
+}
--- /dev/null
+fn main() {
+ let v: Vec<u8> = vec![1, 2];
+ let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc
+ panic!("this should never print: {}", x);
+}
--- /dev/null
+fn main() {
+ let v: Vec<u8> = vec![1, 2];
+ let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc
+ panic!("this should never print: {}", x);
+}
--- /dev/null
+fn main() {
+ let p = 44 as *const i32;
+ let x = unsafe { *p }; //~ ERROR invalid use of 44 as a pointer
+ panic!("this should never print: {}", x);
+}
+++ /dev/null
-fn main() {
- let p = {
- let b = Box::new(42);
- &*b as *const i32 as *const ()
- };
- let _x = unsafe { *p }; //~ ERROR dereferenced after this allocation got freed
-}
+++ /dev/null
-use std::alloc::{alloc, dealloc, Layout};
-
-// error-pattern: allocation has size 1 and alignment 1, but gave size 1 and alignment 2
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- dealloc(x, Layout::from_size_align_unchecked(1, 2));
- }
-}
+++ /dev/null
-use std::alloc::{alloc, dealloc, Layout};
-
-// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- dealloc(x, Layout::from_size_align_unchecked(2, 1));
- }
-}
+++ /dev/null
-use std::alloc::{alloc, dealloc, Layout};
-
-// error-pattern: dereferenced after this allocation got freed
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- dealloc(x, Layout::from_size_align_unchecked(1, 1));
- dealloc(x, Layout::from_size_align_unchecked(1, 1));
- }
-}
+++ /dev/null
-// This should fail even without validation.
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let x = 2usize as *const u32;
- let _y = unsafe { &*x as *const u32 }; //~ ERROR invalid use of 2 as a pointer
-}
+++ /dev/null
-// Deref a raw ptr to access a field of a large struct, where the field
-// is allocated but not the entire struct is.
-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 alloc
- assert_eq!(val, 13);
-}
+++ /dev/null
-fn f() {}
-
-fn main() {
- let x: u8 = unsafe {
- *std::mem::transmute::<fn(), *const u8>(f) //~ ERROR contains a function
- };
- panic!("this should never print: {}", x);
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-
-use std::intrinsics::*;
-
-fn main() {
- unsafe {
- let _n = unchecked_div(1i64, 0); //~ERROR dividing by zero
- }
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-
-use std::intrinsics::*;
-
-fn main() {
- unsafe {
- let _n = unchecked_rem(3u32, 0); //~ ERROR calculating the remainder with a divisor of zero
- }
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // divison by 0
- unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // divison with a remainder
- unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR 2u16 cannot be divided by 3u16 without remainder
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // signed divison with a remainder
- unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR -19i8 cannot be divided by 2i8 without remainder
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // divison of MIN by -1
- unsafe { std::intrinsics::exact_div(i64::MIN, -1); } //~ ERROR result of dividing MIN by -1 cannot be represented
-}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmiri-disable-validation
-
-#![feature(box_syntax)]
-
-fn main() {
- let x = box 42;
- unsafe {
- let f = std::mem::transmute::<Box<i32>, fn()>(x);
- f() //~ ERROR function pointer but it does not point to a function
- }
-}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmiri-disable-validation
-
-use std::mem;
-
-fn f() {}
-
-fn main() {
- let x : fn() = f;
- let y : *mut u8 = unsafe { mem::transmute(x) };
- let y = y.wrapping_offset(1);
- let x : fn() = unsafe { mem::transmute(y) };
- x(); //~ ERROR function pointer but it does not point to a function
-}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let b = Box::new(42);
+ let g = unsafe {
+ std::mem::transmute::<&Box<usize>, &fn(i32)>(&b)
+ };
+
+ (*g)(42) //~ ERROR it does not point to a function
+}
--- /dev/null
+fn main() {
+ fn f() {}
+
+ let g = unsafe {
+ std::mem::transmute::<fn(), fn(i32)>(f)
+ };
+
+ g(42) //~ ERROR calling a function with more arguments than it expected
+}
--- /dev/null
+fn main() {
+ fn f(_ : (i32,i32)) {}
+
+ let g = unsafe {
+ std::mem::transmute::<fn((i32,i32)), fn(i32)>(f)
+ };
+
+ g(42) //~ ERROR calling a function with argument of type (i32, i32) passing data of type i32
+}
--- /dev/null
+fn main() {
+ fn f(_ : (i32,i32)) {}
+
+ let g = unsafe {
+ std::mem::transmute::<fn((i32,i32)), fn()>(f)
+ };
+
+ g() //~ ERROR calling a function with fewer arguments than it requires
+}
+
--- /dev/null
+fn main() {
+ fn f(_ : *const [i32]) {}
+
+ let g = unsafe {
+ std::mem::transmute::<fn(*const [i32]), fn(*const i32)>(f)
+ };
+
+ g(&42 as *const i32) //~ ERROR calling a function with argument of type *const [i32] passing data of type *const i32
+}
--- /dev/null
+fn main() {
+ fn f() -> u32 { 42 }
+
+ let g = unsafe {
+ std::mem::transmute::<fn() -> u32, fn()>(f)
+ };
+
+ g() //~ ERROR calling a function with return type u32 passing return place of type ()
+}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let g = unsafe {
+ std::mem::transmute::<usize, fn(i32)>(42)
+ };
+
+ g(42) //~ ERROR invalid use of 42 as a pointer
+}
--- /dev/null
+fn f() {}
+
+fn main() {
+ let x: u8 = unsafe {
+ *std::mem::transmute::<fn(), *const u8>(f) //~ ERROR contains a function
+ };
+ panic!("this should never print: {}", x);
+}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+#![feature(box_syntax)]
+
+fn main() {
+ let x = box 42;
+ unsafe {
+ let f = std::mem::transmute::<Box<i32>, fn()>(x);
+ f() //~ ERROR function pointer but it does not point to a function
+ }
+}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+use std::mem;
+
+fn f() {}
+
+fn main() {
+ let x : fn() = f;
+ let y : *mut u8 = unsafe { mem::transmute(x) };
+ let y = y.wrapping_offset(1);
+ let x : fn() = unsafe { mem::transmute(y) };
+ x(); //~ ERROR function pointer but it does not point to a function
+}
+++ /dev/null
-// Even with intptrcast and without validation, we want to be *sure* to catch bugs
-// that arise from pointers being insufficiently aligned. The only way to achieve
-// that is not not let programs exploit integer information for alignment, so here
-// we test that this is indeed the case.
-fn main() {
- let x = &mut [0u8; 3];
- 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 memory with alignment 1, but alignment 2 is required
- println!("{:?}", x);
-}
--- /dev/null
+#![feature(core_intrinsics)]
+
+fn main() {
+ let x = 5;
+ unsafe {
+ std::intrinsics::assume(x < 10);
+ std::intrinsics::assume(x > 1);
+ std::intrinsics::assume(x > 42); //~ `assume` intrinsic called with `false`
+ }
+}
--- /dev/null
+#![feature(intrinsics)]
+
+// Directly call intrinsic to avoid debug assertions in libstd
+extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+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); } //~ ERROR: invalid use of NULL pointer
+}
--- /dev/null
+// 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::<usize>() * 8 - 1));
+ }
+}
--- /dev/null
+//error-pattern: copy_nonoverlapping called on overlapping ranges
+#![feature(intrinsics)]
+
+// Directly call intrinsic to avoid debug assertions in libstd
+extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+fn main() {
+ let mut data = [0u8; 16];
+ unsafe {
+ let a = data.as_mut_ptr();
+ let b = a.wrapping_offset(1) as *mut _;
+ copy_nonoverlapping(a, b, 2);
+ }
+}
--- /dev/null
+//error-pattern: accessing memory with alignment 1, but alignment 2 is required
+#![feature(intrinsics)]
+
+// Directly call intrinsic to avoid debug assertions in libstd
+extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+fn main() {
+ let mut data = [0u16; 8];
+ let ptr = (&mut data[0] as *mut u16 as *mut u8).wrapping_add(1) as *mut u16;
+ // Even copying 0 elements to something unaligned should error
+ unsafe { copy_nonoverlapping(&data[5], ptr, 0); }
+}
--- /dev/null
+#![feature(intrinsics)]
+
+mod rusti {
+ extern "rust-intrinsic" {
+ pub fn ctlz_nonzero<T>(x: T) -> T;
+ }
+}
+
+pub fn main() {
+ unsafe {
+ use crate::rusti::*;
+
+ ctlz_nonzero(0u8); //~ ERROR `ctlz_nonzero` called on 0
+ }
+}
--- /dev/null
+#![feature(intrinsics)]
+
+mod rusti {
+ extern "rust-intrinsic" {
+ pub fn cttz_nonzero<T>(x: T) -> T;
+ }
+}
+
+pub fn main() {
+ unsafe {
+ use crate::rusti::*;
+
+ cttz_nonzero(0u8); //~ ERROR `cttz_nonzero` called on 0
+ }
+}
--- /dev/null
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+fn main() {
+ unsafe {
+ let _n = unchecked_div(1i64, 0); //~ERROR dividing by zero
+ }
+}
--- /dev/null
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+fn main() {
+ unsafe {
+ let _n = unchecked_rem(3u32, 0); //~ ERROR calculating the remainder with a divisor of zero
+ }
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // divison by 0
+ unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // divison with a remainder
+ unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR 2u16 cannot be divided by 3u16 without remainder
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // signed divison with a remainder
+ unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR -19i8 cannot be divided by 2i8 without remainder
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // divison of MIN by -1
+ unsafe { std::intrinsics::exact_div(i64::MIN, -1); } //~ ERROR result of dividing MIN by -1 cannot be represented
+}
--- /dev/null
+// 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;
+ // The error is inside another function, so we cannot match it by line
+ let x = unsafe { x.offset(5) };
+ panic!("this should never print: {:?}", x);
+}
--- /dev/null
+// error-pattern: overflowing in-bounds pointer arithmetic
+fn main() {
+ let v = [0i8; 4];
+ let x = &v as *const i8;
+ let x = unsafe { x.offset(-1) };
+ panic!("this should never print: {:?}", x);
+}
--- /dev/null
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+//error-pattern: overflowing shift by 64 in `unchecked_shr`
+
+fn main() {
+ unsafe {
+ let _n = unchecked_shr(1i64, 64);
+ }
+}
--- /dev/null
+// error-pattern: invalid use of NULL pointer
+
+fn main() {
+ let x = 0 as *mut i32;
+ let _x = x.wrapping_offset(8); // ok, this has no inbounds tag
+ let _x = unsafe { x.offset(0) }; // UB despite offset 0, NULL is never inbounds
+}
--- /dev/null
+// error-pattern: invalid use of 1 as a pointer
+
+fn main() {
+ // Can't offset an integer pointer by non-zero offset.
+ unsafe {
+ let _val = (1 as *mut u8).offset(1);
+ }
+}
--- /dev/null
+// error-pattern: invalid use of 1 as a pointer
+
+fn main() {
+ let ptr = Box::into_raw(Box::new(0u32));
+ // Can't start with an integer pointer and get to something usable
+ unsafe {
+ let _val = (1 as *mut u8).offset(ptr as isize);
+ }
+}
--- /dev/null
+//error-pattern: overflowing in-bounds pointer arithmetic
+fn main() {
+ let v = [1i8, 2];
+ let x = &v[1] as *const i8;
+ let _val = unsafe { x.offset(isize::MIN) };
+}
--- /dev/null
+// error-pattern: outside bounds of alloc
+
+fn main() {
+ let x = Box::into_raw(Box::new(0u32));
+ let x = x.wrapping_offset(8); // ok, this has no inbounds tag
+ let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is not inbounds of the only object it can point to
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MAX overflow
+ unsafe { std::intrinsics::unchecked_add(40000u16, 30000); } //~ ERROR overflow executing `unchecked_add`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MIN overflow
+ unsafe { std::intrinsics::unchecked_add(-30000i16, -8000); } //~ ERROR overflow executing `unchecked_add`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MIN/-1 cannot be represented
+ unsafe { std::intrinsics::unchecked_div(i16::MIN, -1); } //~ ERROR overflow executing `unchecked_div`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MAX overflow
+ unsafe { std::intrinsics::unchecked_mul(300u16, 250u16); } //~ ERROR overflow executing `unchecked_mul`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MIN overflow
+ unsafe { std::intrinsics::unchecked_mul(1_000_000_000i32, -4); } //~ ERROR overflow executing `unchecked_mul`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MIN overflow
+ unsafe { std::intrinsics::unchecked_sub(14u32, 22); } //~ ERROR overflow executing `unchecked_sub`
+}
--- /dev/null
+#![feature(core_intrinsics)]
+fn main() {
+ // MAX overflow
+ unsafe { std::intrinsics::unchecked_sub(30000i16, -7000); } //~ ERROR overflow executing `unchecked_sub`
+}
--- /dev/null
+#![feature(intrinsics)]
+
+// Directly call intrinsic to avoid debug assertions in libstd
+extern "rust-intrinsic" {
+ fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+}
+
+fn main() {
+ unsafe { write_bytes::<u8>(std::ptr::null_mut(), 0, 0) }; //~ ERROR invalid use of NULL pointer
+}
--- /dev/null
+// 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::<usize>() * 8 - 1));
+ }
+}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- unsafe {
- let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
- let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
- assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
- libc::pthread_mutex_destroy(&mut mutex as *mut _); //~ ERROR destroyed a locked mutex
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- unsafe {
- let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
- let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
- assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
- libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR deadlock
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- unsafe {
- let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
- let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
- assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
- assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
- assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
- libc::pthread_mutex_unlock(&mut mutex as *mut _); //~ ERROR was not locked
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
- libc::pthread_rwlock_destroy(rw.get()); //~ ERROR destroyed a locked rwlock
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
- libc::pthread_rwlock_destroy(rw.get()); //~ ERROR destroyed a locked rwlock
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
- libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- libc::pthread_rwlock_unlock(rw.get()); //~ ERROR was not locked
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
- libc::pthread_rwlock_rdlock(rw.get()); //~ ERROR: deadlock
- }
-}
+++ /dev/null
-// ignore-windows: No libc on Windows
-
-#![feature(rustc_private)]
-
-extern crate libc;
-
-fn main() {
- let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
- unsafe {
- assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
- libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock
- }
-}
+++ /dev/null
-fn main() {
- // This pointer *could* be NULL so we cannot load from it, not even at ZST
- let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *const ();
- let _x: () = unsafe { *ptr }; //~ ERROR outside bounds
-}
+++ /dev/null
-fn main() {
- // This pointer *could* be NULL so we cannot load from it, not even at ZST.
- // Not using the () type here, as writes of that type do not even have MIR generated.
- // Also not assigning directly as that's array initialization, not assignment.
- let zst_val = [1u8; 0];
- let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *mut [u8; 0];
- unsafe { *ptr = zst_val; } //~ ERROR outside bounds
-}
+++ /dev/null
-// 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;
- // The error is inside another function, so we cannot match it by line
- let x = unsafe { x.offset(5) };
- panic!("this should never print: {:?}", x);
-}
+++ /dev/null
-// error-pattern: overflowing in-bounds pointer arithmetic
-fn main() {
- let v = [0i8; 4];
- let x = &v as *const i8;
- let x = unsafe { x.offset(-1) };
- panic!("this should never print: {:?}", x);
-}
+++ /dev/null
-fn main() {
- let v: Vec<u8> = vec![1, 2];
- let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc
- panic!("this should never print: {}", x);
-}
+++ /dev/null
-fn main() {
- let v: Vec<u8> = vec![1, 2];
- let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of alloc
- panic!("this should never print: {}", x);
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-
-use std::intrinsics::*;
-
-//error-pattern: overflowing shift by 64 in `unchecked_shr`
-
-fn main() {
- unsafe {
- let _n = unchecked_shr(1i64, 64);
- }
-}
+++ /dev/null
-// error-pattern: invalid use of NULL pointer
-
-fn main() {
- let x = 0 as *mut i32;
- let _x = x.wrapping_offset(8); // ok, this has no inbounds tag
- let _x = unsafe { x.offset(0) }; // UB despite offset 0, NULL is never inbounds
-}
+++ /dev/null
-// error-pattern: invalid use of 1 as a pointer
-
-fn main() {
- // Can't offset an integer pointer by non-zero offset.
- unsafe {
- let _val = (1 as *mut u8).offset(1);
- }
-}
+++ /dev/null
-// error-pattern: invalid use of 1 as a pointer
-
-fn main() {
- let ptr = Box::into_raw(Box::new(0u32));
- // Can't start with an integer pointer and get to something usable
- unsafe {
- let _val = (1 as *mut u8).offset(ptr as isize);
- }
-}
+++ /dev/null
-//error-pattern: overflowing in-bounds pointer arithmetic
-fn main() {
- let v = [1i8, 2];
- let x = &v[1] as *const i8;
- let _val = unsafe { x.offset(isize::MIN) };
-}
+++ /dev/null
-// error-pattern: outside bounds of alloc
-
-fn main() {
- let x = Box::into_raw(Box::new(0u32));
- let x = x.wrapping_offset(8); // ok, this has no inbounds tag
- let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is not inbounds of the only object it can point to
-}
+++ /dev/null
-use std::alloc::{alloc, realloc, Layout};
-
-// error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
- }
-}
+++ /dev/null
-use std::alloc::{alloc, realloc, Layout};
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
- let _z = *x; //~ ERROR dereferenced after this allocation got freed
- }
-}
+++ /dev/null
-use std::alloc::{alloc, dealloc, realloc, Layout};
-
-// error-pattern: dereferenced after this allocation got freed
-
-fn main() {
- unsafe {
- let x = alloc(Layout::from_size_align_unchecked(1, 1));
- dealloc(x, Layout::from_size_align_unchecked(1, 1));
- realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
- }
-}
+++ /dev/null
-// This should fail even without validation/SB
-// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
-
-#![allow(dead_code, unused_variables)]
-
-#[repr(packed)]
-struct Foo {
- x: i32,
- y: i32,
-}
-
-fn main() {
- let foo = Foo {
- x: 42,
- y: 99,
- };
- let p = unsafe { &foo.x };
- let i = *p; //~ ERROR memory with alignment 1, but alignment 4 is required
-}
+++ /dev/null
-// Validation/SB changes why we fail
-// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
-
-// error-pattern: deallocating stack variable memory using Rust heap deallocation operation
-
-fn main() {
- let x = 42;
- let bad_box = unsafe { std::mem::transmute::<&i32, Box<i32>>(&x) };
- drop(bad_box);
-}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ unsafe {
+ let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
+ let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
+ assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
+ libc::pthread_mutex_destroy(&mut mutex as *mut _); //~ ERROR destroyed a locked mutex
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ unsafe {
+ let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
+ let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
+ assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
+ libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR deadlock
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ unsafe {
+ let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), 0);
+ let mut mutex: libc::pthread_mutex_t = std::mem::zeroed();
+ assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0);
+ assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
+ assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
+ libc::pthread_mutex_unlock(&mut mutex as *mut _); //~ ERROR was not locked
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
+ libc::pthread_rwlock_destroy(rw.get()); //~ ERROR destroyed a locked rwlock
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
+ libc::pthread_rwlock_destroy(rw.get()); //~ ERROR destroyed a locked rwlock
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0);
+ libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ libc::pthread_rwlock_unlock(rw.get()); //~ ERROR was not locked
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
+ libc::pthread_rwlock_rdlock(rw.get()); //~ ERROR: deadlock
+ }
+}
--- /dev/null
+// ignore-windows: No libc on Windows
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+fn main() {
+ let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
+ unsafe {
+ assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0);
+ libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock
+ }
+}
--- /dev/null
+fn main() {
+ // miri always gives allocations the worst possible alignment, so a `u8` array is guaranteed
+ // to be at the virtual location 1 (so one byte offset from the ultimate alignemnt location 0)
+ let mut x = [0u8; 20];
+ let x_ptr: *mut u8 = &mut x[0];
+ let y_ptr = x_ptr as *mut u64;
+ unsafe {
+ *y_ptr = 42; //~ ERROR accessing memory with alignment 1, but alignment
+ }
+ panic!("unreachable in miri");
+}
--- /dev/null
+#![feature(core_intrinsics)]
+
+fn main() {
+ // Do a 4-aligned u64 atomic access. That should be UB on all platforms,
+ // even if u64 only has alignment 4.
+ let z = [0u32; 2];
+ let zptr = &z as *const _ as *const u64;
+ unsafe {
+ ::std::intrinsics::atomic_load(zptr);
+ //~^ ERROR accessing memory with alignment 4, but alignment 8 is required
+ }
+}
--- /dev/null
+// Even with intptrcast and without validation, we want to be *sure* to catch bugs
+// that arise from pointers being insufficiently aligned. The only way to achieve
+// that is not not let programs exploit integer information for alignment, so here
+// we test that this is indeed the case.
+fn main() {
+ let x = &mut [0u8; 3];
+ 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 memory with alignment 1, but alignment 2 is required
+ println!("{:?}", x);
+}
--- /dev/null
+// This should fail even without validation/SB
+// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
+
+#![allow(dead_code, unused_variables)]
+
+#[repr(packed)]
+struct Foo {
+ x: i32,
+ y: i32,
+}
+
+fn main() {
+ let foo = Foo {
+ x: 42,
+ y: 99,
+ };
+ let p = unsafe { &foo.x };
+ let i = *p; //~ ERROR memory with alignment 1, but alignment 4 is required
+}
--- /dev/null
+// This should fail even without validation
+// compile-flags: -Zmiri-disable-validation
+
+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 memory with alignment 2, but alignment 4 is required
+}
--- /dev/null
+// This should fail even without validation.
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let x = [2u32, 3]; // Make it big enough so we don't get an out-of-bounds error.
+ 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 memory with alignment 1, but alignment 4 is required
+}
--- /dev/null
+// This should fail even without validation.
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let x = [2u16, 3, 4, 5]; // Make it big enough so we don't get an out-of-bounds error.
+ let x = &x[0] as *const _ as *const *const u8; // cast to ptr-to-ptr, so that we load a ptr
+ // 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 memory with alignment 2, but alignment
+}
--- /dev/null
+// This should fail even without validation
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let x = &2u16;
+ 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 memory with alignment 2, but alignment 4 is required
+}
+++ /dev/null
-// This should fail even without validation
-// compile-flags: -Zmiri-disable-validation
-
-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 memory with alignment 2, but alignment 4 is required
-}
+++ /dev/null
-// This should fail even without validation.
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let x = [2u32, 3]; // Make it big enough so we don't get an out-of-bounds error.
- 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 memory with alignment 1, but alignment 4 is required
-}
+++ /dev/null
-// This should fail even without validation.
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let x = [2u16, 3, 4, 5]; // Make it big enough so we don't get an out-of-bounds error.
- let x = &x[0] as *const _ as *const *const u8; // cast to ptr-to-ptr, so that we load a ptr
- // 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 memory with alignment 2, but alignment
-}
+++ /dev/null
-// This should fail even without validation
-// compile-flags: -Zmiri-disable-validation
-
-fn main() {
- let x = &2u16;
- 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 memory with alignment 2, but alignment 4 is required
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MAX overflow
- unsafe { std::intrinsics::unchecked_add(40000u16, 30000); } //~ ERROR overflow executing `unchecked_add`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MIN overflow
- unsafe { std::intrinsics::unchecked_add(-30000i16, -8000); } //~ ERROR overflow executing `unchecked_add`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MIN/-1 cannot be represented
- unsafe { std::intrinsics::unchecked_div(i16::MIN, -1); } //~ ERROR overflow executing `unchecked_div`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MAX overflow
- unsafe { std::intrinsics::unchecked_mul(300u16, 250u16); } //~ ERROR overflow executing `unchecked_mul`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MIN overflow
- unsafe { std::intrinsics::unchecked_mul(1_000_000_000i32, -4); } //~ ERROR overflow executing `unchecked_mul`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MIN overflow
- unsafe { std::intrinsics::unchecked_sub(14u32, 22); } //~ ERROR overflow executing `unchecked_sub`
-}
+++ /dev/null
-#![feature(core_intrinsics)]
-fn main() {
- // MAX overflow
- unsafe { std::intrinsics::unchecked_sub(30000i16, -7000); } //~ ERROR overflow executing `unchecked_sub`
-}
+++ /dev/null
-fn main() {
- let p = 44 as *const i32;
- let x = unsafe { *p }; //~ ERROR invalid use of 44 as a pointer
- panic!("this should never print: {}", x);
-}
+++ /dev/null
-#![feature(intrinsics)]
-
-// Directly call intrinsic to avoid debug assertions in libstd
-extern "rust-intrinsic" {
- fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
-}
-
-fn main() {
- unsafe { write_bytes::<u8>(std::ptr::null_mut(), 0, 0) }; //~ ERROR invalid use of NULL pointer
-}
+++ /dev/null
-// 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::<usize>() * 8 - 1));
- }
-}