+++ /dev/null
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(dead_code)]
-
-use std::mem;
-
-enum Tag<A> {
- Tag2(A)
-}
-
-struct Rec {
- c8: u8,
- t: Tag<u64>
-}
-
-fn mk_rec() -> Rec {
- return Rec { c8:0, t:Tag::Tag2(0) };
-}
-
-fn is_u64_aligned(u: &Tag<u64>) -> bool {
- let p: usize = unsafe { mem::transmute(u) };
- let u64_align = std::mem::align_of::<u64>();
- return (p & (u64_align + 1)) == 0; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
-}
-
-pub fn main() {
- let x = mk_rec();
- assert!(is_u64_aligned(&x.t));
-}
fn main() {
let b = Box::new(42);
let g = unsafe {
- std::mem::transmute::<&usize, &fn(i32)>(&b)
+ std::mem::transmute::<&Box<usize>, &fn(i32)>(&b)
};
- (*g)(42) //~ ERROR a memory access tried to interpret some bytes as a pointer
+ (*g)(42) //~ ERROR tried to treat a memory pointer as a function pointer
}
std::mem::transmute::<usize, fn(i32)>(42)
};
- g(42) //~ ERROR a memory access tried to interpret some bytes as a pointer
+ g(42) //~ ERROR dangling pointer was dereferenced
}
+++ /dev/null
-// ignore-macos: Uses Linux-only APIs
-// ignore-windows: Uses Linux-only APIs
-
-#![feature(rustc_private)]
-extern crate libc;
-
-fn main() {
- let mut buf = [0u8; 5];
- unsafe {
- libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr() as *mut libc::c_void, 5 as libc::size_t, 0 as libc::c_uint);
- //~^ ERROR miri does not support gathering system entropy in deterministic mode!
- }
-}
--- /dev/null
+fn main() {
+ let x = 13;
+ 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
+}
+++ /dev/null
-fn main() {
- let x = 13;
- let y = &x;
- let z = &y as *const &i32 as *const usize;
- let ptr_bytes = unsafe { *z }; // the actual deref is fine, because we read the entire pointer at once
- let _val = ptr_bytes / 432; //~ ERROR invalid arithmetic on pointers that would leak base addresses
-}
+++ /dev/null
-fn main() {
- let x = 13;
- 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
-}
+++ /dev/null
-fn main() {
- let bytes = [0i8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
- let one = bytes.as_ptr().wrapping_offset(1);
- let three = bytes.as_ptr().wrapping_offset(3);
- let res = (one as usize) | (three as usize); //~ ERROR invalid arithmetic on pointers that would leak base addresses
- println!("{}", res);
-}
+++ /dev/null
-fn main() {
- let val = 13usize;
- let addr = &val as *const _ as usize;
- let _val = addr & 13; //~ ERROR access part of a pointer value as raw bytes
-}
+++ /dev/null
-fn main() {
- let b = Box::new(0);
- let x = &*b as *const i32; // soon-to-be dangling
- drop(b);
- let b = Box::new(0);
- let y = &*b as *const i32; // different allocation
- // We cannot compare these even though both are inbounds -- they *could* be
- // equal if memory was reused.
- assert!(x != y); //~ ERROR invalid arithmetic on pointers
-}
+++ /dev/null
-fn main() {
- let b = Box::new(0);
- let x = &*b as *const i32;
- // We cannot compare this with a non-NULL integer. After all, these *could* be equal (with the right base address).
- assert!(x != 64 as *const i32); //~ ERROR invalid arithmetic on pointers
-}
+++ /dev/null
-fn main() {
- let b = Box::new(0);
- let x = (&*b as *const i32).wrapping_sub(0x800); // out-of-bounds
- let b = Box::new(0);
- let y = &*b as *const i32; // different allocation
- // We cannot compare these even though both allocations are live -- they *could* be
- // equal (with the right base addresses).
- assert!(x != y); //~ ERROR invalid arithmetic on pointers
-}
+++ /dev/null
-fn main() {
- let b = Box::new(0);
- let x = (&*b as *const i32).wrapping_sub(0x800); // out-of-bounds
- // We cannot compare this with NULL. After all, this *could* be NULL (with the right base address).
- assert!(x != std::ptr::null()); //~ ERROR invalid arithmetic on pointers
-}
+++ /dev/null
-fn main() {
- let x = &1;
- // Casting down to u8 and back up to a pointer loses too much precision; this must not work.
- let x = x as *const i32;
- let x = x as u8; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
- let x = x as *const i32;
- let _val = unsafe { *x };
-}
-// error-pattern: tried to interpret some bytes as a pointer
+// error-pattern: dangling pointer was dereferenced
fn main() {
// Can't offset an integer pointer by non-zero offset.
-// error-pattern: pointer value as raw bytes
+// error-pattern: dangling pointer was dereferenced
fn main() {
let ptr = Box::into_raw(Box::new(0u32));
+++ /dev/null
-fn main() {
- let val = 13usize;
- let addr = &val as *const _ as usize;
- let _val = addr % 16; //~ ERROR access part of a pointer value as raw bytes
-}
+++ /dev/null
-// error-pattern: pointer value as raw bytes
-
-fn main() {
- let ptr = Box::into_raw(Box::new(0u32));
- // Can't start with an integer pointer and get to something usable
- let ptr = (1 as *mut u8).wrapping_offset(ptr as isize);
- let _val = unsafe { *ptr };
-}
use std::mem;
fn main() {
- let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR dangling reference (created from integer)
+ let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR dangling reference (not entirely in bounds)
}
fn main() {
let p = 44 as *const i32;
- let x = unsafe { *p }; //~ ERROR a memory access tried to interpret some bytes as a pointer
+ let x = unsafe { *p }; //~ ERROR dangling pointer was dereferenced
panic!("this should never print: {}", x);
}
--- /dev/null
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+use std::mem;
+
+enum Tag<A> {
+ Tag2(A)
+}
+
+struct Rec {
+ c8: u8,
+ t: Tag<u64>
+}
+
+fn mk_rec() -> Rec {
+ return Rec { c8:0, t:Tag::Tag2(0) };
+}
+
+fn is_u64_aligned(u: &Tag<u64>) -> bool {
+ let p: usize = unsafe { mem::transmute(u) };
+ let u64_align = std::mem::align_of::<u64>();
+ return (p & (u64_align + 1)) == 0;
+}
+
+pub fn main() {
+ let x = mk_rec();
+ assert!(is_u64_aligned(&x.t));
+}
unsafe { std::mem::transmute(x) }
}
-fn main() {
+fn cast() {
// Some casting-to-int with arithmetic.
let x = &42 as *const i32 as usize;
let y = x * 2;
assert_eq!(y, x + x);
let z = y as u8 as usize;
assert_eq!(z, y % 256);
+}
+fn format() {
// Pointer string formatting! We can't check the output as it changes when libstd changes,
// but we can make sure Miri does not error.
format!("{:?}", &mut 13 as *mut _);
+}
+fn transmute() {
// Check that intptrcast is triggered for explicit casts and that it is consistent with
// transmuting.
let a: *const i32 = &42;
let c = a as usize as u8;
assert_eq!(b, c);
}
+
+fn ptr_bitops1() {
+ let bytes = [0i8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let one = bytes.as_ptr().wrapping_offset(1);
+ let three = bytes.as_ptr().wrapping_offset(3);
+ let res = (one as usize) | (three as usize);
+ format!("{}", res);
+}
+
+fn ptr_bitops2() {
+ let val = 13usize;
+ let addr = &val as *const _ as usize;
+ let _val = addr & 13;
+}
+
+fn ptr_eq_dangling() {
+ let b = Box::new(0);
+ let x = &*b as *const i32; // soon-to-be dangling
+ drop(b);
+ let b = Box::new(0);
+ let y = &*b as *const i32; // different allocation
+ // We cannot compare these even though both are inbounds -- they *could* be
+ // equal if memory was reused.
+ assert!(x != y);
+}
+
+fn ptr_eq_out_of_bounds() {
+ let b = Box::new(0);
+ let x = (&*b as *const i32).wrapping_sub(0x800); // out-of-bounds
+ let b = Box::new(0);
+ let y = &*b as *const i32; // different allocation
+ // We cannot compare these even though both allocations are live -- they *could* be
+ // equal (with the right base addresses).
+ assert!(x != y);
+}
+
+fn ptr_eq_out_of_bounds_null() {
+ let b = Box::new(0);
+ let x = (&*b as *const i32).wrapping_sub(0x800); // out-of-bounds
+ // We cannot compare this with NULL. After all, this *could* be NULL (with the right base address).
+ assert!(x != std::ptr::null());
+}
+
+fn ptr_eq_integer() {
+ let b = Box::new(0);
+ let x = &*b as *const i32;
+ // We cannot compare this with a non-NULL integer. After all, these *could* be equal (with the right base address).
+ assert!(x != 64 as *const i32);
+}
+
+fn main() {
+ cast();
+ format();
+ transmute();
+ ptr_bitops1();
+ ptr_bitops2();
+ ptr_eq_dangling();
+ ptr_eq_out_of_bounds();
+ ptr_eq_out_of_bounds_null();
+ ptr_eq_integer();
+}