summaryrefslogtreecommitdiffstats
path: root/tests/ui/consts/const-eval/ub-nonnull.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/consts/const-eval/ub-nonnull.rs')
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs
new file mode 100644
index 000000000..a64b3a74c
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-nonnull.rs
@@ -0,0 +1,59 @@
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+#![feature(rustc_attrs, ptr_metadata)]
+#![allow(invalid_value)] // make sure we cannot allow away the errors tested here
+
+use std::mem;
+use std::ptr::NonNull;
+use std::num::{NonZeroU8, NonZeroUsize};
+
+const NON_NULL: NonNull<u8> = unsafe { mem::transmute(1usize) };
+const NON_NULL_PTR: NonNull<u8> = unsafe { mem::transmute(&1) };
+
+const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
+ let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+ // Use address-of-element for pointer arithmetic. This could wrap around to null!
+ let out_of_bounds_ptr = &ptr[255]; //~ ERROR evaluation of constant value failed
+ mem::transmute(out_of_bounds_ptr)
+} };
+
+const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+//~^ ERROR it is undefined behavior to use this value
+const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+// Also test other uses of rustc_layout_scalar_valid_range_start
+
+#[rustc_layout_scalar_valid_range_start(10)]
+#[rustc_layout_scalar_valid_range_end(30)]
+struct RestrictedRange1(u32);
+const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[rustc_layout_scalar_valid_range_start(30)]
+#[rustc_layout_scalar_valid_range_end(10)]
+struct RestrictedRange2(u32);
+const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+//~^ ERROR it is undefined behavior to use this value
+ let x: &dyn Send = &42;
+ let meta = std::ptr::metadata(x);
+ mem::transmute((0_usize, meta))
+};
+
+fn main() {}