]> git.lizzy.rs Git - rust.git/commitdiff
tighten CTFE safety net for accesses to globals
authorRalf Jung <post@ralfj.de>
Thu, 9 Apr 2020 09:32:43 +0000 (11:32 +0200)
committerRalf Jung <post@ralfj.de>
Thu, 9 Apr 2020 09:54:45 +0000 (11:54 +0200)
src/librustc_mir/const_eval/machine.rs

index e92634714789495b383426a3d58b654235544f9d..3d0c5ffae5210bc162caa16919d1e429b933b23a 100644 (file)
@@ -350,15 +350,30 @@ fn before_access_global(
         static_def_id: Option<DefId>,
         is_write: bool,
     ) -> InterpResult<'tcx> {
-        if is_write && allocation.mutability == Mutability::Not {
-            Err(err_ub!(WriteToReadOnly(alloc_id)).into())
-        } else if is_write {
-            Err(ConstEvalErrKind::ModifiedGlobal.into())
-        } else if memory_extra.can_access_statics || static_def_id.is_none() {
-            // `static_def_id.is_none()` indicates this is not a static, but a const or so.
-            Ok(())
+        if is_write {
+            // Write access. These are never allowed, but we give a targeted error message.
+            if allocation.mutability == Mutability::Not {
+                Err(err_ub!(WriteToReadOnly(alloc_id)).into())
+            } else {
+                Err(ConstEvalErrKind::ModifiedGlobal.into())
+            }
         } else {
-            Err(ConstEvalErrKind::ConstAccessesStatic.into())
+            // Read access. These are usually allowed, with some exceptions.
+            if memory_extra.can_access_statics {
+                // This is allowed to read from anything.
+                Ok(())
+            } else if allocation.mutability == Mutability::Mut || static_def_id.is_some() {
+                // This is a potentially dangerous read.
+                // We *must* error on any access to a mutable global here, as the content of
+                // this allocation may be different now and at run-time, so if we permit reading
+                // now we might return the wrong value.
+                // We conservatively also reject all statics here, but that could be relaxed
+                // in the future.
+                Err(ConstEvalErrKind::ConstAccessesStatic.into())
+            } else {
+                // Immutable global, this read is fine.
+                Ok(())
+            }
         }
     }
 }