diff --git a/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs b/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs new file mode 100644 index 00000000000..d6413faf74b --- /dev/null +++ b/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs @@ -0,0 +1,9 @@ +//@error-pattern: first pointer has smaller offset than second: 0 < 4 +#![feature(ptr_sub_ptr)] + +fn main() { + let arr = [0u8; 8]; + let ptr1 = arr.as_ptr(); + let ptr2 = ptr1.wrapping_add(4); + let _val = unsafe { ptr1.sub_ptr(ptr2) }; +} diff --git a/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr b/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr new file mode 100644 index 00000000000..bb68f9f5c18 --- /dev/null +++ b/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: ptr_offset_from_unsigned called when first pointer has smaller offset than second: 0 < 4 + --> RUSTLIB/core/src/ptr/const_ptr.rs:LL:CC + | +LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called when first pointer has smaller offset than second: 0 < 4 + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: backtrace: + = note: inside `std::ptr::const_ptr::::sub_ptr` at RUSTLIB/core/src/ptr/const_ptr.rs:LL:CC +note: inside `main` at $DIR/ptr_offset_from_unsigned_neg.rs:LL:CC + --> $DIR/ptr_offset_from_unsigned_neg.rs:LL:CC + | +LL | let _val = unsafe { ptr1.sub_ptr(ptr2) }; + | ^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/pass/intrinsics.rs b/tests/pass/intrinsics.rs index 756744badaf..6267e6e6bc1 100644 --- a/tests/pass/intrinsics.rs +++ b/tests/pass/intrinsics.rs @@ -1,6 +1,6 @@ //@compile-flags: -Zmiri-permissive-provenance -#![feature(core_intrinsics, const_raw_ptr_comparison)] -#![feature(layout_for_ptr)] +#![feature(core_intrinsics, layout_for_ptr)] +//! Tests for various intrinsics that do not fit anywhere else. use std::intrinsics; use std::mem::{size_of, size_of_val, size_of_val_raw}; @@ -39,9 +39,4 @@ fn main() { let _v = intrinsics::discriminant_value(&0); let _v = intrinsics::discriminant_value(&true); let _v = intrinsics::discriminant_value(&vec![1, 2, 3]); - - let addr = &13 as *const i32; - let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1); - assert!(addr.guaranteed_eq(addr2 as *const _)); - assert!(addr.guaranteed_ne(0x100 as *const _)); } diff --git a/tests/pass/pointers.rs b/tests/pass/pointers.rs index a271e764d9f..b2e6f4556fa 100644 --- a/tests/pass/pointers.rs +++ b/tests/pass/pointers.rs @@ -1,4 +1,5 @@ -#![feature(ptr_metadata)] +//@compile-flags: -Zmiri-permissive-provenance +#![feature(ptr_metadata, const_raw_ptr_comparison)] use std::mem::{self, transmute}; use std::ptr; @@ -131,6 +132,12 @@ fn main() { assert!(dangling > 3); assert!(dangling >= 4); + // CTFE-specific equality tests, need to also work at runtime. + let addr = &13 as *const i32; + let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1); + assert!(addr.guaranteed_eq(addr2 as *const _)); + assert!(addr.guaranteed_ne(0x100 as *const _)); + wide_ptr_ops(); metadata_vtable(); } diff --git a/tests/pass/ptr_offset.rs b/tests/pass/ptr_offset.rs index 5270e8663b2..95eac8522fb 100644 --- a/tests/pass/ptr_offset.rs +++ b/tests/pass/ptr_offset.rs @@ -1,7 +1,9 @@ //@compile-flags: -Zmiri-permissive-provenance +#![feature(ptr_sub_ptr)] use std::{mem, ptr}; fn main() { + smoke(); test_offset_from(); test_vec_into_iter(); ptr_arith_offset(); @@ -9,6 +11,20 @@ fn main() { ptr_offset(); } +fn smoke() { + // Smoke-test various offsetting operations. + let ptr = &5; + let ptr = ptr as *const i32; + let _val = ptr.wrapping_offset(0); + let _val = unsafe { ptr.offset(0) }; + let _val = ptr.wrapping_add(0); + let _val = unsafe { ptr.add(0) }; + let _val = ptr.wrapping_sub(0); + let _val = unsafe { ptr.sub(0) }; + let _val = unsafe { ptr.offset_from(ptr) }; + let _val = unsafe { ptr.sub_ptr(ptr) }; +} + fn test_offset_from() { unsafe { let buf = [0u32; 4]; @@ -17,12 +33,14 @@ fn test_offset_from() { let y = x.offset(12); assert_eq!(y.offset_from(x), 12); + assert_eq!(y.sub_ptr(x), 12); assert_eq!(x.offset_from(y), -12); assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4); assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4); let x = (((x as usize) * 2) / 2) as *const u8; assert_eq!(y.offset_from(x), 12); + assert_eq!(y.sub_ptr(x), 12); assert_eq!(x.offset_from(y), -12); } }