Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CTFE validation: handle pointers in str #85332

Merged
merged 4 commits into from
May 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_mir/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
self.ecx.memory.read_bytes(mplace.ptr, Size::from_bytes(len)),
self.path,
err_ub!(InvalidUninitBytes(..)) => { "uninitialized data in `str`" },
err_unsup!(ReadPointerAsBytes) => { "a pointer in `str`" },
);
}
ty::Array(tys, ..) | ty::Slice(tys)
Expand Down
6 changes: 2 additions & 4 deletions src/test/ui/consts/const-eval/dangling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
use std::mem;

// Make sure we error with the right kind of error on a too large slice.
const TEST: () = { unsafe { //~ NOTE
const TEST: () = { unsafe {
let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
let _val = &*slice; //~ ERROR: any use of this value will cause an error
//~| NOTE: slice is bigger than largest supported object
//~| on by default
//~| slice is bigger than largest supported object
//~| WARN this was previously accepted by the compiler but is being phased out
//~| NOTE
} };

fn main() {}
1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/dangling.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ LL | | let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
LL | | let _val = &*slice;
| | ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object
LL | |
... |
LL | |
LL | | } };
| |____-
Expand Down
4 changes: 1 addition & 3 deletions src/test/ui/consts/const-points-to-static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

const TEST: &u8 = &MY_STATIC;
//~^ ERROR it is undefined behavior to use this value
//~| NOTE encountered a reference pointing to a static variable
//~| NOTE undefined behavior
//~| NOTE the raw bytes of the constant
//~| encountered a reference pointing to a static variable

static MY_STATIC: u8 = 4;

Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/consts/issue-83182.32bit.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/issue-83182.rs:5:1
|
LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer in `str` at .<deref>.0
|
= 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) {
╾─alloc3──╼ 01 00 00 00 │ ╾──╼....
}

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.
14 changes: 14 additions & 0 deletions src/test/ui/consts/issue-83182.64bit.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/issue-83182.rs:5:1
|
LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer in `str` at .<deref>.0
|
= 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) {
╾───────alloc3────────╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
}

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.
8 changes: 8 additions & 0 deletions src/test/ui/consts/issue-83182.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// stderr-per-bitwidth

use std::mem;
struct MyStr(str);
const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
//~^ ERROR: it is undefined behavior to use this value
//~| type validation failed: encountered a pointer in `str`
fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ error[E0080]: it is undefined behavior to use this value
|
LL | / const REF_INTERIOR_MUT: &usize = {
LL | |
LL | |
LL | |
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | unsafe { &*(&FOO as *const _ as *const usize) }
LL | | };
Expand All @@ -16,12 +14,10 @@ LL | | };
}

error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:20:1
--> $DIR/const_refers_to_static2.rs:18:1
|
LL | / const READ_IMMUT: &usize = {
LL | |
LL | |
LL | |
LL | | static FOO: usize = 0;
LL | | &FOO
LL | | };
Expand All @@ -35,17 +31,17 @@ LL | | };
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static2.rs:16:18
--> $DIR/const_refers_to_static2.rs:14:18
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^
help: skipping check for `const_raw_ptr_deref` feature
--> $DIR/const_refers_to_static2.rs:16:14
--> $DIR/const_refers_to_static2.rs:14:14
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static2.rs:25:6
--> $DIR/const_refers_to_static2.rs:21:6
|
LL | &FOO
| ^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ error[E0080]: it is undefined behavior to use this value
|
LL | / const REF_INTERIOR_MUT: &usize = {
LL | |
LL | |
LL | |
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | unsafe { &*(&FOO as *const _ as *const usize) }
LL | | };
Expand All @@ -16,12 +14,10 @@ LL | | };
}

error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:20:1
--> $DIR/const_refers_to_static2.rs:18:1
|
LL | / const READ_IMMUT: &usize = {
LL | |
LL | |
LL | |
LL | | static FOO: usize = 0;
LL | | &FOO
LL | | };
Expand All @@ -35,17 +31,17 @@ LL | | };
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static2.rs:16:18
--> $DIR/const_refers_to_static2.rs:14:18
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^
help: skipping check for `const_raw_ptr_deref` feature
--> $DIR/const_refers_to_static2.rs:16:14
--> $DIR/const_refers_to_static2.rs:14:14
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static2.rs:25:6
--> $DIR/const_refers_to_static2.rs:21:6
|
LL | &FOO
| ^^^
Expand Down
8 changes: 2 additions & 6 deletions src/test/ui/consts/miri_unleashed/const_refers_to_static2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@ use std::sync::atomic::Ordering;
// so they cause an immediate error when *defining* the const.

const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this value
//~| NOTE encountered a reference pointing to a static variable
//~| NOTE undefined behavior
//~| NOTE the raw bytes of the constant
//~| encountered a reference pointing to a static variable
static FOO: AtomicUsize = AtomicUsize::new(0);
unsafe { &*(&FOO as *const _ as *const usize) }
};

// ok some day perhaps
const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value
//~| NOTE encountered a reference pointing to a static variable
//~| NOTE undefined behavior
//~| NOTE the raw bytes of the constant
//~| encountered a reference pointing to a static variable
static FOO: usize = 0;
&FOO
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ error[E0080]: it is undefined behavior to use this value
|
LL | / const SLICE_MUT: &[u8; 1] = {
LL | |
LL | |
LL | |
LL | | unsafe { &static_cross_crate::ZERO }
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
Expand All @@ -15,18 +13,16 @@ LL | | };
}

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:47:9
--> $DIR/const_refers_to_static_cross_crate.rs:40:9
|
LL | SLICE_MUT => true,
| ^^^^^^^^^

error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static_cross_crate.rs:19:1
--> $DIR/const_refers_to_static_cross_crate.rs:17:1
|
LL | / const U8_MUT: &u8 = {
LL | |
LL | |
LL | |
LL | | unsafe { &static_cross_crate::ZERO[0] }
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
Expand All @@ -37,143 +33,141 @@ LL | | };
}

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:56:9
--> $DIR/const_refers_to_static_cross_crate.rs:49:9
|
LL | U8_MUT => true,
| ^^^^^^

warning: any use of this value will cause an error
--> $DIR/const_refers_to_static_cross_crate.rs:29:15
--> $DIR/const_refers_to_static_cross_crate.rs:25:15
|
LL | / const U8_MUT2: &u8 = {
LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
LL | |
LL | |
LL | |
LL | |
LL | | };
| |__-
|
note: the lint level is defined here
--> $DIR/const_refers_to_static_cross_crate.rs:27:8
--> $DIR/const_refers_to_static_cross_crate.rs:23:8
|
LL | #[warn(const_err)]
| ^^^^^^^^^
= 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 #71800 <https://github.com/rust-lang/rust/issues/71800>

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:67:9
--> $DIR/const_refers_to_static_cross_crate.rs:60:9
|
LL | U8_MUT2 => true,
| ^^^^^^^

warning: any use of this value will cause an error
--> $DIR/const_refers_to_static_cross_crate.rs:37:51
--> $DIR/const_refers_to_static_cross_crate.rs:32:51
|
LL | / const U8_MUT3: &u8 = {
LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| | ^^^^^^^^^^^ constant accesses static
LL | |
LL | |
... |
LL | |
LL | | };
| |__-
|
note: the lint level is defined here
--> $DIR/const_refers_to_static_cross_crate.rs:35:8
--> $DIR/const_refers_to_static_cross_crate.rs:30:8
|
LL | #[warn(const_err)]
| ^^^^^^^^^
= 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 #71800 <https://github.com/rust-lang/rust/issues/71800>

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:75:9
--> $DIR/const_refers_to_static_cross_crate.rs:68:9
|
LL | U8_MUT3 => true,
| ^^^^^^^

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:47:9
--> $DIR/const_refers_to_static_cross_crate.rs:40:9
|
LL | SLICE_MUT => true,
| ^^^^^^^^^

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:56:9
--> $DIR/const_refers_to_static_cross_crate.rs:49:9
|
LL | U8_MUT => true,
| ^^^^^^

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:67:9
--> $DIR/const_refers_to_static_cross_crate.rs:60:9
|
LL | U8_MUT2 => true,
| ^^^^^^^

error: could not evaluate constant pattern
--> $DIR/const_refers_to_static_cross_crate.rs:75:9
--> $DIR/const_refers_to_static_cross_crate.rs:68:9
|
LL | U8_MUT3 => true,
| ^^^^^^^

warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:16:15
--> $DIR/const_refers_to_static_cross_crate.rs:14:15
|
LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:16:15
--> $DIR/const_refers_to_static_cross_crate.rs:14:15
|
LL | unsafe { &static_cross_crate::ZERO }
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:23:15
--> $DIR/const_refers_to_static_cross_crate.rs:19:15
|
LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:23:15
--> $DIR/const_refers_to_static_cross_crate.rs:19:15
|
LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:23:15
--> $DIR/const_refers_to_static_cross_crate.rs:19:15
|
LL | unsafe { &static_cross_crate::ZERO[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:29:17
--> $DIR/const_refers_to_static_cross_crate.rs:25:17
|
LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:37:20
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:37:20
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:37:20
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_panic` feature
--> $DIR/const_refers_to_static_cross_crate.rs:37:77
--> $DIR/const_refers_to_static_cross_crate.rs:32:77
|
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| ^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/const_refers_to_static_cross_crate.rs:37:20
--> $DIR/const_refers_to_static_cross_crate.rs:32:20
|
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
Loading