about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-19 13:49:07 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-19 16:46:03 +0100
commit59eff14120a067d04832142c8198f0132db2acb0 (patch)
tree28fc4e62adb89b04e76c4215c59d6cb2720924f1
parentbc543d7e6c4c87f99eea4dc6217eee54cd7f18b1 (diff)
downloadrust-59eff14120a067d04832142c8198f0132db2acb0.tar.gz
rust-59eff14120a067d04832142c8198f0132db2acb0.zip
Also catch static mutation at evaluation time
-rw-r--r--src/librustc/ich/impls_ty.rs1
-rw-r--r--src/librustc/mir/interpret/error.rs3
-rw-r--r--src/librustc_mir/interpret/memory.rs8
-rw-r--r--src/librustc_mir/transform/const_prop.rs1
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs7
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs30
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr9
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs17
-rw-r--r--src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr6
-rw-r--r--src/test/ui/error-codes/E0017.rs1
-rw-r--r--src/test/ui/error-codes/E0017.stderr10
-rw-r--r--src/test/ui/error-codes/E0388.rs1
-rw-r--r--src/test/ui/error-codes/E0388.stderr10
-rw-r--r--src/test/ui/write-to-static-mut-in-static.rs4
-rw-r--r--src/test/ui/write-to-static-mut-in-static.stderr9
15 files changed, 82 insertions, 35 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index f3a62975dd9..fc970400f6c 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -423,6 +423,7 @@ impl_stable_hash_for!(
         CalledClosureAsFunction,
         VtableForArgumentlessMethod,
         ModifiedConstantMemory,
+        ModifiedStatic,
         AssumptionNotHeld,
         InlineAsm,
         ReallocateNonBasePtr,
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index f28aa41ed42..5895b6cab9a 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -276,6 +276,7 @@ pub enum EvalErrorKind<'tcx, O> {
     CalledClosureAsFunction,
     VtableForArgumentlessMethod,
     ModifiedConstantMemory,
+    ModifiedStatic,
     AssumptionNotHeld,
     InlineAsm,
     TypeNotPrimitive(Ty<'tcx>),
@@ -380,6 +381,8 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
                 "tried to call a vtable function without arguments",
             ModifiedConstantMemory =>
                 "tried to modify constant memory",
+            ModifiedStatic =>
+                "tried to modify a static's initial value from another static's initializer",
             AssumptionNotHeld =>
                 "`assume` argument was false",
             InlineAsm =>
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index e125927e7d2..68a91b0a3bd 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -423,10 +423,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
             if alloc.mutability == Mutability::Immutable {
                 return err!(ModifiedConstantMemory);
             }
-            let kind = M::STATIC_KIND.expect(
-                "An allocation is being mutated but the machine does not expect that to happen"
-            );
-            Ok((MemoryKind::Machine(kind), alloc.into_owned()))
+            match M::STATIC_KIND {
+                Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())),
+                None => err!(ModifiedStatic),
+            }
         });
         // Unpack the error type manually because type inference doesn't
         // work otherwise (and we cannot help it because `impl Trait`)
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 885d70dc430..51327464266 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -197,6 +197,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
                     | CalledClosureAsFunction
                     | VtableForArgumentlessMethod
                     | ModifiedConstantMemory
+                    | ModifiedStatic
                     | AssumptionNotHeld
                     // FIXME: should probably be removed and turned into a bug! call
                     | TypeNotPrimitive(_)
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 31a0dc1494c..1371b9a9977 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -249,7 +249,8 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
                 match dest {
                     Place::Local(index) => break *index,
                     Place::Projection(proj) => dest = &proj.base,
-                    Place::Promoted(..) | Place::Static(..) => {
+                    Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
+                    Place::Static(..) => {
                         // Catch more errors in the destination.
                         self.visit_place(
                             dest,
@@ -495,6 +496,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 // Only allow statics (not consts) to refer to other statics.
                 if self.mode == Mode::Static || self.mode == Mode::StaticMut {
                     if context.is_mutating_use() {
+                        // this is not strictly necessary as miri will also bail out
+                        // For interior mutability we can't really catch this statically as that
+                        // goes through raw pointers and intermediate temporaries, so miri has
+                        // to catch this anyway
                         self.tcx.sess.span_err(
                             self.span,
                             "cannot mutate statics in the initializer of another static",
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
new file mode 100644
index 00000000000..ef0de61d219
--- /dev/null
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
@@ -0,0 +1,30 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// New test for #53818: modifying static memory at compile-time is not allowed.
+// The test should never compile successfully
+
+#![feature(const_raw_ptr_deref)]
+#![feature(const_let)]
+
+use std::cell::UnsafeCell;
+
+struct Foo(UnsafeCell<u32>);
+
+unsafe impl Send for Foo {}
+unsafe impl Sync for Foo {}
+
+static FOO: Foo = Foo(UnsafeCell::new(42));
+
+static BAR: () = unsafe {
+    *FOO.0.get() = 5; //~ ERROR could not evaluate static initializer
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
new file mode 100644
index 00000000000..0892b05a69d
--- /dev/null
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+  --> $DIR/assign-to-static-within-other-static-2.rs:27:5
+   |
+LL |     *FOO.0.get() = 5; //~ ERROR could not evaluate static initializer
+   |     ^^^^^^^^^^^^^^^^ tried to modify a static's initial value from another static's initializer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
index 5113d73b384..6f16f644eec 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
@@ -16,20 +16,9 @@
 
 use std::cell::UnsafeCell;
 
-struct Foo(UnsafeCell<u32>);
-
-unsafe impl Send for Foo {}
-unsafe impl Sync for Foo {}
-
-static FOO: Foo = Foo(UnsafeCell::new(42));
-
-static BAR: () = unsafe {
-    *FOO.0.get() = 5;
-};
-
-static mut FOO2: u32 = 42;
-static BOO2: () = unsafe {
-    FOO2 = 5;
+static mut FOO: u32 = 42;
+static BOO: () = unsafe {
+    FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
 };
 
 fn main() {}
diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
index 87f02e8e4cf..ca652c9df32 100644
--- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
+++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
@@ -1,8 +1,8 @@
 error: cannot mutate statics in the initializer of another static
-  --> $DIR/assign-to-static-within-other-static.rs:32:5
+  --> $DIR/assign-to-static-within-other-static.rs:21:5
    |
-LL |     FOO2 = 5;
-   |     ^^^^^^^^
+LL |     FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
+   |     ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs
index c98c35a1442..bf400fde365 100644
--- a/src/test/ui/error-codes/E0017.rs
+++ b/src/test/ui/error-codes/E0017.rs
@@ -14,5 +14,6 @@ const C: i32 = 2;
 const CR: &'static mut i32 = &mut C; //~ ERROR E0017
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
                                               //~| ERROR cannot borrow
+                                              //~| ERROR cannot mutate statics
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
 fn main() {}
diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr
index 411b9f31397..94a90d92d3e 100644
--- a/src/test/ui/error-codes/E0017.stderr
+++ b/src/test/ui/error-codes/E0017.stderr
@@ -4,6 +4,12 @@ error[E0017]: references in constants may only refer to immutable values
 LL | const CR: &'static mut i32 = &mut C; //~ ERROR E0017
    |                              ^^^^^^ constants require immutable values
 
+error: cannot mutate statics in the initializer of another static
+  --> $DIR/E0017.rs:15:39
+   |
+LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
+   |                                       ^^^^^^
+
 error[E0017]: references in statics may only refer to immutable values
   --> $DIR/E0017.rs:15:39
    |
@@ -17,12 +23,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                            ^
 
 error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0017.rs:17:38
+  --> $DIR/E0017.rs:18:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
    |                                      ^^^^^^ statics require immutable values
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors occurred: E0017, E0596.
 For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs
index c002badfef6..3203798c709 100644
--- a/src/test/ui/error-codes/E0388.rs
+++ b/src/test/ui/error-codes/E0388.rs
@@ -14,6 +14,7 @@ const C: i32 = 2;
 const CR: &'static mut i32 = &mut C; //~ ERROR E0017
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
                                               //~| ERROR cannot borrow
+                                              //~| ERROR cannot mutate statics
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr
index d2263cd4034..46efda9147b 100644
--- a/src/test/ui/error-codes/E0388.stderr
+++ b/src/test/ui/error-codes/E0388.stderr
@@ -4,6 +4,12 @@ error[E0017]: references in constants may only refer to immutable values
 LL | const CR: &'static mut i32 = &mut C; //~ ERROR E0017
    |                              ^^^^^^ constants require immutable values
 
+error: cannot mutate statics in the initializer of another static
+  --> $DIR/E0388.rs:15:39
+   |
+LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
+   |                                       ^^^^^^
+
 error[E0017]: references in statics may only refer to immutable values
   --> $DIR/E0388.rs:15:39
    |
@@ -17,12 +23,12 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                            ^
 
 error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0388.rs:17:38
+  --> $DIR/E0388.rs:18:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
    |                                      ^^^^^^ statics require immutable values
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors occurred: E0017, E0596.
 For more information about an error, try `rustc --explain E0017`.
diff --git a/src/test/ui/write-to-static-mut-in-static.rs b/src/test/ui/write-to-static-mut-in-static.rs
index 1ea74f73723..191f09b54ee 100644
--- a/src/test/ui/write-to-static-mut-in-static.rs
+++ b/src/test/ui/write-to-static-mut-in-static.rs
@@ -12,10 +12,10 @@
 
 pub static mut A: u32 = 0;
 pub static mut B: () = unsafe { A = 1; };
-//~^ ERROR statements in statics are unstable
+//~^ ERROR cannot mutate statics in the initializer of another static
 
 pub static mut C: u32 = unsafe { C = 1; 0 };
-//~^ ERROR statements in statics are unstable
+//~^ ERROR cannot mutate statics in the initializer of another static
 
 pub static D: u32 = D;
 
diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr
index f07d240746f..673a71b4642 100644
--- a/src/test/ui/write-to-static-mut-in-static.stderr
+++ b/src/test/ui/write-to-static-mut-in-static.stderr
@@ -1,19 +1,14 @@
-error[E0658]: statements in statics are unstable (see issue #48821)
+error: cannot mutate statics in the initializer of another static
   --> $DIR/write-to-static-mut-in-static.rs:14:33
    |
 LL | pub static mut B: () = unsafe { A = 1; };
    |                                 ^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
 
-error[E0658]: statements in statics are unstable (see issue #48821)
+error: cannot mutate statics in the initializer of another static
   --> $DIR/write-to-static-mut-in-static.rs:17:34
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    |                                  ^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.