From fa83763491bd388e131ee8456468727b2a95854e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 19 Nov 2022 23:36:20 +0100 Subject: [PATCH 01/11] always check alignment during CTFE --- .../src/const_eval/eval_queries.rs | 2 +- .../const-ptr/forbidden_slices.64bit.stderr | 58 ++++++++++--------- src/test/ui/const-ptr/forbidden_slices.rs | 2 - src/test/ui/consts/copy-intrinsic.rs | 1 + src/test/ui/consts/copy-intrinsic.stderr | 16 +++-- .../detect-extra-ub.no_flag.stderr | 24 ++++++++ .../consts/extra-const-ub/detect-extra-ub.rs | 1 - .../detect-extra-ub.with_flag.stderr | 12 ++-- 8 files changed, 75 insertions(+), 41 deletions(-) create mode 100644 src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 319f2b2c25ebf..4dfa42d15e035 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -311,7 +311,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( CompileTimeInterpreter::new( tcx.const_eval_limit(), /*can_access_statics:*/ is_static, - /*check_alignment:*/ tcx.sess.opts.unstable_opts.extra_const_ub_checks, + /*check_alignment:*/ true, ), ); diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr index 4e929e3525c20..d47e7233a53cb 100644 --- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr @@ -71,16 +71,18 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) ╾───────ALLOC_ID───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:32:1 +error[E0080]: could not evaluate static initializer + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | -LL | pub static S7: &[u16] = unsafe { - | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) + = note: accessing memory with alignment 1, but alignment 2 is required | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 16, align: 8) { - ╾─────ALLOC_ID+0x1─────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ - } +note: inside `std::slice::from_raw_parts::<'_, u16>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `S7` + --> $DIR/forbidden_slices.rs:35:5 + | +LL | from_raw_parts(ptr, 4) + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -90,7 +92,7 @@ error[E0080]: could not evaluate static initializer note: inside `std::slice::from_raw_parts::<'_, u64>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `S8` - --> $DIR/forbidden_slices.rs:43:5 + --> $DIR/forbidden_slices.rs:42:5 | LL | from_raw_parts(ptr, 1) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +107,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R0` - --> $DIR/forbidden_slices.rs:46:34 + --> $DIR/forbidden_slices.rs:45:34 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +122,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, ()>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R1` - --> $DIR/forbidden_slices.rs:47:33 + --> $DIR/forbidden_slices.rs:46:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,13 +138,13 @@ note: inside `ptr::const_ptr::::offset` note: inside `ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R2` - --> $DIR/forbidden_slices.rs:50:25 + --> $DIR/forbidden_slices.rs:49:25 | LL | from_ptr_range(ptr..ptr.add(2)) | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:52:1 + --> $DIR/forbidden_slices.rs:51:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized bytes @@ -153,7 +155,7 @@ LL | pub static R4: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:57:1 + --> $DIR/forbidden_slices.rs:56:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -165,7 +167,7 @@ LL | pub static R5: &[u8] = unsafe { } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:62:1 + --> $DIR/forbidden_slices.rs:61:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean @@ -175,16 +177,20 @@ LL | pub static R6: &[bool] = unsafe { ╾──────ALLOC_ID───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:67:1 +error[E0080]: could not evaluate static initializer + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | -LL | pub static R7: &[u16] = unsafe { - | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) + = note: accessing memory with alignment 1, but alignment 2 is required | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 16, align: 8) { - ╾────ALLOC_ID+0x1─────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ - } +note: inside `std::slice::from_raw_parts::<'_, u16>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `from_ptr_range::<'_, u16>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `R7` + --> $DIR/forbidden_slices.rs:68:5 + | +LL | from_ptr_range(ptr..ptr.add(4)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -196,7 +202,7 @@ note: inside `ptr::const_ptr::::offset` note: inside `ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R8` - --> $DIR/forbidden_slices.rs:74:25 + --> $DIR/forbidden_slices.rs:72:25 | LL | from_ptr_range(ptr..ptr.add(1)) | ^^^^^^^^^^ @@ -211,7 +217,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R9` - --> $DIR/forbidden_slices.rs:79:34 + --> $DIR/forbidden_slices.rs:77:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +232,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R10` - --> $DIR/forbidden_slices.rs:80:35 + --> $DIR/forbidden_slices.rs:78:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-ptr/forbidden_slices.rs b/src/test/ui/const-ptr/forbidden_slices.rs index e2184911f422c..eaf5ada12ff87 100644 --- a/src/test/ui/const-ptr/forbidden_slices.rs +++ b/src/test/ui/const-ptr/forbidden_slices.rs @@ -30,7 +30,6 @@ pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; / // Reading padding is not ok pub static S7: &[u16] = unsafe { - //~^ ERROR: it is undefined behavior to use this value let ptr = (&D2 as *const Struct as *const u16).byte_add(1); from_raw_parts(ptr, 4) @@ -65,7 +64,6 @@ pub static R6: &[bool] = unsafe { from_ptr_range(ptr..ptr.add(4)) }; pub static R7: &[u16] = unsafe { - //~^ ERROR: it is undefined behavior to use this value let ptr = (&D2 as *const Struct as *const u16).byte_add(1); from_ptr_range(ptr..ptr.add(4)) }; diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs index 249bbb5991cc9..d85f24d48970b 100644 --- a/src/test/ui/consts/copy-intrinsic.rs +++ b/src/test/ui/consts/copy-intrinsic.rs @@ -18,6 +18,7 @@ const COPY_ZERO: () = unsafe { let src = (); let mut dst = (); copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); + //~^ ERROR: evaluation of constant value failed }; const COPY_OOB_1: () = unsafe { diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr index be41c2db398be..acc4ada90ea12 100644 --- a/src/test/ui/consts/copy-intrinsic.stderr +++ b/src/test/ui/consts/copy-intrinsic.stderr @@ -1,27 +1,33 @@ error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:27:5 + --> $DIR/copy-intrinsic.rs:20:5 + | +LL | copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required + +error[E0080]: evaluation of constant value failed + --> $DIR/copy-intrinsic.rs:28:5 | LL | copy_nonoverlapping(0x100 as *const i32, dangle, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer at offset 40 is out-of-bounds error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:34:5 + --> $DIR/copy-intrinsic.rs:35:5 | LL | copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc7 has size 4, so pointer at offset 40 is out-of-bounds error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:41:5 + --> $DIR/copy-intrinsic.rs:42:5 | LL | copy(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy` error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:47:5 + --> $DIR/copy-intrinsic.rs:48:5 | LL | copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr new file mode 100644 index 0000000000000..3738dfd4a67eb --- /dev/null +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr @@ -0,0 +1,24 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: accessing memory with alignment 1, but alignment 4 is required + | +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `INNER` + --> $DIR/detect-extra-ub.rs:37:9 + | +LL | ptr.read(); + | ^^^^^^^^^^ + +note: erroneous constant used + --> $DIR/detect-extra-ub.rs:31:5 + | +LL | INNER; + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs index 9c239c8a100f9..c52adc31a64c8 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -1,5 +1,4 @@ // revisions: no_flag with_flag -// [no_flag] check-pass // [with_flag] compile-flags: -Zextra-const-ub-checks #![feature(const_ptr_read)] diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 51eec78336565..c721db459aaa4 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:9:20 + --> $DIR/detect-extra-ub.rs:8:20 | LL | let _x: bool = transmute(3u8); | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:15:21 + --> $DIR/detect-extra-ub.rs:14:21 | LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:21:30 + --> $DIR/detect-extra-ub.rs:20:30 | LL | let _x: (usize, usize) = transmute(x); | ^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -23,7 +23,7 @@ LL | let _x: (usize, usize) = transmute(x); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:26:20 + --> $DIR/detect-extra-ub.rs:25:20 | LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) @@ -38,13 +38,13 @@ note: inside `std::ptr::read::` note: inside `ptr::const_ptr::::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `INNER` - --> $DIR/detect-extra-ub.rs:38:9 + --> $DIR/detect-extra-ub.rs:37:9 | LL | ptr.read(); | ^^^^^^^^^^ note: erroneous constant used - --> $DIR/detect-extra-ub.rs:32:5 + --> $DIR/detect-extra-ub.rs:31:5 | LL | INNER; | ^^^^^ From a57582843186eb02b373a9eb98f7fd2b84961875 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 20 Nov 2022 09:54:45 +0100 Subject: [PATCH 02/11] adjust tests --- .../const-ptr/forbidden_slices.32bit.stderr | 50 +++++---- .../const-ptr/forbidden_slices.64bit.stderr | 60 +++++------ src/test/ui/const-ptr/forbidden_slices.rs | 11 +- .../consts/const-eval/ub-ref-ptr.32bit.stderr | 49 ++++++--- .../consts/const-eval/ub-ref-ptr.64bit.stderr | 49 ++++++--- src/test/ui/consts/const-eval/ub-ref-ptr.rs | 9 ++ .../const-eval/ub-wide-ptr.32bit.stderr | 100 +++++++++--------- .../const-eval/ub-wide-ptr.64bit.stderr | 100 +++++++++--------- src/test/ui/consts/const-eval/ub-wide-ptr.rs | 1 + src/test/ui/consts/copy-intrinsic.rs | 3 +- src/test/ui/consts/copy-intrinsic.stderr | 16 +-- .../detect-extra-ub.no_flag.stderr | 24 ----- .../consts/extra-const-ub/detect-extra-ub.rs | 12 +-- .../detect-extra-ub.with_flag.stderr | 31 +----- 14 files changed, 248 insertions(+), 267 deletions(-) delete mode 100644 src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr diff --git a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr index 3a58a7cd7ef05..0079bb3aad6df 100644 --- a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr @@ -27,7 +27,7 @@ LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - = note: dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + = note: dereferencing pointer failed: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds | note: inside `std::slice::from_raw_parts::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -45,7 +45,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) } | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─ALLOC_ID─╼ 01 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value @@ -57,7 +57,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size = 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: the raw bytes of the constant (size: 8, align: 4) { - ╾─ALLOC_ID─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value @@ -68,24 +68,24 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─ALLOC_ID─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value --> $DIR/forbidden_slices.rs:32:1 | LL | pub static S7: &[u16] = unsafe { - | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[1]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─A_ID+0x1─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID+0x2╼ 04 00 00 00 │ ╾──╼.... } error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - = note: dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + = note: dereferencing pointer failed: allocN has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | note: inside `std::slice::from_raw_parts::<'_, u64>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -129,7 +129,7 @@ LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + = note: out-of-bounds pointer arithmetic: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds | note: inside `ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -149,7 +149,7 @@ LL | pub static R4: &[u8] = unsafe { | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾ALLOC_ID─╼ 01 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value @@ -161,7 +161,7 @@ LL | pub static R5: &[u8] = unsafe { = 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: the raw bytes of the constant (size: 8, align: 4) { - ╾ALLOC_ID─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value @@ -172,31 +172,35 @@ LL | pub static R6: &[bool] = unsafe { | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾ALLOC_ID─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } -error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:67:1 +error[E0080]: could not evaluate static initializer + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | -LL | pub static R7: &[u16] = unsafe { - | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) + = note: accessing memory with alignment 1, but alignment 2 is required | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - ╾A_ID+0x1─╼ 04 00 00 00 │ ╾──╼.... - } +note: inside `std::slice::from_raw_parts::<'_, u16>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `from_ptr_range::<'_, u16>` + --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +note: inside `R7` + --> $DIR/forbidden_slices.rs:69:5 + | +LL | from_ptr_range(ptr..ptr.add(4)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + = note: out-of-bounds pointer arithmetic: allocN has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | note: inside `ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R8` - --> $DIR/forbidden_slices.rs:74:25 + --> $DIR/forbidden_slices.rs:73:25 | LL | from_ptr_range(ptr..ptr.add(1)) | ^^^^^^^^^^ @@ -211,7 +215,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R9` - --> $DIR/forbidden_slices.rs:79:34 + --> $DIR/forbidden_slices.rs:78:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +230,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R10` - --> $DIR/forbidden_slices.rs:80:35 + --> $DIR/forbidden_slices.rs:79:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr index d47e7233a53cb..f4f9fe69516a6 100644 --- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr @@ -27,7 +27,7 @@ LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) }; error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - = note: dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + = note: dereferencing pointer failed: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds | note: inside `std::slice::from_raw_parts::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -45,7 +45,7 @@ LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) } | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────ALLOC_ID───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value @@ -57,7 +57,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size = 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: the raw bytes of the constant (size: 16, align: 8) { - ╾───────ALLOC_ID───────╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value @@ -68,31 +68,29 @@ LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────ALLOC_ID───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -error[E0080]: could not evaluate static initializer - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL +error[E0080]: it is undefined behavior to use this value + --> $DIR/forbidden_slices.rs:32:1 | - = note: accessing memory with alignment 1, but alignment 2 is required +LL | pub static S7: &[u16] = unsafe { + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[1]: encountered uninitialized bytes | -note: inside `std::slice::from_raw_parts::<'_, u16>` - --> $SRC_DIR/core/src/slice/raw.rs:LL:COL -note: inside `S7` - --> $DIR/forbidden_slices.rs:35:5 - | -LL | from_raw_parts(ptr, 4) - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾ALLOC_ID+0x2╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ + } error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/slice/raw.rs:LL:COL | - = note: dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + = note: dereferencing pointer failed: allocN has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | note: inside `std::slice::from_raw_parts::<'_, u64>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `S8` - --> $DIR/forbidden_slices.rs:42:5 + --> $DIR/forbidden_slices.rs:43:5 | LL | from_raw_parts(ptr, 1) | ^^^^^^^^^^^^^^^^^^^^^^ @@ -107,7 +105,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R0` - --> $DIR/forbidden_slices.rs:45:34 + --> $DIR/forbidden_slices.rs:46:34 | LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +120,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, ()>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R1` - --> $DIR/forbidden_slices.rs:46:33 + --> $DIR/forbidden_slices.rs:47:33 | LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,31 +129,31 @@ LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) }; error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + = note: out-of-bounds pointer arithmetic: allocN has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds | note: inside `ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R2` - --> $DIR/forbidden_slices.rs:49:25 + --> $DIR/forbidden_slices.rs:50:25 | LL | from_ptr_range(ptr..ptr.add(2)) | ^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:51:1 + --> $DIR/forbidden_slices.rs:52:1 | LL | pub static R4: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────ALLOC_ID───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:56:1 + --> $DIR/forbidden_slices.rs:57:1 | LL | pub static R5: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -163,18 +161,18 @@ LL | pub static R5: &[u8] = unsafe { = 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: the raw bytes of the constant (size: 16, align: 8) { - ╾──────ALLOC_ID───────╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/forbidden_slices.rs:61:1 + --> $DIR/forbidden_slices.rs:62:1 | LL | pub static R6: &[bool] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x11, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────ALLOC_ID───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: could not evaluate static initializer @@ -187,7 +185,7 @@ note: inside `std::slice::from_raw_parts::<'_, u16>` note: inside `from_ptr_range::<'_, u16>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R7` - --> $DIR/forbidden_slices.rs:68:5 + --> $DIR/forbidden_slices.rs:69:5 | LL | from_ptr_range(ptr..ptr.add(4)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -195,14 +193,14 @@ LL | from_ptr_range(ptr..ptr.add(4)) error[E0080]: could not evaluate static initializer --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | - = note: out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds + = note: out-of-bounds pointer arithmetic: allocN has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds | note: inside `ptr::const_ptr::::offset` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `ptr::const_ptr::::add` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `R8` - --> $DIR/forbidden_slices.rs:72:25 + --> $DIR/forbidden_slices.rs:73:25 | LL | from_ptr_range(ptr..ptr.add(1)) | ^^^^^^^^^^ @@ -217,7 +215,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R9` - --> $DIR/forbidden_slices.rs:77:34 + --> $DIR/forbidden_slices.rs:78:34 | LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +230,7 @@ note: inside `ptr::const_ptr::::sub_ptr` note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL note: inside `R10` - --> $DIR/forbidden_slices.rs:78:35 + --> $DIR/forbidden_slices.rs:79:35 | LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-ptr/forbidden_slices.rs b/src/test/ui/const-ptr/forbidden_slices.rs index eaf5ada12ff87..cc6100226dc1c 100644 --- a/src/test/ui/const-ptr/forbidden_slices.rs +++ b/src/test/ui/const-ptr/forbidden_slices.rs @@ -1,6 +1,6 @@ // stderr-per-bitwidth -// normalize-stderr-test "alloc[0-9]+" -> "ALLOC_ID" -// normalize-stderr-test "a[0-9]+\+0x" -> "A_ID+0x" +// normalize-stderr-test "╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼" -> "╾ALLOC_ID$2╼" +// normalize-stderr-test "alloc\d+" -> "allocN" // error-pattern: could not evaluate static initializer #![feature( slice_from_ptr_range, @@ -30,7 +30,8 @@ pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; / // Reading padding is not ok pub static S7: &[u16] = unsafe { - let ptr = (&D2 as *const Struct as *const u16).byte_add(1); + //~^ ERROR: it is undefined behavior to use this value + let ptr = (&D2 as *const Struct as *const u16).add(1); from_raw_parts(ptr, 4) }; @@ -65,11 +66,11 @@ pub static R6: &[bool] = unsafe { }; pub static R7: &[u16] = unsafe { let ptr = (&D2 as *const Struct as *const u16).byte_add(1); - from_ptr_range(ptr..ptr.add(4)) + from_ptr_range(ptr..ptr.add(4)) //~ inside `R7` }; pub static R8: &[u64] = unsafe { let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::(); - from_ptr_range(ptr..ptr.add(1)) + from_ptr_range(ptr..ptr.add(1)) //~ inside `R8` }; // This is sneaky: &D0 and &D0 point to different objects diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index e5b5c7a846c11..b4c343e64d5e4 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:13:1 + --> $DIR/ub-ref-ptr.rs:14:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:17:1 + --> $DIR/ub-ref-ptr.rs:18:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:21:1 + --> $DIR/ub-ref-ptr.rs:22:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:24:1 + --> $DIR/ub-ref-ptr.rs:25:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:31:1 + --> $DIR/ub-ref-ptr.rs:32:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:34:39 + --> $DIR/ub-ref-ptr.rs:35:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:34:38 + --> $DIR/ub-ref-ptr.rs:35:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:37:86 + --> $DIR/ub-ref-ptr.rs:38:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:37:85 + --> $DIR/ub-ref-ptr.rs:38:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:40:1 + --> $DIR/ub-ref-ptr.rs:41:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:43:1 + --> $DIR/ub-ref-ptr.rs:44:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:46:41 + --> $DIR/ub-ref-ptr.rs:47:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:50:1 + --> $DIR/ub-ref-ptr.rs:51:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:52:38 + --> $DIR/ub-ref-ptr.rs:53:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:55:1 + --> $DIR/ub-ref-ptr.rs:56:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:58:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer @@ -148,6 +148,21 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾─alloc41─╼ │ ╾──╼ } -error: aborting due to 14 previous errors +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: accessing memory with alignment 1, but alignment 4 is required + | +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 + | +LL | ptr.read(); + | ^^^^^^^^^^ + +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 607366cabc4e9..012e050de8476 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:13:1 + --> $DIR/ub-ref-ptr.rs:14:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:17:1 + --> $DIR/ub-ref-ptr.rs:18:1 | LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:21:1 + --> $DIR/ub-ref-ptr.rs:22:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:24:1 + --> $DIR/ub-ref-ptr.rs:25:1 | LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:31:1 + --> $DIR/ub-ref-ptr.rs:32:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:34:39 + --> $DIR/ub-ref-ptr.rs:35:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:34:38 + --> $DIR/ub-ref-ptr.rs:35:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:37:86 + --> $DIR/ub-ref-ptr.rs:38:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:37:85 + --> $DIR/ub-ref-ptr.rs:38:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:40:1 + --> $DIR/ub-ref-ptr.rs:41:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:43:1 + --> $DIR/ub-ref-ptr.rs:44:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:46:41 + --> $DIR/ub-ref-ptr.rs:47:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:50:1 + --> $DIR/ub-ref-ptr.rs:51:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:52:38 + --> $DIR/ub-ref-ptr.rs:53:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:55:1 + --> $DIR/ub-ref-ptr.rs:56:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:58:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer @@ -148,6 +148,21 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾───────alloc41───────╼ │ ╾──────╼ } -error: aborting due to 14 previous errors +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: accessing memory with alignment 1, but alignment 4 is required + | +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 + | +LL | ptr.read(); + | ^^^^^^^^^^ + +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.rs b/src/test/ui/consts/const-eval/ub-ref-ptr.rs index a1c81239009ac..b0fc3c196a49f 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength // stderr-per-bitwidth #![allow(invalid_value)] +#![feature(const_ptr_read)] use std::mem; @@ -57,4 +58,12 @@ const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; //~^ ERROR it is undefined behavior to use this value + +const UNALIGNED_READ: () = unsafe { + let x = &[0u8; 4]; + let ptr = x.as_ptr().cast::(); + ptr.read(); //~ inside `UNALIGNED_READ` +}; + + fn main() {} diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index 9994c2e5a8345..90a3dcada058d 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -1,27 +1,27 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:36:1 + --> $DIR/ub-wide-ptr.rs:37:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN──╼ e7 03 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:38:1 + --> $DIR/ub-wide-ptr.rs:39:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ ff ff ff ff │ ╾──╼.... + ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼.... } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:41:1 + --> $DIR/ub-wide-ptr.rs:42:1 | LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -30,7 +30,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:44:1 + --> $DIR/ub-wide-ptr.rs:45:1 | LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -39,68 +39,68 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:46:1 + --> $DIR/ub-wide-ptr.rs:47:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ ff ff ff ff │ ╾──╼.... + ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:50:1 + --> $DIR/ub-wide-ptr.rs:51:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized data in `str` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ 01 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:53:1 + --> $DIR/ub-wide-ptr.rs:54:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized data in `str` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ 01 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼.... } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:60:1 + --> $DIR/ub-wide-ptr.rs:61:1 | LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:67:1 + --> $DIR/ub-wide-ptr.rs:68:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ e7 03 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:70:1 + --> $DIR/ub-wide-ptr.rs:71:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ ff ff ff 7f │ ╾──╼.... + ╾ALLOC_ID╼ ff ff ff 7f │ ╾──╼.... } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:73:1 + --> $DIR/ub-wide-ptr.rs:74:1 | LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -109,18 +109,18 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:76:1 + --> $DIR/ub-wide-ptr.rs:77:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾─allocN─╼ e7 03 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼.... } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:79:1 + --> $DIR/ub-wide-ptr.rs:80:1 | LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -129,165 +129,165 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:83:1 + --> $DIR/ub-wide-ptr.rs:84:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾─allocN─╼ │ ╾──╼ + ╾ALLOC_ID╼ │ ╾──╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:83:40 + --> $DIR/ub-wide-ptr.rs:84:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:90:1 + --> $DIR/ub-wide-ptr.rs:91:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾allocN─╼ │ ╾──╼ + ╾ALLOC_ID╼ │ ╾──╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:90:42 + --> $DIR/ub-wide-ptr.rs:91:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:94:1 + --> $DIR/ub-wide-ptr.rs:95:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..1[0]: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { - ╾allocN─╼ │ ╾──╼ + ╾ALLOC_ID╼ │ ╾──╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:94:42 + --> $DIR/ub-wide-ptr.rs:95:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:102:1 + --> $DIR/ub-wide-ptr.rs:103:1 | LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:111:1 + --> $DIR/ub-wide-ptr.rs:112:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:115:1 + --> $DIR/ub-wide-ptr.rs:116:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:119:1 + --> $DIR/ub-wide-ptr.rs:120:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ 04 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼.... } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:122:57 + --> $DIR/ub-wide-ptr.rs:123:57 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:125:57 + --> $DIR/ub-wide-ptr.rs:126:57 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:128:56 + --> $DIR/ub-wide-ptr.rs:129:56 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:131:1 + --> $DIR/ub-wide-ptr.rs:132:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:136:1 + --> $DIR/ub-wide-ptr.rs:137:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:141:1 + --> $DIR/ub-wide-ptr.rs:142:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ 00 00 00 00 │ ╾──╼.... + ╾ALLOC_ID╼ 00 00 00 00 │ ╾──╼.... } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:143:1 + --> $DIR/ub-wide-ptr.rs:144:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 4) { - ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼ } error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:149:5 + --> $DIR/ub-wide-ptr.rs:150:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:153:5 + --> $DIR/ub-wide-ptr.rs:154:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 06a377d9f7c97..ab25303ddc0cf 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -1,27 +1,27 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:36:1 + --> $DIR/ub-wide-ptr.rs:37:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN────────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:38:1 + --> $DIR/ub-wide-ptr.rs:39:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ + ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:41:1 + --> $DIR/ub-wide-ptr.rs:42:1 | LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -30,7 +30,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:44:1 + --> $DIR/ub-wide-ptr.rs:45:1 | LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -39,68 +39,68 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:46:1 + --> $DIR/ub-wide-ptr.rs:47:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ + ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:50:1 + --> $DIR/ub-wide-ptr.rs:51:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized data in `str` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:53:1 + --> $DIR/ub-wide-ptr.rs:54:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized data in `str` | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:60:1 + --> $DIR/ub-wide-ptr.rs:61:1 | LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:67:1 + --> $DIR/ub-wide-ptr.rs:68:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:70:1 + --> $DIR/ub-wide-ptr.rs:71:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........ + ╾ALLOC_ID╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........ } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:73:1 + --> $DIR/ub-wide-ptr.rs:74:1 | LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -109,18 +109,18 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:76:1 + --> $DIR/ub-wide-ptr.rs:77:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾───────allocN───────╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:79:1 + --> $DIR/ub-wide-ptr.rs:80:1 | LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -129,165 +129,165 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:83:1 + --> $DIR/ub-wide-ptr.rs:84:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .[0]: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾───────allocN───────╼ │ ╾──────╼ + ╾ALLOC_ID╼ │ ╾──────╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:83:40 + --> $DIR/ub-wide-ptr.rs:84:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:90:1 + --> $DIR/ub-wide-ptr.rs:91:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾──────allocN───────╼ │ ╾──────╼ + ╾ALLOC_ID╼ │ ╾──────╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:90:42 + --> $DIR/ub-wide-ptr.rs:91:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:94:1 + --> $DIR/ub-wide-ptr.rs:95:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..1[0]: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 8, align: 8) { - ╾──────allocN───────╼ │ ╾──────╼ + ╾ALLOC_ID╼ │ ╾──────╼ } note: erroneous constant used - --> $DIR/ub-wide-ptr.rs:94:42 + --> $DIR/ub-wide-ptr.rs:95:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:102:1 + --> $DIR/ub-wide-ptr.rs:103:1 | LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:111:1 + --> $DIR/ub-wide-ptr.rs:112:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:115:1 + --> $DIR/ub-wide-ptr.rs:116:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:119:1 + --> $DIR/ub-wide-ptr.rs:120:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:122:57 + --> $DIR/ub-wide-ptr.rs:123:57 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:125:57 + --> $DIR/ub-wide-ptr.rs:126:57 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:128:56 + --> $DIR/ub-wide-ptr.rs:129:56 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:131:1 + --> $DIR/ub-wide-ptr.rs:132:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:136:1 + --> $DIR/ub-wide-ptr.rs:137:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..: encountered 0x03, but expected a boolean | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:141:1 + --> $DIR/ub-wide-ptr.rs:142:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........ + ╾ALLOC_ID╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........ } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-wide-ptr.rs:143:1 + --> $DIR/ub-wide-ptr.rs:144:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { - ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼ } error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:149:5 + --> $DIR/ub-wide-ptr.rs:150:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:153:5 + --> $DIR/ub-wide-ptr.rs:154:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs index 2894ef831884c..d12e5e2bed93e 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs @@ -4,6 +4,7 @@ use std::mem; +// normalize-stderr-test "╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼" -> "╾ALLOC_ID$2╼" // normalize-stderr-test "offset \d+" -> "offset N" // normalize-stderr-test "alloc\d+" -> "allocN" // normalize-stderr-test "size \d+" -> "size N" diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs index d85f24d48970b..94d7bdc6bae9f 100644 --- a/src/test/ui/consts/copy-intrinsic.rs +++ b/src/test/ui/consts/copy-intrinsic.rs @@ -17,8 +17,7 @@ const COPY_ZERO: () = unsafe { // Since we are not copying anything, this should be allowed. let src = (); let mut dst = (); - copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); - //~^ ERROR: evaluation of constant value failed + copy_nonoverlapping(&src as *const _ as *const u8, &mut dst as *mut _ as *mut u8, 0); }; const COPY_OOB_1: () = unsafe { diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr index acc4ada90ea12..be41c2db398be 100644 --- a/src/test/ui/consts/copy-intrinsic.stderr +++ b/src/test/ui/consts/copy-intrinsic.stderr @@ -1,33 +1,27 @@ error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:20:5 - | -LL | copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required - -error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:28:5 + --> $DIR/copy-intrinsic.rs:27:5 | LL | copy_nonoverlapping(0x100 as *const i32, dangle, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer at offset 40 is out-of-bounds error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:35:5 + --> $DIR/copy-intrinsic.rs:34:5 | LL | copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc7 has size 4, so pointer at offset 40 is out-of-bounds error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:42:5 + --> $DIR/copy-intrinsic.rs:41:5 | LL | copy(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy` error[E0080]: evaluation of constant value failed - --> $DIR/copy-intrinsic.rs:48:5 + --> $DIR/copy-intrinsic.rs:47:5 | LL | copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::() * 8 - 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr deleted file mode 100644 index 3738dfd4a67eb..0000000000000 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.no_flag.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: accessing memory with alignment 1, but alignment 4 is required - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `INNER` - --> $DIR/detect-extra-ub.rs:37:9 - | -LL | ptr.read(); - | ^^^^^^^^^^ - -note: erroneous constant used - --> $DIR/detect-extra-ub.rs:31:5 - | -LL | INNER; - | ^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs index c52adc31a64c8..e2f8149883b1d 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -1,4 +1,5 @@ // revisions: no_flag with_flag +// [no_flag] check-pass // [with_flag] compile-flags: -Zextra-const-ub-checks #![feature(const_ptr_read)] @@ -27,15 +28,4 @@ const UNALIGNED_PTR: () = unsafe { //[with_flag]~| invalid value }; -const UNALIGNED_READ: () = { - INNER; //[with_flag]~ constant - // There is an error here but its span is in the standard library so we cannot match it... - // so we have this in a *nested* const, such that the *outer* const fails to use it. - const INNER: () = unsafe { - let x = &[0u8; 4]; - let ptr = x.as_ptr().cast::(); - ptr.read(); - }; -}; - fn main() {} diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index c721db459aaa4..b2a5fd90149a3 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:8:20 + --> $DIR/detect-extra-ub.rs:9:20 | LL | let _x: bool = transmute(3u8); | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:14:21 + --> $DIR/detect-extra-ub.rs:15:21 | LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:20:30 + --> $DIR/detect-extra-ub.rs:21:30 | LL | let _x: (usize, usize) = transmute(x); | ^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -23,32 +23,11 @@ LL | let _x: (usize, usize) = transmute(x); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:25:20 + --> $DIR/detect-extra-ub.rs:26:20 | LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: accessing memory with alignment 1, but alignment 4 is required - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `ptr::const_ptr::::read` - --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `INNER` - --> $DIR/detect-extra-ub.rs:37:9 - | -LL | ptr.read(); - | ^^^^^^^^^^ - -note: erroneous constant used - --> $DIR/detect-extra-ub.rs:31:5 - | -LL | INNER; - | ^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. From ed71e32e1440765d3e133e9892d59ca130477cec Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 14:56:12 +0000 Subject: [PATCH 03/11] Always pass alignment and handle checking lazily --- .../rustc_const_eval/src/interpret/memory.rs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 528c1cb06c0eb..b8feb7feda398 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -349,11 +349,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size: Size, align: Align, ) -> InterpResult<'tcx, Option<(AllocId, Size, M::ProvenanceExtra)>> { - let align = M::enforce_alignment(&self).then_some(align); self.check_and_deref_ptr( ptr, size, align, + M::enforce_alignment(self), CheckInAllocMsg::MemoryAccessTest, |alloc_id, offset, prov| { let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?; @@ -373,10 +373,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { align: Align, msg: CheckInAllocMsg, ) -> InterpResult<'tcx> { - self.check_and_deref_ptr(ptr, size, Some(align), msg, |alloc_id, _, _| { - let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?; - Ok((size, align, ())) - })?; + self.check_and_deref_ptr( + ptr, + size, + align, + /* force_alignment_check */ true, + msg, + |alloc_id, _, _| { + let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?; + Ok((size, align, ())) + }, + )?; Ok(()) } @@ -388,7 +395,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, ptr: Pointer>, size: Size, - align: Option, + align: Align, + force_alignment_check: bool, msg: CheckInAllocMsg, alloc_size: impl FnOnce( AllocId, @@ -417,7 +425,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub!(DanglingIntPointer(addr, msg)); } // Must be aligned. - if let Some(align) = align { + if force_alignment_check { check_offset_align(addr, align)?; } None @@ -441,7 +449,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. - if let Some(align) = align { + if force_alignment_check { if M::use_addr_for_alignment_check(self) { // `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true. check_offset_align(ptr.addr().bytes(), align)?; @@ -560,11 +568,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size: Size, align: Align, ) -> InterpResult<'tcx, Option>> { - let align = M::enforce_alignment(self).then_some(align); let ptr_and_alloc = self.check_and_deref_ptr( ptr, size, align, + M::enforce_alignment(self), CheckInAllocMsg::MemoryAccessTest, |alloc_id, offset, prov| { let alloc = self.get_alloc_raw(alloc_id)?; From d66824dbc4fb74598251a89d7c3c5fb2df5afeba Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 16:51:16 +0000 Subject: [PATCH 04/11] Make alignment checks a future incompat lint --- .../src/const_eval/eval_queries.rs | 15 ++-- .../src/const_eval/machine.rs | 26 +++++- .../src/interpret/eval_context.rs | 16 ++-- .../rustc_const_eval/src/interpret/machine.rs | 4 +- .../rustc_const_eval/src/interpret/memory.rs | 83 ++++++++++++++----- .../rustc_const_eval/src/interpret/place.rs | 9 +- .../src/util/might_permit_raw_init.rs | 4 +- compiler/rustc_lint_defs/src/builtin.rs | 36 ++++++++ .../rustc_mir_transform/src/const_prop.rs | 5 +- .../src/dataflow_const_prop.rs | 3 +- .../consts/const-eval/ub-ref-ptr.32bit.stderr | 20 +++-- .../consts/const-eval/ub-ref-ptr.64bit.stderr | 20 +++-- src/tools/miri/src/machine.rs | 9 +- 13 files changed, 180 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 4dfa42d15e035..18e01567ca35e 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,3 +1,4 @@ +use crate::const_eval::CheckAlignment; use std::borrow::Cow; use either::{Left, Right}; @@ -76,7 +77,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( None => InternKind::Constant, } }; - ecx.machine.check_alignment = false; // interning doesn't need to respect alignment + ecx.machine.check_alignment = CheckAlignment::No; // interning doesn't need to respect alignment intern_const_alloc_recursive(ecx, intern_kind, &ret)?; // we leave alignment checks off, since this `ecx` will not be used for further evaluation anyway @@ -102,11 +103,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>( tcx, root_span, param_env, - CompileTimeInterpreter::new( - tcx.const_eval_limit(), - can_access_statics, - /*check_alignment:*/ false, - ), + CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics, CheckAlignment::No), ) } @@ -311,7 +308,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>( CompileTimeInterpreter::new( tcx.const_eval_limit(), /*can_access_statics:*/ is_static, - /*check_alignment:*/ true, + if tcx.sess.opts.unstable_opts.extra_const_ub_checks { + CheckAlignment::Error + } else { + CheckAlignment::FutureIncompat + }, ), ); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 3dfded2d930a0..355ad66929629 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -47,14 +47,34 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { pub(super) can_access_statics: bool, /// Whether to check alignment during evaluation. - pub(super) check_alignment: bool, + pub(super) check_alignment: CheckAlignment, +} + +#[derive(Copy, Clone)] +pub enum CheckAlignment { + /// Ignore alignment when following relocations. + /// This is mainly used in interning. + No, + /// Hard error when dereferencing a misaligned pointer. + Error, + /// Emit a future incompat lint when dereferencing a misaligned pointer. + FutureIncompat, +} + +impl CheckAlignment { + pub fn should_check(&self) -> bool { + match self { + CheckAlignment::No => false, + CheckAlignment::Error | CheckAlignment::FutureIncompat => true, + } + } } impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { pub(crate) fn new( const_eval_limit: Limit, can_access_statics: bool, - check_alignment: bool, + check_alignment: CheckAlignment, ) -> Self { CompileTimeInterpreter { steps_remaining: const_eval_limit.0, @@ -309,7 +329,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error #[inline(always)] - fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { ecx.machine.check_alignment } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0b2809f1d2c28..f551b5c29114d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -248,6 +248,15 @@ impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> { Right(span) => span, } } + + pub fn lint_root(&self) -> Option { + self.current_source_info().and_then(|source_info| { + match &self.body.source_scopes[source_info.scope].local_data { + mir::ClearCrossCrate::Set(data) => Some(data.lint_root), + mir::ClearCrossCrate::Clear => None, + } + }) + } } impl<'tcx> fmt::Display for FrameInfo<'tcx> { @@ -954,12 +963,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // This deliberately does *not* honor `requires_caller_location` since it is used for much // more than just panics. for frame in stack.iter().rev() { - let lint_root = frame.current_source_info().and_then(|source_info| { - match &frame.body.source_scopes[source_info.scope].local_data { - mir::ClearCrossCrate::Set(data) => Some(data.lint_root), - mir::ClearCrossCrate::Clear => None, - } - }); + let lint_root = frame.lint_root(); let span = frame.current_span(); frames.push(FrameInfo { span, instance: frame.instance, lint_root }); diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 0604d5ee6fa4c..f52545317ea1a 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -13,6 +13,8 @@ use rustc_span::def_id::DefId; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi as CallAbi; +use crate::const_eval::CheckAlignment; + use super::{ AllocId, AllocRange, Allocation, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Provenance, Scalar, StackPopUnwind, @@ -122,7 +124,7 @@ pub trait Machine<'mir, 'tcx>: Sized { const PANIC_ON_ALLOC_FAIL: bool; /// Whether memory accesses should be alignment-checked. - fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment; /// Whether, when checking alignment, we should look at the actual address and thus support /// custom alignment logic based on whatever the integer address happens to be. diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index b8feb7feda398..ffd5e05bcc40a 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -14,10 +14,15 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::display_allocation; +use rustc_middle::mir::interpret::UndefinedBehaviorInfo; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; +use rustc_session::lint::builtin::INVALID_ALIGNMENT; use rustc_target::abi::{Align, HasDataLayout, Size}; +use crate::const_eval::CheckAlignment; + use super::{ alloc_range, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Provenance, Scalar, @@ -377,7 +382,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ptr, size, align, - /* force_alignment_check */ true, + CheckAlignment::Error, msg, |alloc_id, _, _| { let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?; @@ -396,7 +401,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ptr: Pointer>, size: Size, align: Align, - force_alignment_check: bool, + check: CheckAlignment, msg: CheckInAllocMsg, alloc_size: impl FnOnce( AllocId, @@ -404,19 +409,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { M::ProvenanceExtra, ) -> InterpResult<'tcx, (Size, Align, T)>, ) -> InterpResult<'tcx, Option> { - fn check_offset_align<'tcx>(offset: u64, align: Align) -> InterpResult<'tcx> { - if offset % align.bytes() == 0 { - Ok(()) - } else { - // The biggest power of two through which `offset` is divisible. - let offset_pow2 = 1 << offset.trailing_zeros(); - throw_ub!(AlignmentCheckFailed { - has: Align::from_bytes(offset_pow2).unwrap(), - required: align, - }) - } - } - Ok(match self.ptr_try_get_alloc_id(ptr) { Err(addr) => { // We couldn't get a proper allocation. This is only okay if the access size is 0, @@ -425,8 +417,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub!(DanglingIntPointer(addr, msg)); } // Must be aligned. - if force_alignment_check { - check_offset_align(addr, align)?; + if check.should_check() { + self.check_offset_align(addr, align, check)?; } None } @@ -449,16 +441,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Test align. Check this last; if both bounds and alignment are violated // we want the error to be about the bounds. - if force_alignment_check { + if check.should_check() { if M::use_addr_for_alignment_check(self) { // `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true. - check_offset_align(ptr.addr().bytes(), align)?; + self.check_offset_align(ptr.addr().bytes(), align, check)?; } else { // Check allocation alignment and offset alignment. if alloc_align.bytes() < align.bytes() { - throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align }); + self.alignment_check_failed(alloc_align, align, check)?; } - check_offset_align(offset.bytes(), align)?; + self.check_offset_align(offset.bytes(), align, check)?; } } @@ -468,6 +460,55 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } }) } + + fn check_offset_align( + &self, + offset: u64, + align: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx> { + if offset % align.bytes() == 0 { + Ok(()) + } else { + // The biggest power of two through which `offset` is divisible. + let offset_pow2 = 1 << offset.trailing_zeros(); + self.alignment_check_failed(Align::from_bytes(offset_pow2).unwrap(), align, check) + } + } + + fn alignment_check_failed( + &self, + has: Align, + required: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + match check { + CheckAlignment::Error => { + throw_ub!(AlignmentCheckFailed { has, required }) + } + CheckAlignment::No => span_bug!( + self.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ), + CheckAlignment::FutureIncompat => self.tcx.struct_span_lint_hir( + INVALID_ALIGNMENT, + self.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), + self.cur_span(), + UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), + |db| { + let mut stacktrace = self.generate_stacktrace(); + // Filter out `requires_caller_location` frames. + stacktrace + .retain(|frame| !frame.instance.def.requires_caller_location(*self.tcx)); + for frame in stacktrace { + db.span_label(frame.span, format!("inside `{}`", frame.instance)); + } + db + }, + ), + } + Ok(()) + } } /// Allocation accessors diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index c47cfe8bb69fd..905eb71bb18ed 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -364,13 +364,8 @@ where .size_and_align_of_mplace(&mplace)? .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); assert!(mplace.align <= align, "dynamic alignment less strict than static one?"); - let align = M::enforce_alignment(self).then_some(align); - self.check_ptr_access_align( - mplace.ptr, - size, - align.unwrap_or(Align::ONE), - CheckInAllocMsg::DerefTest, - )?; + let align = if M::enforce_alignment(self).should_check() { align } else { Align::ONE }; + self.check_ptr_access_align(mplace.ptr, size, align, CheckInAllocMsg::DerefTest)?; Ok(()) } diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs index 6ca71223391d2..4ce107ea68d4f 100644 --- a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs +++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_session::Limit; use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants}; -use crate::const_eval::CompileTimeInterpreter; +use crate::const_eval::{CheckAlignment, CompileTimeInterpreter}; use crate::interpret::{InterpCx, MemoryKind, OpTy}; /// Determines if this type permits "raw" initialization by just transmuting some memory into an @@ -41,7 +41,7 @@ fn might_permit_raw_init_strict<'tcx>( let machine = CompileTimeInterpreter::new( Limit::new(0), /*can_access_statics:*/ false, - /*check_alignment:*/ true, + CheckAlignment::Error, ); let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a3008e9e321c8..dddc200b2fb1a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1019,6 +1019,42 @@ declare_lint! { }; } +declare_lint! { + /// The `invalid_alignment` lint detects dereferences of misaligned pointers during + /// constant evluation. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// const FOO: () = unsafe { + /// let x = [0_u8; 10]; + /// let y = x.as_ptr() as *const u32; + /// *y; // the address of a `u8` array is unknown and thus we don't know if + /// // it is aligned enough for reading a `u32`. + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The compiler allowed dereferencing raw pointers irrespective of alignment + /// during const eval due to the const evaluator at the time not making it easy + /// or cheap to check. Now that it is both, this is not accepted anymore. + /// + /// Since it was undefined behaviour to begin with, this breakage does not violate + /// Rust's stability guarantees. Using undefined behaviour can cause arbitrary + /// behaviour, including failure to build. + /// + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub INVALID_ALIGNMENT, + Deny, + "raw pointers must be aligned before dereferencing", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #68585 ", + }; +} + declare_lint! { /// The `exported_private_dependencies` lint detects private dependencies /// that are exposed in a public interface. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index b0514e033566c..c8ba6310d590b 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -6,6 +6,7 @@ use std::cell::Cell; use either::Right; use rustc_ast::Mutability; +use rustc_const_eval::const_eval::CheckAlignment; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; @@ -186,10 +187,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> type MemoryKind = !; #[inline(always)] - fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { // We do not check for alignment to avoid having to carry an `Align` // in `ConstValue::ByRef`. - false + CheckAlignment::No } #[inline(always)] diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index e9027387413cf..37675426f1916 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -2,6 +2,7 @@ //! //! Currently, this pass only propagates scalar values. +use rustc_const_eval::const_eval::CheckAlignment; use rustc_const_eval::interpret::{ConstValue, ImmTy, Immediate, InterpCx, Scalar}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::visit::{MutVisitor, Visitor}; @@ -448,7 +449,7 @@ impl<'mir, 'tcx> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachi type MemoryKind = !; const PANIC_ON_ALLOC_FAIL: bool = true; - fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { unimplemented!() } diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index b4c343e64d5e4..8cd3918c0b407 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -148,20 +148,22 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾─alloc41─╼ │ ╾──╼ } -error[E0080]: evaluation of constant value failed +error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: accessing memory with alignment 1, but alignment 4 is required - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `ptr::const_ptr::::read` + = note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNALIGNED_READ` - --> $DIR/ub-ref-ptr.rs:65:5 + | + = note: inside `ptr::const_ptr::::read` + | + ::: $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ^^^^^^^^^^ + | ---------- inside `UNALIGNED_READ` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(invalid_alignment)]` on by default error: aborting due to 15 previous errors diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 012e050de8476..77c52788a9cb9 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -148,20 +148,22 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; ╾───────alloc41───────╼ │ ╾──────╼ } -error[E0080]: evaluation of constant value failed +error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: accessing memory with alignment 1, but alignment 4 is required - | -note: inside `std::ptr::read::` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `ptr::const_ptr::::read` + = note: inside `std::ptr::read::` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL -note: inside `UNALIGNED_READ` - --> $DIR/ub-ref-ptr.rs:65:5 + | + = note: inside `ptr::const_ptr::::read` + | + ::: $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ^^^^^^^^^^ + | ---------- inside `UNALIGNED_READ` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(invalid_alignment)]` on by default error: aborting due to 15 previous errors diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index e5b1eb2e48706..8f3c979f5ebab 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -24,6 +24,7 @@ use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Symbol; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; +use rustc_const_eval::const_eval::CheckAlignment; use crate::{ concurrency::{data_race, weak_memory}, @@ -752,8 +753,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { const PANIC_ON_ALLOC_FAIL: bool = false; #[inline(always)] - fn enforce_alignment(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { - ecx.machine.check_alignment != AlignmentCheck::None + fn enforce_alignment(ecx: &MiriInterpCx<'mir, 'tcx>) -> CheckAlignment { + if ecx.machine.check_alignment == AlignmentCheck::None { + CheckAlignment::No + } else { + CheckAlignment::Error + } } #[inline(always)] From d9d92ed7dadffa26d14274e7c73e3bdb4d56687e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Nov 2022 11:16:33 +0000 Subject: [PATCH 05/11] Move alignment failure error reporting to machine --- .../src/const_eval/machine.rs | 39 +++++++++++++++++- .../rustc_const_eval/src/interpret/machine.rs | 9 +++- .../rustc_const_eval/src/interpret/memory.rs | 41 +------------------ .../rustc_mir_transform/src/const_prop.rs | 13 +++++- .../src/dataflow_const_prop.rs | 9 ++++ src/tools/miri/src/machine.rs | 11 ++++- 6 files changed, 78 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 355ad66929629..50776d65551ef 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,9 +1,10 @@ use rustc_hir::def::DefKind; -use rustc_hir::LangItem; +use rustc_hir::{LangItem, CRATE_HIR_ID}; use rustc_middle::mir; -use rustc_middle::mir::interpret::PointerArithmetic; +use rustc_middle::mir::interpret::{PointerArithmetic, UndefinedBehaviorInfo}; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_session::lint::builtin::INVALID_ALIGNMENT; use std::borrow::Borrow; use std::hash::Hash; use std::ops::ControlFlow; @@ -338,6 +339,40 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks } + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + match check { + CheckAlignment::Error => { + throw_ub!(AlignmentCheckFailed { has, required }) + } + CheckAlignment::No => span_bug!( + ecx.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ), + CheckAlignment::FutureIncompat => ecx.tcx.struct_span_lint_hir( + INVALID_ALIGNMENT, + ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), + ecx.cur_span(), + UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), + |db| { + let mut stacktrace = ecx.generate_stacktrace(); + // Filter out `requires_caller_location` frames. + stacktrace + .retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx)); + for frame in stacktrace { + db.span_label(frame.span, format!("inside `{}`", frame.instance)); + } + db + }, + ), + } + Ok(()) + } + fn load_mir( ecx: &InterpCx<'mir, 'tcx, Self>, instance: ty::InstanceDef<'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index f52545317ea1a..1d4ef20d0651f 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -10,7 +10,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_target::abi::Size; +use rustc_target::abi::{Align, Size}; use rustc_target::spec::abi::Abi as CallAbi; use crate::const_eval::CheckAlignment; @@ -132,6 +132,13 @@ pub trait Machine<'mir, 'tcx>: Sized { /// If this returns true, Provenance::OFFSET_IS_ADDR must be true. fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx, ()>; + /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index ffd5e05bcc40a..5b1ac6b2f65e2 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -14,11 +14,8 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::display_allocation; -use rustc_middle::mir::interpret::UndefinedBehaviorInfo; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; -use rustc_session::lint::builtin::INVALID_ALIGNMENT; use rustc_target::abi::{Align, HasDataLayout, Size}; use crate::const_eval::CheckAlignment; @@ -448,7 +445,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Check allocation alignment and offset alignment. if alloc_align.bytes() < align.bytes() { - self.alignment_check_failed(alloc_align, align, check)?; + M::alignment_check_failed(self, alloc_align, align, check)?; } self.check_offset_align(offset.bytes(), align, check)?; } @@ -472,43 +469,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - self.alignment_check_failed(Align::from_bytes(offset_pow2).unwrap(), align, check) + M::alignment_check_failed(self, Align::from_bytes(offset_pow2).unwrap(), align, check) } } - - fn alignment_check_failed( - &self, - has: Align, - required: Align, - check: CheckAlignment, - ) -> InterpResult<'tcx, ()> { - match check { - CheckAlignment::Error => { - throw_ub!(AlignmentCheckFailed { has, required }) - } - CheckAlignment::No => span_bug!( - self.cur_span(), - "`alignment_check_failed` called when no alignment check requested" - ), - CheckAlignment::FutureIncompat => self.tcx.struct_span_lint_hir( - INVALID_ALIGNMENT, - self.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), - self.cur_span(), - UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), - |db| { - let mut stacktrace = self.generate_stacktrace(); - // Filter out `requires_caller_location` frames. - stacktrace - .retain(|frame| !frame.instance.def.requires_caller_location(*self.tcx)); - for frame in stacktrace { - db.span_label(frame.span, format!("inside `{}`", frame.instance)); - } - db - }, - ), - } - Ok(()) - } } /// Allocation accessors diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index c8ba6310d590b..044b7ce65bd71 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayo use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_span::{def_id::DefId, Span}; -use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; +use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; @@ -197,6 +197,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + span_bug!( + ecx.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ) + } fn load_mir( _ecx: &InterpCx<'mir, 'tcx, Self>, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 37675426f1916..c75fe2327de3e 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace}; use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects}; use rustc_span::DUMMY_SP; +use rustc_target::abi::Align; use crate::MirPass; @@ -456,6 +457,14 @@ impl<'mir, 'tcx> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachi fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { unimplemented!() } + fn alignment_check_failed( + _ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> interpret::InterpResult<'tcx, ()> { + unimplemented!() + } fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 8f3c979f5ebab..ab629e4711b10 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -22,7 +22,7 @@ use rustc_middle::{ }; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Symbol; -use rustc_target::abi::Size; +use rustc_target::abi::{Size, Align}; use rustc_target::spec::abi::Abi; use rustc_const_eval::const_eval::CheckAlignment; @@ -766,6 +766,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ecx.machine.check_alignment == AlignmentCheck::Int } + fn alignment_check_failed( + _ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + _check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + throw_ub!(AlignmentCheckFailed { has, required }) + } + #[inline(always)] fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { ecx.machine.validate From 98dc76a374807615a3400995e86237d89df95d35 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Nov 2022 11:52:26 +0000 Subject: [PATCH 06/11] Always report alignment failures in future incompat summaries --- compiler/rustc_lint_defs/src/builtin.rs | 1 + .../consts/const-eval/ub-ref-ptr.32bit.stderr | 18 ++++++++++++++++++ .../consts/const-eval/ub-ref-ptr.64bit.stderr | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index dddc200b2fb1a..111e6b961543e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1052,6 +1052,7 @@ declare_lint! { "raw pointers must be aligned before dereferencing", @future_incompatible = FutureIncompatibleInfo { reference: "issue #68585 ", + reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, }; } diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 8cd3918c0b407..6e6cbb34aeb82 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -168,3 +168,21 @@ LL | ptr.read(); error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: accessing memory with alignment 1, but alignment 4 is required + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: inside `ptr::const_ptr::::read` + | + ::: $DIR/ub-ref-ptr.rs:65:5 + | +LL | ptr.read(); + | ---------- inside `UNALIGNED_READ` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(invalid_alignment)]` on by default + diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 77c52788a9cb9..3d1f36f001227 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -168,3 +168,21 @@ LL | ptr.read(); error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: accessing memory with alignment 1, but alignment 4 is required + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | + = note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: inside `ptr::const_ptr::::read` + | + ::: $DIR/ub-ref-ptr.rs:65:5 + | +LL | ptr.read(); + | ---------- inside `UNALIGNED_READ` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(invalid_alignment)]` on by default + From dec05e9c73fb5590a4f302bdf5426fc0cabe6f17 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Nov 2022 12:00:07 +0000 Subject: [PATCH 07/11] Factor decorate closure out into a method --- .../rustc_const_eval/src/const_eval/error.rs | 135 +++++++++--------- 1 file changed, 65 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index c60d6e4fed9f5..13472cc2bfa0a 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -86,6 +86,59 @@ impl<'tcx> ConstEvalErr<'tcx> { self.report_decorated(tcx, message, |_| {}) } + #[instrument(level = "trace", skip(self, decorate))] + pub(super) fn decorate(&self, err: &mut Diagnostic, decorate: impl FnOnce(&mut Diagnostic)) { + trace!("reporting const eval failure at {:?}", self.span); + // Add some more context for select error types. + match self.error { + InterpError::Unsupported( + UnsupportedOpInfo::ReadPointerAsBytes + | UnsupportedOpInfo::PartialPointerOverwrite(_) + | UnsupportedOpInfo::PartialPointerCopy(_), + ) => { + err.help("this code performed an operation that depends on the underlying bytes representing a pointer"); + err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported"); + } + _ => {} + } + // Add spans for the stacktrace. Don't print a single-line backtrace though. + if self.stacktrace.len() > 1 { + // Helper closure to print duplicated lines. + let mut flush_last_line = |last_frame, times| { + if let Some((line, span)) = last_frame { + err.span_note(span, &line); + // Don't print [... additional calls ...] if the number of lines is small + if times < 3 { + for _ in 0..times { + err.span_note(span, &line); + } + } else { + err.span_note( + span, + format!("[... {} additional calls {} ...]", times, &line), + ); + } + } + }; + + let mut last_frame = None; + let mut times = 0; + for frame_info in &self.stacktrace { + let frame = (frame_info.to_string(), frame_info.span); + if last_frame.as_ref() == Some(&frame) { + times += 1; + } else { + flush_last_line(last_frame, times); + last_frame = Some(frame); + times = 0; + } + } + flush_last_line(last_frame, times); + } + // Let the caller attach any additional information it wants. + decorate(err); + } + /// Create a diagnostic for this const eval error. /// /// Sets the message passed in via `message` and adds span labels with detailed error @@ -101,88 +154,30 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, decorate: impl FnOnce(&mut Diagnostic), ) -> ErrorHandled { - let finish = |err: &mut Diagnostic, span_msg: Option| { - trace!("reporting const eval failure at {:?}", self.span); - if let Some(span_msg) = span_msg { - err.span_label(self.span, span_msg); - } - // Add some more context for select error types. - match self.error { - InterpError::Unsupported( - UnsupportedOpInfo::ReadPointerAsBytes - | UnsupportedOpInfo::PartialPointerOverwrite(_) - | UnsupportedOpInfo::PartialPointerCopy(_), - ) => { - err.help("this code performed an operation that depends on the underlying bytes representing a pointer"); - err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported"); - } - _ => {} - } - // Add spans for the stacktrace. Don't print a single-line backtrace though. - if self.stacktrace.len() > 1 { - // Helper closure to print duplicated lines. - let mut flush_last_line = |last_frame, times| { - if let Some((line, span)) = last_frame { - err.span_note(span, &line); - // Don't print [... additional calls ...] if the number of lines is small - if times < 3 { - for _ in 0..times { - err.span_note(span, &line); - } - } else { - err.span_note( - span, - format!("[... {} additional calls {} ...]", times, &line), - ); - } - } - }; - - let mut last_frame = None; - let mut times = 0; - for frame_info in &self.stacktrace { - let frame = (frame_info.to_string(), frame_info.span); - if last_frame.as_ref() == Some(&frame) { - times += 1; - } else { - flush_last_line(last_frame, times); - last_frame = Some(frame); - times = 0; - } - } - flush_last_line(last_frame, times); - } - // Let the caller attach any additional information it wants. - decorate(err); - }; - debug!("self.error: {:?}", self.error); // Special handling for certain errors match &self.error { // Don't emit a new diagnostic for these errors err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { - return ErrorHandled::TooGeneric; - } - err_inval!(AlreadyReported(error_reported)) => { - return ErrorHandled::Reported(*error_reported); + ErrorHandled::TooGeneric } + err_inval!(AlreadyReported(error_reported)) => ErrorHandled::Reported(*error_reported), err_inval!(Layout(LayoutError::SizeOverflow(_))) => { // We must *always* hard error on these, even if the caller wants just a lint. // The `message` makes little sense here, this is a more serious error than the // caller thinks anyway. // See . let mut err = struct_error(tcx, &self.error.to_string()); - finish(&mut err, None); - return ErrorHandled::Reported(err.emit()); + self.decorate(&mut err, decorate); + ErrorHandled::Reported(err.emit()) } - _ => {} - }; - - let err_msg = self.error.to_string(); - - // Report as hard error. - let mut err = struct_error(tcx, message); - finish(&mut err, Some(err_msg)); - ErrorHandled::Reported(err.emit()) + _ => { + // Report as hard error. + let mut err = struct_error(tcx, message); + err.span_label(self.span, self.error.to_string()); + self.decorate(&mut err, decorate); + ErrorHandled::Reported(err.emit()) + } + } } } From b05c790fd6ac0ad050ead3e7ae956729fcf7e0db Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Nov 2022 12:06:17 +0000 Subject: [PATCH 08/11] Reuse the ctfe error emitting logic for the future incompat lint --- .../src/const_eval/machine.rs | 39 +++++++++++-------- .../consts/const-eval/ub-ref-ptr.32bit.stderr | 34 ++++++++-------- .../consts/const-eval/ub-ref-ptr.64bit.stderr | 34 ++++++++-------- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 50776d65551ef..abe06737def0b 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,7 +1,7 @@ use rustc_hir::def::DefKind; use rustc_hir::{LangItem, CRATE_HIR_ID}; use rustc_middle::mir; -use rustc_middle::mir::interpret::{PointerArithmetic, UndefinedBehaviorInfo}; +use rustc_middle::mir::interpret::{InterpError, PointerArithmetic, UndefinedBehaviorInfo}; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::builtin::INVALID_ALIGNMENT; @@ -353,22 +353,27 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.cur_span(), "`alignment_check_failed` called when no alignment check requested" ), - CheckAlignment::FutureIncompat => ecx.tcx.struct_span_lint_hir( - INVALID_ALIGNMENT, - ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), - ecx.cur_span(), - UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), - |db| { - let mut stacktrace = ecx.generate_stacktrace(); - // Filter out `requires_caller_location` frames. - stacktrace - .retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx)); - for frame in stacktrace { - db.span_label(frame.span, format!("inside `{}`", frame.instance)); - } - db - }, - ), + CheckAlignment::FutureIncompat => { + let err = ConstEvalErr::new( + ecx, + InterpError::UndefinedBehavior(UndefinedBehaviorInfo::AlignmentCheckFailed { + has, + required, + }) + .into(), + None, + ); + ecx.tcx.struct_span_lint_hir( + INVALID_ALIGNMENT, + ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), + err.span, + err.error.to_string(), + |db| { + err.decorate(db, |_| {}); + db + }, + ); + } } Ok(()) } diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 6e6cbb34aeb82..a0a8d76d10d2d 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -151,18 +151,17 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: inside `std::ptr::read::` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: inside `ptr::const_ptr::::read` - | - ::: $DIR/ub-ref-ptr.rs:65:5 +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ---------- inside `UNALIGNED_READ` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 + | ^^^^^^^^^^ = note: `#[deny(invalid_alignment)]` on by default error: aborting due to 15 previous errors @@ -172,17 +171,16 @@ Future incompatibility report: Future breakage diagnostic: error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: inside `std::ptr::read::` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: inside `ptr::const_ptr::::read` - | - ::: $DIR/ub-ref-ptr.rs:65:5 +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ---------- inside `UNALIGNED_READ` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 + | ^^^^^^^^^^ = note: `#[deny(invalid_alignment)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index 3d1f36f001227..d53b44671e3f4 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -151,18 +151,17 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: inside `std::ptr::read::` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: inside `ptr::const_ptr::::read` - | - ::: $DIR/ub-ref-ptr.rs:65:5 +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ---------- inside `UNALIGNED_READ` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 + | ^^^^^^^^^^ = note: `#[deny(invalid_alignment)]` on by default error: aborting due to 15 previous errors @@ -172,17 +171,16 @@ Future incompatibility report: Future breakage diagnostic: error: accessing memory with alignment 1, but alignment 4 is required --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: inside `std::ptr::read::` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 +note: inside `std::ptr::read::` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside `ptr::const_ptr::::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL - | - = note: inside `ptr::const_ptr::::read` - | - ::: $DIR/ub-ref-ptr.rs:65:5 +note: inside `UNALIGNED_READ` + --> $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); - | ---------- inside `UNALIGNED_READ` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #68585 + | ^^^^^^^^^^ = note: `#[deny(invalid_alignment)]` on by default From 2b2170384d511a613ddd6a4298feab0ed3a5f6ec Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 22 Nov 2022 13:55:37 +0000 Subject: [PATCH 09/11] Fix docs --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 111e6b961543e..848906e29d5b1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1031,7 +1031,7 @@ declare_lint! { /// let y = x.as_ptr() as *const u32; /// *y; // the address of a `u8` array is unknown and thus we don't know if /// // it is aligned enough for reading a `u32`. - /// } + /// }; /// ``` /// /// {{produces}} From 5a06b1e67c746b5cdcaa03116dcc869b7b8fc2dd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Nov 2022 22:04:08 +0100 Subject: [PATCH 10/11] simplify alignment_check_failed a bit --- .../src/const_eval/machine.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index abe06737def0b..e006a62feeabd 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,7 +1,7 @@ use rustc_hir::def::DefKind; use rustc_hir::{LangItem, CRATE_HIR_ID}; use rustc_middle::mir; -use rustc_middle::mir::interpret::{InterpError, PointerArithmetic, UndefinedBehaviorInfo}; +use rustc_middle::mir::interpret::PointerArithmetic; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::builtin::INVALID_ALIGNMENT; @@ -345,24 +345,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, required: Align, check: CheckAlignment, ) -> InterpResult<'tcx, ()> { + let err = err_ub!(AlignmentCheckFailed { has, required }).into(); match check { - CheckAlignment::Error => { - throw_ub!(AlignmentCheckFailed { has, required }) - } + CheckAlignment::Error => Err(err), CheckAlignment::No => span_bug!( ecx.cur_span(), "`alignment_check_failed` called when no alignment check requested" ), CheckAlignment::FutureIncompat => { - let err = ConstEvalErr::new( - ecx, - InterpError::UndefinedBehavior(UndefinedBehaviorInfo::AlignmentCheckFailed { - has, - required, - }) - .into(), - None, - ); + let err = ConstEvalErr::new(ecx, err, None); ecx.tcx.struct_span_lint_hir( INVALID_ALIGNMENT, ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), @@ -373,9 +364,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, db }, ); + Ok(()) } } - Ok(()) } fn load_mir( From 2d89027fac84d7ba95cf2d66b49136d3f0d08ba2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Nov 2022 14:41:06 +0000 Subject: [PATCH 11/11] Make the test actually emit the future incompat lint --- compiler/rustc_lint_defs/src/builtin.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 848906e29d5b1..33cb35e60ebb6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1026,10 +1026,11 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail + /// #![feature(const_ptr_read)] /// const FOO: () = unsafe { - /// let x = [0_u8; 10]; - /// let y = x.as_ptr() as *const u32; - /// *y; // the address of a `u8` array is unknown and thus we don't know if + /// let x = &[0_u8; 4]; + /// let y = x.as_ptr().cast::(); + /// y.read(); // the address of a `u8` array is unknown and thus we don't know if /// // it is aligned enough for reading a `u32`. /// }; /// ```