about summary refs log tree commit diff
path: root/tests/ui/consts
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/consts')
-rw-r--r--tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr4
-rw-r--r--tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr2
-rw-r--r--tests/ui/consts/const-eval/partial_ptr_overwrite.rs12
-rw-r--r--tests/ui/consts/const-eval/partial_ptr_overwrite.stderr12
-rw-r--r--tests/ui/consts/const-eval/ptr_fragments.rs63
-rw-r--r--tests/ui/consts/const-eval/ptr_fragments_in_final.rs25
-rw-r--r--tests/ui/consts/const-eval/ptr_fragments_in_final.stderr10
-rw-r--r--tests/ui/consts/const-eval/read_partial_ptr.rs49
-rw-r--r--tests/ui/consts/const-eval/read_partial_ptr.stderr39
-rw-r--r--tests/ui/consts/missing_span_in_backtrace.rs13
-rw-r--r--tests/ui/consts/missing_span_in_backtrace.stderr16
11 files changed, 203 insertions, 42 deletions
diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr b/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr
index cb2bb1e8cd8..e5b108df298 100644
--- a/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr
+++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr
@@ -4,7 +4,7 @@ error: encountered `const_allocate` pointer in final value that was not made glo
 LL | const FOO: &i32 = foo();
    | ^^^^^^^^^^^^^^^
    |
-   = note: use `const_make_global` to make allocated pointers immutable before returning
+   = note: use `const_make_global` to turn allocated pointers into immutable globals before returning
 
 error: encountered `const_allocate` pointer in final value that was not made global
   --> $DIR/ptr_not_made_global.rs:12:1
@@ -12,7 +12,7 @@ error: encountered `const_allocate` pointer in final value that was not made glo
 LL | const FOO_RAW: *const i32 = foo();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: use `const_make_global` to make allocated pointers immutable before returning
+   = note: use `const_make_global` to turn allocated pointers into immutable globals before returning
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr
index 2445ce633d6..2d1993f96d3 100644
--- a/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr
+++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr
@@ -4,7 +4,7 @@ error: encountered `const_allocate` pointer in final value that was not made glo
 LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
    | ^^^^^^^^^^^^^^^^^^^
    |
-   = note: use `const_make_global` to make allocated pointers immutable before returning
+   = note: use `const_make_global` to turn allocated pointers into immutable globals before returning
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-eval/partial_ptr_overwrite.rs b/tests/ui/consts/const-eval/partial_ptr_overwrite.rs
deleted file mode 100644
index bd97bec0f71..00000000000
--- a/tests/ui/consts/const-eval/partial_ptr_overwrite.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Test for the behavior described in <https://github.com/rust-lang/rust/issues/87184>.
-
-const PARTIAL_OVERWRITE: () = {
-    let mut p = &42;
-    unsafe {
-        let ptr: *mut _ = &mut p;
-        *(ptr as *mut u8) = 123; //~ ERROR unable to overwrite parts of a pointer
-    }
-    let x = *p;
-};
-
-fn main() {}
diff --git a/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr b/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
deleted file mode 100644
index 6ef1cfd35c8..00000000000
--- a/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0080]: unable to overwrite parts of a pointer in memory at ALLOC0
-  --> $DIR/partial_ptr_overwrite.rs:7:9
-   |
-LL |         *(ptr as *mut u8) = 123;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PARTIAL_OVERWRITE` failed here
-   |
-   = help: this code performed an operation that depends on the underlying bytes representing a pointer
-   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ptr_fragments.rs b/tests/ui/consts/const-eval/ptr_fragments.rs
new file mode 100644
index 00000000000..04dcbe55590
--- /dev/null
+++ b/tests/ui/consts/const-eval/ptr_fragments.rs
@@ -0,0 +1,63 @@
+//! Test that various operations involving pointer fragments work as expected.
+//@ run-pass
+
+use std::mem::{self, MaybeUninit, transmute};
+use std::ptr;
+
+type Byte = MaybeUninit<u8>;
+
+const unsafe fn memcpy(dst: *mut Byte, src: *const Byte, n: usize) {
+    let mut i = 0;
+    while i < n {
+        *dst.add(i) = *src.add(i);
+        i += 1;
+    }
+}
+
+const _MEMCPY: () = unsafe {
+    let ptr = &42;
+    let mut ptr2 = ptr::null::<i32>();
+    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
+    assert!(*ptr2 == 42);
+};
+const _MEMCPY_OFFSET: () = unsafe {
+    // Same as above, but the pointer has a non-zero offset so not all the data bytes are the same.
+    let ptr = &(42, 18);
+    let ptr = &ptr.1;
+    let mut ptr2 = ptr::null::<i32>();
+    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
+    assert!(*ptr2 == 18);
+};
+
+const MEMCPY_RET: MaybeUninit<*const i32> = unsafe {
+    let ptr = &42;
+    let mut ptr2 = MaybeUninit::new(ptr::null::<i32>());
+    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
+    // Return in a MaybeUninit so it does not get treated as a scalar.
+    ptr2
+};
+
+#[allow(dead_code)]
+fn reassemble_ptr_fragments_in_static() {
+    static DATA: i32 = 1i32;
+
+    #[cfg(target_pointer_width = "64")]
+    struct Thing {
+        x: MaybeUninit<u32>,
+        y: MaybeUninit<u32>,
+    }
+    #[cfg(target_pointer_width = "32")]
+    struct Thing {
+        x: MaybeUninit<u16>,
+        y: MaybeUninit<u16>,
+    }
+
+    static X: Thing = unsafe {
+        let Thing { x, y } = transmute(&raw const DATA);
+        Thing { x, y }
+    };
+}
+
+fn main() {
+    assert_eq!(unsafe { MEMCPY_RET.assume_init().read() }, 42);
+}
diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs
new file mode 100644
index 00000000000..e2f3f51b086
--- /dev/null
+++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs
@@ -0,0 +1,25 @@
+//! Test that we properly error when there is a pointer fragment in the final value.
+
+use std::{mem::{self, MaybeUninit}, ptr};
+
+type Byte = MaybeUninit<u8>;
+
+const unsafe fn memcpy(dst: *mut Byte, src: *const Byte, n: usize) {
+    let mut i = 0;
+    while i < n {
+        dst.add(i).write(src.add(i).read());
+        i += 1;
+    }
+}
+
+const MEMCPY_RET: MaybeUninit<*const i32> = unsafe { //~ERROR: partial pointer in final value
+    let ptr = &42;
+    let mut ptr2 = MaybeUninit::new(ptr::null::<i32>());
+    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>() / 2);
+    // Return in a MaybeUninit so it does not get treated as a scalar.
+    ptr2
+};
+
+fn main() {
+    assert_eq!(unsafe { MEMCPY_RET.assume_init().read() }, 42);
+}
diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr
new file mode 100644
index 00000000000..628bf2566e5
--- /dev/null
+++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr
@@ -0,0 +1,10 @@
+error: encountered partial pointer in final value of constant
+  --> $DIR/ptr_fragments_in_final.rs:15:1
+   |
+LL | const MEMCPY_RET: MaybeUninit<*const i32> = unsafe {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/consts/const-eval/read_partial_ptr.rs b/tests/ui/consts/const-eval/read_partial_ptr.rs
new file mode 100644
index 00000000000..bccef9c0bc6
--- /dev/null
+++ b/tests/ui/consts/const-eval/read_partial_ptr.rs
@@ -0,0 +1,49 @@
+//! Ensure we error when trying to load from a pointer whose provenance has been messed with.
+
+const PARTIAL_OVERWRITE: () = {
+    let mut p = &42;
+    // Overwrite one byte with a no-provenance value.
+    unsafe {
+        let ptr: *mut _ = &mut p;
+        *(ptr as *mut u8) = 123;
+    }
+    let x = *p; //~ ERROR: unable to read parts of a pointer
+};
+
+const PTR_BYTES_SWAP: () = {
+    let mut p = &42;
+    // Swap the first two bytes.
+    unsafe {
+        let ptr = &mut p as *mut _ as *mut std::mem::MaybeUninit<u8>;
+        let byte0 = ptr.read();
+        let byte1 = ptr.add(1).read();
+        ptr.write(byte1);
+        ptr.add(1).write(byte0);
+    }
+    let x = *p; //~ ERROR: unable to read parts of a pointer
+};
+
+const PTR_BYTES_REPEAT: () = {
+    let mut p = &42;
+    // Duplicate the first byte over the second.
+    unsafe {
+        let ptr = &mut p as *mut _ as *mut std::mem::MaybeUninit<u8>;
+        let byte0 = ptr.read();
+        ptr.add(1).write(byte0);
+    }
+    let x = *p; //~ ERROR: unable to read parts of a pointer
+};
+
+const PTR_BYTES_MIX: () = {
+    let mut p = &42;
+    let q = &43;
+    // Overwrite the first byte of p with the first byte of q.
+    unsafe {
+        let ptr = &mut p as *mut _ as *mut std::mem::MaybeUninit<u8>;
+        let qtr = &q as *const _ as *const std::mem::MaybeUninit<u8>;
+        ptr.write(qtr.read());
+    }
+    let x = *p; //~ ERROR: unable to read parts of a pointer
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/read_partial_ptr.stderr b/tests/ui/consts/const-eval/read_partial_ptr.stderr
new file mode 100644
index 00000000000..196606c77a3
--- /dev/null
+++ b/tests/ui/consts/const-eval/read_partial_ptr.stderr
@@ -0,0 +1,39 @@
+error[E0080]: unable to read parts of a pointer from memory at ALLOC0
+  --> $DIR/read_partial_ptr.rs:10:13
+   |
+LL |     let x = *p;
+   |             ^^ evaluation of `PARTIAL_OVERWRITE` failed here
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: unable to read parts of a pointer from memory at ALLOC1
+  --> $DIR/read_partial_ptr.rs:23:13
+   |
+LL |     let x = *p;
+   |             ^^ evaluation of `PTR_BYTES_SWAP` failed here
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: unable to read parts of a pointer from memory at ALLOC2
+  --> $DIR/read_partial_ptr.rs:34:13
+   |
+LL |     let x = *p;
+   |             ^^ evaluation of `PTR_BYTES_REPEAT` failed here
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: unable to read parts of a pointer from memory at ALLOC3
+  --> $DIR/read_partial_ptr.rs:46:13
+   |
+LL |     let x = *p;
+   |             ^^ evaluation of `PTR_BYTES_MIX` failed here
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/missing_span_in_backtrace.rs b/tests/ui/consts/missing_span_in_backtrace.rs
index 4f3f9aa6ada..09a11c75fd7 100644
--- a/tests/ui/consts/missing_span_in_backtrace.rs
+++ b/tests/ui/consts/missing_span_in_backtrace.rs
@@ -1,3 +1,4 @@
+//! Check what happens when the error occurs inside a std function that we can't print the span of.
 //@ ignore-backends: gcc
 //@ compile-flags: -Z ui-testing=no
 
@@ -7,15 +8,15 @@ use std::{
 };
 
 const X: () = {
-    let mut ptr1 = &1;
-    let mut ptr2 = &2;
+    let mut x1 = 1;
+    let mut x2 = 2;
 
     // Swap them, bytewise.
     unsafe {
-        ptr::swap_nonoverlapping( //~ ERROR unable to copy parts of a pointer
-            &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
-            &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
-            mem::size_of::<&i32>(),
+        ptr::swap_nonoverlapping( //~ ERROR beyond the end of the allocation
+            &mut x1 as *mut _ as *mut MaybeUninit<u8>,
+            &mut x2 as *mut _ as *mut MaybeUninit<u8>,
+            10,
         );
     }
 };
diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr
index 0ac1e281107..55dde635828 100644
--- a/tests/ui/consts/missing_span_in_backtrace.stderr
+++ b/tests/ui/consts/missing_span_in_backtrace.stderr
@@ -1,15 +1,13 @@
-error[E0080]: unable to copy parts of a pointer from memory at ALLOC0
-  --> $DIR/missing_span_in_backtrace.rs:15:9
+error[E0080]: memory access failed: attempting to access 1 byte, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes
+  --> $DIR/missing_span_in_backtrace.rs:16:9
    |
-15 | /         ptr::swap_nonoverlapping(
-16 | |             &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
-17 | |             &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
-18 | |             mem::size_of::<&i32>(),
-19 | |         );
+16 | /         ptr::swap_nonoverlapping(
+17 | |             &mut x1 as *mut _ as *mut MaybeUninit<u8>,
+18 | |             &mut x2 as *mut _ as *mut MaybeUninit<u8>,
+19 | |             10,
+20 | |         );
    | |_________^ evaluation of `X` failed inside this call
    |
-   = help: this code performed an operation that depends on the underlying bytes representing a pointer
-   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 note: inside `swap_nonoverlapping::compiletime::<MaybeUninit<u8>>`
   --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
 note: inside `std::ptr::swap_nonoverlapping_const::<MaybeUninit<u8>>`