Skip to content

Commit a2352fe

Browse files
committed
reference to mutable memory in const is impossible
1 parent d147d5b commit a2352fe

13 files changed

+145
-73
lines changed

compiler/rustc_const_eval/messages.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ const_eval_upcast_mismatch =
406406
407407
## The `front_matter`s here refer to either `const_eval_front_matter_invalid_value` or `const_eval_front_matter_invalid_value_with_path`.
408408
## (We'd love to sort this differently to make that more clear but tidy won't let us...)
409-
const_eval_validation_box_to_mut = {$front_matter}: encountered a box pointing to mutable memory in a constant
410409
const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant
411410
const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty}
412411
const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance)
@@ -452,7 +451,6 @@ const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but
452451
const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers
453452
const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected}
454453
const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
455-
const_eval_validation_ref_to_mut = {$front_matter}: encountered a reference pointing to mutable memory in a constant
456454
const_eval_validation_ref_to_static = {$front_matter}: encountered a reference pointing to a static variable in a constant
457455
const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
458456
const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})

compiler/rustc_const_eval/src/errors.rs

-4
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
612612
PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static,
613613
PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_static,
614614

615-
PtrToMut { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_mut,
616-
PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_mut,
617-
618615
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
619616
PartialPointer => const_eval_validation_partial_pointer,
620617
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
@@ -770,7 +767,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
770767
}
771768
NullPtr { .. }
772769
| PtrToStatic { .. }
773-
| PtrToMut { .. }
774770
| MutableRefInConst
775771
| MutableRefToImmutable
776772
| NullFnPtr

compiler/rustc_const_eval/src/interpret/validity.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -510,10 +510,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
510510
if alloc.inner().mutability == Mutability::Mut
511511
&& matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. }))
512512
{
513-
// This should be unreachable, but if someone manages to copy a pointer
514-
// out of a `static`, then that pointer might point to mutable memory,
515-
// and we would catch that here.
516-
throw_validation_failure!(self.path, PtrToMut { ptr_kind });
513+
// This is impossible: this can only be some inner allocation of a
514+
// `static mut` (everything else either hits the `GlobalAlloc::Static`
515+
// case or is interned immutably). To get such a pointer we'd have to
516+
// load it from a static, but such loads lead to a CTFE error.
517+
span_bug!(
518+
self.ecx.tcx.span,
519+
"encountered reference to mutable memory inside a `const`"
520+
);
517521
}
518522
if ptr_expected_mutbl == Mutability::Mut
519523
&& alloc.inner().mutability == Mutability::Not

compiler/rustc_middle/src/mir/interpret/error.rs

-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,6 @@ pub enum ValidationErrorKind<'tcx> {
427427
PartialPointer,
428428
PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> },
429429
PtrToStatic { ptr_kind: PointerKind },
430-
PtrToMut { ptr_kind: PointerKind },
431430
MutableRefInConst,
432431
MutableRefToImmutable,
433432
UnsafeCellInImmutable,

tests/ui/consts/const-points-to-static.32bit.stderr

-22
This file was deleted.

tests/ui/consts/const-points-to-static.64bit.stderr

-22
This file was deleted.

tests/ui/consts/const-points-to-static.rs

-13
This file was deleted.

tests/ui/consts/miri_unleashed/const_refers_to_static.32bit.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ LL | const READ_IMMUT: &usize = {
3838
╾ALLOC1╼ │ ╾──╼
3939
}
4040

41+
error[E0080]: it is undefined behavior to use this value
42+
--> $DIR/const_refers_to_static.rs:34:1
43+
|
44+
LL | const REF_IMMUT: &u8 = &MY_STATIC;
45+
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
46+
|
47+
= 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.
48+
= note: the raw bytes of the constant (size: 4, align: 4) {
49+
╾ALLOC2╼ │ ╾──╼
50+
}
51+
4152
warning: skipping const checks
4253
|
4354
help: skipping check that does not even have a feature gate
@@ -75,7 +86,12 @@ help: skipping check that does not even have a feature gate
7586
|
7687
LL | &FOO
7788
| ^^^
89+
help: skipping check that does not even have a feature gate
90+
--> $DIR/const_refers_to_static.rs:34:25
91+
|
92+
LL | const REF_IMMUT: &u8 = &MY_STATIC;
93+
| ^^^^^^^^^
7894

79-
error: aborting due to 5 previous errors; 1 warning emitted
95+
error: aborting due to 6 previous errors; 1 warning emitted
8096

8197
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/miri_unleashed/const_refers_to_static.64bit.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ LL | const READ_IMMUT: &usize = {
3838
╾ALLOC1╼ │ ╾──────╼
3939
}
4040

41+
error[E0080]: it is undefined behavior to use this value
42+
--> $DIR/const_refers_to_static.rs:34:1
43+
|
44+
LL | const REF_IMMUT: &u8 = &MY_STATIC;
45+
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
46+
|
47+
= 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.
48+
= note: the raw bytes of the constant (size: 8, align: 8) {
49+
╾ALLOC2╼ │ ╾──────╼
50+
}
51+
4152
warning: skipping const checks
4253
|
4354
help: skipping check that does not even have a feature gate
@@ -75,7 +86,12 @@ help: skipping check that does not even have a feature gate
7586
|
7687
LL | &FOO
7788
| ^^^
89+
help: skipping check that does not even have a feature gate
90+
--> $DIR/const_refers_to_static.rs:34:25
91+
|
92+
LL | const REF_IMMUT: &u8 = &MY_STATIC;
93+
| ^^^^^^^^^
7894

79-
error: aborting due to 5 previous errors; 1 warning emitted
95+
error: aborting due to 6 previous errors; 1 warning emitted
8096

8197
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/miri_unleashed/const_refers_to_static.rs

+5
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this valu
3030
&FOO
3131
};
3232

33+
static MY_STATIC: u8 = 4;
34+
const REF_IMMUT: &u8 = &MY_STATIC;
35+
//~^ ERROR it is undefined behavior to use this value
36+
//~| encountered a reference pointing to a static variable
37+
3338
fn main() {}

tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr

+43-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
5353
╾ALLOC5╼ │ ╾──╼
5454
}
5555

56+
error[E0080]: it is undefined behavior to use this value
57+
--> $DIR/mutable_references_err.rs:49:1
58+
|
59+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
61+
|
62+
= 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.
63+
= note: the raw bytes of the constant (size: 4, align: 4) {
64+
╾ALLOC6╼ │ ╾──╼
65+
}
66+
67+
error[E0080]: evaluation of constant value failed
68+
--> $DIR/mutable_references_err.rs:53:43
69+
|
70+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
71+
| ^^^^^^^^^^^^^ constant accesses static
72+
5673
warning: skipping const checks
5774
|
5875
help: skipping check that does not even have a feature gate
@@ -100,7 +117,32 @@ help: skipping check that does not even have a feature gate
100117
|
101118
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
102119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120+
help: skipping check that does not even have a feature gate
121+
--> $DIR/mutable_references_err.rs:49:44
122+
|
123+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
124+
| ^^^^^^^
125+
help: skipping check that does not even have a feature gate
126+
--> $DIR/mutable_references_err.rs:49:44
127+
|
128+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
129+
| ^^^^^^^
130+
help: skipping check that does not even have a feature gate
131+
--> $DIR/mutable_references_err.rs:52:36
132+
|
133+
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
134+
| ^^^^^^^
135+
help: skipping check that does not even have a feature gate
136+
--> $DIR/mutable_references_err.rs:53:45
137+
|
138+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
139+
| ^^^^^^^^^^^
140+
help: skipping check that does not even have a feature gate
141+
--> $DIR/mutable_references_err.rs:53:45
142+
|
143+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
144+
| ^^^^^^^^^^^
103145

104-
error: aborting due to 5 previous errors; 1 warning emitted
146+
error: aborting due to 7 previous errors; 1 warning emitted
105147

106148
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr

+43-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const
5353
╾ALLOC5╼ │ ╾──────╼
5454
}
5555

56+
error[E0080]: it is undefined behavior to use this value
57+
--> $DIR/mutable_references_err.rs:49:1
58+
|
59+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to a static variable in a constant
61+
|
62+
= 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.
63+
= note: the raw bytes of the constant (size: 8, align: 8) {
64+
╾ALLOC6╼ │ ╾──────╼
65+
}
66+
67+
error[E0080]: evaluation of constant value failed
68+
--> $DIR/mutable_references_err.rs:53:43
69+
|
70+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
71+
| ^^^^^^^^^^^^^ constant accesses static
72+
5673
warning: skipping const checks
5774
|
5875
help: skipping check that does not even have a feature gate
@@ -100,7 +117,32 @@ help: skipping check that does not even have a feature gate
100117
|
101118
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
102119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120+
help: skipping check that does not even have a feature gate
121+
--> $DIR/mutable_references_err.rs:49:44
122+
|
123+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
124+
| ^^^^^^^
125+
help: skipping check that does not even have a feature gate
126+
--> $DIR/mutable_references_err.rs:49:44
127+
|
128+
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
129+
| ^^^^^^^
130+
help: skipping check that does not even have a feature gate
131+
--> $DIR/mutable_references_err.rs:52:36
132+
|
133+
LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
134+
| ^^^^^^^
135+
help: skipping check that does not even have a feature gate
136+
--> $DIR/mutable_references_err.rs:53:45
137+
|
138+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
139+
| ^^^^^^^^^^^
140+
help: skipping check that does not even have a feature gate
141+
--> $DIR/mutable_references_err.rs:53:45
142+
|
143+
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
144+
| ^^^^^^^^^^^
103145

104-
error: aborting due to 5 previous errors; 1 warning emitted
146+
error: aborting due to 7 previous errors; 1 warning emitted
105147

106148
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/miri_unleashed/mutable_references_err.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,18 @@ const BLUNT: &mut i32 = &mut 42;
4141
static READONLY: i32 = 0;
4242
static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
4343
//~^ ERROR: it is undefined behavior to use this value
44-
//~| mutable reference
44+
//~| pointing to read-only memory
45+
46+
// Check for consts pointing to mutable memory.
47+
// Currently it's not even possible to create such a const.
48+
static mut MUTABLE: i32 = 42;
49+
const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
50+
//~^ ERROR: undefined behavior to use this value
51+
//~| pointing to a static
52+
static mut MUTABLE_REF: &mut i32 = &mut 42;
53+
const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
54+
//~^ ERROR: evaluation of constant value failed
55+
//~| accesses static
4556

4657
fn main() {
4758
unsafe {

0 commit comments

Comments
 (0)