Skip to content

Commit 59eff14

Browse files
committed
Also catch static mutation at evaluation time
1 parent bc543d7 commit 59eff14

15 files changed

+82
-35
lines changed

src/librustc/ich/impls_ty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl_stable_hash_for!(
423423
CalledClosureAsFunction,
424424
VtableForArgumentlessMethod,
425425
ModifiedConstantMemory,
426+
ModifiedStatic,
426427
AssumptionNotHeld,
427428
InlineAsm,
428429
ReallocateNonBasePtr,

src/librustc/mir/interpret/error.rs

+3
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ pub enum EvalErrorKind<'tcx, O> {
276276
CalledClosureAsFunction,
277277
VtableForArgumentlessMethod,
278278
ModifiedConstantMemory,
279+
ModifiedStatic,
279280
AssumptionNotHeld,
280281
InlineAsm,
281282
TypeNotPrimitive(Ty<'tcx>),
@@ -380,6 +381,8 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
380381
"tried to call a vtable function without arguments",
381382
ModifiedConstantMemory =>
382383
"tried to modify constant memory",
384+
ModifiedStatic =>
385+
"tried to modify a static's initial value from another static's initializer",
383386
AssumptionNotHeld =>
384387
"`assume` argument was false",
385388
InlineAsm =>

src/librustc_mir/interpret/memory.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
423423
if alloc.mutability == Mutability::Immutable {
424424
return err!(ModifiedConstantMemory);
425425
}
426-
let kind = M::STATIC_KIND.expect(
427-
"An allocation is being mutated but the machine does not expect that to happen"
428-
);
429-
Ok((MemoryKind::Machine(kind), alloc.into_owned()))
426+
match M::STATIC_KIND {
427+
Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())),
428+
None => err!(ModifiedStatic),
429+
}
430430
});
431431
// Unpack the error type manually because type inference doesn't
432432
// work otherwise (and we cannot help it because `impl Trait`)

src/librustc_mir/transform/const_prop.rs

+1
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
197197
| CalledClosureAsFunction
198198
| VtableForArgumentlessMethod
199199
| ModifiedConstantMemory
200+
| ModifiedStatic
200201
| AssumptionNotHeld
201202
// FIXME: should probably be removed and turned into a bug! call
202203
| TypeNotPrimitive(_)

src/librustc_mir/transform/qualify_consts.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
249249
match dest {
250250
Place::Local(index) => break *index,
251251
Place::Projection(proj) => dest = &proj.base,
252-
Place::Promoted(..) | Place::Static(..) => {
252+
Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
253+
Place::Static(..) => {
253254
// Catch more errors in the destination.
254255
self.visit_place(
255256
dest,
@@ -495,6 +496,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
495496
// Only allow statics (not consts) to refer to other statics.
496497
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
497498
if context.is_mutating_use() {
499+
// this is not strictly necessary as miri will also bail out
500+
// For interior mutability we can't really catch this statically as that
501+
// goes through raw pointers and intermediate temporaries, so miri has
502+
// to catch this anyway
498503
self.tcx.sess.span_err(
499504
self.span,
500505
"cannot mutate statics in the initializer of another static",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// New test for #53818: modifying static memory at compile-time is not allowed.
12+
// The test should never compile successfully
13+
14+
#![feature(const_raw_ptr_deref)]
15+
#![feature(const_let)]
16+
17+
use std::cell::UnsafeCell;
18+
19+
struct Foo(UnsafeCell<u32>);
20+
21+
unsafe impl Send for Foo {}
22+
unsafe impl Sync for Foo {}
23+
24+
static FOO: Foo = Foo(UnsafeCell::new(42));
25+
26+
static BAR: () = unsafe {
27+
*FOO.0.get() = 5; //~ ERROR could not evaluate static initializer
28+
};
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: could not evaluate static initializer
2+
--> $DIR/assign-to-static-within-other-static-2.rs:27:5
3+
|
4+
LL | *FOO.0.get() = 5; //~ ERROR could not evaluate static initializer
5+
| ^^^^^^^^^^^^^^^^ tried to modify a static's initial value from another static's initializer
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs

+3-14
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,9 @@
1616

1717
use std::cell::UnsafeCell;
1818

19-
struct Foo(UnsafeCell<u32>);
20-
21-
unsafe impl Send for Foo {}
22-
unsafe impl Sync for Foo {}
23-
24-
static FOO: Foo = Foo(UnsafeCell::new(42));
25-
26-
static BAR: () = unsafe {
27-
*FOO.0.get() = 5;
28-
};
29-
30-
static mut FOO2: u32 = 42;
31-
static BOO2: () = unsafe {
32-
FOO2 = 5;
19+
static mut FOO: u32 = 42;
20+
static BOO: () = unsafe {
21+
FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
3322
};
3423

3524
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: cannot mutate statics in the initializer of another static
2-
--> $DIR/assign-to-static-within-other-static.rs:32:5
2+
--> $DIR/assign-to-static-within-other-static.rs:21:5
33
|
4-
LL | FOO2 = 5;
5-
| ^^^^^^^^
4+
LL | FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
5+
| ^^^^^^^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0017.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ const C: i32 = 2;
1414
const CR: &'static mut i32 = &mut C; //~ ERROR E0017
1515
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
1616
//~| ERROR cannot borrow
17+
//~| ERROR cannot mutate statics
1718
static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
1819
fn main() {}

src/test/ui/error-codes/E0017.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error[E0017]: references in constants may only refer to immutable values
44
LL | const CR: &'static mut i32 = &mut C; //~ ERROR E0017
55
| ^^^^^^ constants require immutable values
66

7+
error: cannot mutate statics in the initializer of another static
8+
--> $DIR/E0017.rs:15:39
9+
|
10+
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
11+
| ^^^^^^
12+
713
error[E0017]: references in statics may only refer to immutable values
814
--> $DIR/E0017.rs:15:39
915
|
@@ -17,12 +23,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
1723
| ^
1824

1925
error[E0017]: references in statics may only refer to immutable values
20-
--> $DIR/E0017.rs:17:38
26+
--> $DIR/E0017.rs:18:38
2127
|
2228
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
2329
| ^^^^^^ statics require immutable values
2430

25-
error: aborting due to 4 previous errors
31+
error: aborting due to 5 previous errors
2632

2733
Some errors occurred: E0017, E0596.
2834
For more information about an error, try `rustc --explain E0017`.

src/test/ui/error-codes/E0388.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const C: i32 = 2;
1414
const CR: &'static mut i32 = &mut C; //~ ERROR E0017
1515
static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
1616
//~| ERROR cannot borrow
17+
//~| ERROR cannot mutate statics
1718
static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
1819

1920
fn main() {}

src/test/ui/error-codes/E0388.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error[E0017]: references in constants may only refer to immutable values
44
LL | const CR: &'static mut i32 = &mut C; //~ ERROR E0017
55
| ^^^^^^ constants require immutable values
66

7+
error: cannot mutate statics in the initializer of another static
8+
--> $DIR/E0388.rs:15:39
9+
|
10+
LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
11+
| ^^^^^^
12+
713
error[E0017]: references in statics may only refer to immutable values
814
--> $DIR/E0388.rs:15:39
915
|
@@ -17,12 +23,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
1723
| ^
1824

1925
error[E0017]: references in statics may only refer to immutable values
20-
--> $DIR/E0388.rs:17:38
26+
--> $DIR/E0388.rs:18:38
2127
|
2228
LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
2329
| ^^^^^^ statics require immutable values
2430

25-
error: aborting due to 4 previous errors
31+
error: aborting due to 5 previous errors
2632

2733
Some errors occurred: E0017, E0596.
2834
For more information about an error, try `rustc --explain E0017`.

src/test/ui/write-to-static-mut-in-static.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
pub static mut A: u32 = 0;
1414
pub static mut B: () = unsafe { A = 1; };
15-
//~^ ERROR statements in statics are unstable
15+
//~^ ERROR cannot mutate statics in the initializer of another static
1616

1717
pub static mut C: u32 = unsafe { C = 1; 0 };
18-
//~^ ERROR statements in statics are unstable
18+
//~^ ERROR cannot mutate statics in the initializer of another static
1919

2020
pub static D: u32 = D;
2121

Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
error[E0658]: statements in statics are unstable (see issue #48821)
1+
error: cannot mutate statics in the initializer of another static
22
--> $DIR/write-to-static-mut-in-static.rs:14:33
33
|
44
LL | pub static mut B: () = unsafe { A = 1; };
55
| ^^^^^
6-
|
7-
= help: add #![feature(const_let)] to the crate attributes to enable
86

9-
error[E0658]: statements in statics are unstable (see issue #48821)
7+
error: cannot mutate statics in the initializer of another static
108
--> $DIR/write-to-static-mut-in-static.rs:17:34
119
|
1210
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
1311
| ^^^^^
14-
|
15-
= help: add #![feature(const_let)] to the crate attributes to enable
1612

1713
error: aborting due to 2 previous errors
1814

19-
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)