Skip to content

Commit 567bcbc

Browse files
committed
Validate nested static items
1 parent 73476d4 commit 567bcbc

File tree

6 files changed

+149
-68
lines changed

6 files changed

+149
-68
lines changed

compiler/rustc_const_eval/src/interpret/validity.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
457457
// Special handling for pointers to statics (irrespective of their type).
458458
assert!(!self.ecx.tcx.is_thread_local_static(did));
459459
assert!(self.ecx.tcx.is_static(did));
460+
let DefKind::Static { mutability, nested } = self.ecx.tcx.def_kind(did)
461+
else {
462+
bug!()
463+
};
460464
// Mode-specific checks
461465
match self.ctfe_mode {
462466
Some(
@@ -471,7 +475,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
471475
// trigger cycle errors if we try to compute the value of the other static
472476
// and that static refers back to us (potentially through a promoted).
473477
// This could miss some UB, but that's fine.
474-
skip_recursive_check = true;
478+
// We still walk nested allocations, as they are fundamentally part of this validation run.
479+
skip_recursive_check = !nested;
475480
}
476481
Some(CtfeValidationMode::Const { .. }) => {
477482
// We can't recursively validate `extern static`, so we better reject them.
@@ -483,10 +488,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
483488
}
484489
// Return alloc mutability. For "root" statics we look at the type to account for interior
485490
// mutability; for nested statics we have no type and directly use the annotated mutability.
486-
let DefKind::Static { mutability, nested } = self.ecx.tcx.def_kind(did)
487-
else {
488-
bug!()
489-
};
490491
match (mutability, nested) {
491492
(Mutability::Mut, _) => Mutability::Mut,
492493
(Mutability::Not, true) => Mutability::Not,
@@ -708,8 +709,18 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
708709
if let Some(mplace) = op.as_mplace_or_imm().left() {
709710
if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) {
710711
let mutability = match self.ecx.tcx.global_alloc(alloc_id) {
711-
GlobalAlloc::Static(_) => {
712-
self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability
712+
// This can only ever be the static currently being evaluated (or one of its nested allocations), as
713+
// we do not walk into other statics. See `check_safe_pointer` for details.
714+
GlobalAlloc::Static(did) => {
715+
let DefKind::Static { mutability, nested } = self.ecx.tcx.def_kind(did)
716+
else {
717+
bug!()
718+
};
719+
if nested {
720+
mutability
721+
} else {
722+
self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability
723+
}
713724
}
714725
GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
715726
_ => span_bug!(self.ecx.tcx.span, "not a memory allocation"),

tests/ui/consts/miri_unleashed/mutable_references.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::cell::UnsafeCell;
1010
static FOO: &&mut u32 = &&mut 42;
1111
//~^ ERROR encountered mutable pointer in final value of static
1212
//~| WARNING this was previously accepted by the compiler
13+
//~| ERROR it is undefined behavior to use this value
1314

1415
static BAR: &mut () = &mut ();
1516
//~^ ERROR encountered mutable pointer in final value of static
@@ -28,6 +29,7 @@ unsafe impl Sync for Meh {}
2829
static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
2930
//~^ ERROR encountered mutable pointer in final value of static
3031
//~| WARNING this was previously accepted by the compiler
32+
//~| ERROR it is undefined behavior to use this value
3133

3234
static OH_YES: &mut i32 = &mut 42;
3335
//~^ ERROR encountered mutable pointer in final value of static

tests/ui/consts/miri_unleashed/mutable_references.stderr

+37-15
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,19 @@ note: the lint level is defined here
1212
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

15+
error[E0080]: it is undefined behavior to use this value
16+
--> $DIR/mutable_references.rs:10:1
17+
|
18+
LL | static FOO: &&mut u32 = &&mut 42;
19+
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered mutable reference or box pointing to read-only memory
20+
|
21+
= 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.
22+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
23+
HEX_DUMP
24+
}
25+
1526
error: encountered mutable pointer in final value of static
16-
--> $DIR/mutable_references.rs:14:1
27+
--> $DIR/mutable_references.rs:15:1
1728
|
1829
LL | static BAR: &mut () = &mut ();
1930
| ^^^^^^^^^^^^^^^^^^^
@@ -22,7 +33,7 @@ LL | static BAR: &mut () = &mut ();
2233
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
2334

2435
error: encountered mutable pointer in final value of static
25-
--> $DIR/mutable_references.rs:20:1
36+
--> $DIR/mutable_references.rs:21:1
2637
|
2738
LL | static BOO: &mut Foo<()> = &mut Foo(());
2839
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -31,16 +42,27 @@ LL | static BOO: &mut Foo<()> = &mut Foo(());
3142
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
3243

3344
error: encountered mutable pointer in final value of static
34-
--> $DIR/mutable_references.rs:28:1
45+
--> $DIR/mutable_references.rs:29:1
3546
|
3647
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
3748
| ^^^^^^^^^^^^^^^
3849
|
3950
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4051
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
4152

53+
error[E0080]: it is undefined behavior to use this value
54+
--> $DIR/mutable_references.rs:29:1
55+
|
56+
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
57+
| ^^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
58+
|
59+
= 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.
60+
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
61+
HEX_DUMP
62+
}
63+
4264
error: encountered mutable pointer in final value of static
43-
--> $DIR/mutable_references.rs:32:1
65+
--> $DIR/mutable_references.rs:34:1
4466
|
4567
LL | static OH_YES: &mut i32 = &mut 42;
4668
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +71,7 @@ LL | static OH_YES: &mut i32 = &mut 42;
4971
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
5072

5173
error[E0080]: it is undefined behavior to use this value
52-
--> $DIR/mutable_references.rs:32:1
74+
--> $DIR/mutable_references.rs:34:1
5375
|
5476
LL | static OH_YES: &mut i32 = &mut 42;
5577
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
@@ -60,7 +82,7 @@ LL | static OH_YES: &mut i32 = &mut 42;
6082
}
6183

6284
error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item
63-
--> $DIR/mutable_references.rs:41:5
85+
--> $DIR/mutable_references.rs:43:5
6486
|
6587
LL | *OH_YES = 99;
6688
| ^^^^^^^^^^^^ cannot assign
@@ -73,27 +95,27 @@ help: skipping check that does not even have a feature gate
7395
LL | static FOO: &&mut u32 = &&mut 42;
7496
| ^^^^^^^
7597
help: skipping check that does not even have a feature gate
76-
--> $DIR/mutable_references.rs:14:23
98+
--> $DIR/mutable_references.rs:15:23
7799
|
78100
LL | static BAR: &mut () = &mut ();
79101
| ^^^^^^^
80102
help: skipping check that does not even have a feature gate
81-
--> $DIR/mutable_references.rs:20:28
103+
--> $DIR/mutable_references.rs:21:28
82104
|
83105
LL | static BOO: &mut Foo<()> = &mut Foo(());
84106
| ^^^^^^^^^^^^
85107
help: skipping check that does not even have a feature gate
86-
--> $DIR/mutable_references.rs:28:28
108+
--> $DIR/mutable_references.rs:29:28
87109
|
88110
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
89111
| ^^^^^^^^^^^^^^^^^^^^
90112
help: skipping check that does not even have a feature gate
91-
--> $DIR/mutable_references.rs:32:27
113+
--> $DIR/mutable_references.rs:34:27
92114
|
93115
LL | static OH_YES: &mut i32 = &mut 42;
94116
| ^^^^^^^
95117

96-
error: aborting due to 7 previous errors; 1 warning emitted
118+
error: aborting due to 9 previous errors; 1 warning emitted
97119

98120
Some errors have detailed explanations: E0080, E0594.
99121
For more information about an error, try `rustc --explain E0080`.
@@ -114,7 +136,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)]
114136

115137
Future breakage diagnostic:
116138
error: encountered mutable pointer in final value of static
117-
--> $DIR/mutable_references.rs:14:1
139+
--> $DIR/mutable_references.rs:15:1
118140
|
119141
LL | static BAR: &mut () = &mut ();
120142
| ^^^^^^^^^^^^^^^^^^^
@@ -129,7 +151,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)]
129151

130152
Future breakage diagnostic:
131153
error: encountered mutable pointer in final value of static
132-
--> $DIR/mutable_references.rs:20:1
154+
--> $DIR/mutable_references.rs:21:1
133155
|
134156
LL | static BOO: &mut Foo<()> = &mut Foo(());
135157
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +166,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)]
144166

145167
Future breakage diagnostic:
146168
error: encountered mutable pointer in final value of static
147-
--> $DIR/mutable_references.rs:28:1
169+
--> $DIR/mutable_references.rs:29:1
148170
|
149171
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
150172
| ^^^^^^^^^^^^^^^
@@ -159,7 +181,7 @@ LL | #![deny(const_eval_mutable_ptr_in_final_value)]
159181

160182
Future breakage diagnostic:
161183
error: encountered mutable pointer in final value of static
162-
--> $DIR/mutable_references.rs:32:1
184+
--> $DIR/mutable_references.rs:34:1
163185
|
164186
LL | static OH_YES: &mut i32 = &mut 42;
165187
| ^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)