about summary refs log tree commit diff
path: root/src/librustc_mir/interpret
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-05-02 21:44:25 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-05-30 12:59:05 +0200
commit0aa7f4d2f2ff55b8cfe5de5e4e7665a8fdeaf050 (patch)
tree1aa0aed21020a916efac714459a6ba07c6f82f06 /src/librustc_mir/interpret
parent0e9e4083100aa3ebf09b8f1ace0348cb37475eb9 (diff)
downloadrust-0aa7f4d2f2ff55b8cfe5de5e4e7665a8fdeaf050.tar.gz
rust-0aa7f4d2f2ff55b8cfe5de5e4e7665a8fdeaf050.zip
Make TLS accesses explicit in MIR
Diffstat (limited to 'src/librustc_mir/interpret')
-rw-r--r--src/librustc_mir/interpret/machine.rs7
-rw-r--r--src/librustc_mir/interpret/memory.rs2
-rw-r--r--src/librustc_mir/interpret/step.rs6
-rw-r--r--src/librustc_mir/interpret/validity.rs1
4 files changed, 16 insertions, 0 deletions
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 39b0218c5d7..b5dc40d9551 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -358,6 +358,13 @@ pub trait Machine<'mir, 'tcx>: Sized {
         _mem: &Memory<'mir, 'tcx, Self>,
         _ptr: Pointer<Self::PointerTag>,
     ) -> InterpResult<'tcx, u64>;
+
+    fn thread_local_alloc_id(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        did: DefId,
+    ) -> InterpResult<'tcx, AllocId> {
+        throw_unsup!(ThreadLocalStatic(did))
+    }
 }
 
 // A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 61c365644c7..d7f64542aa7 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -437,6 +437,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)),
             None => throw_ub!(PointerUseAfterFree(id)),
             Some(GlobalAlloc::Static(def_id)) => {
+                assert!(!tcx.is_thread_local_static(def_id));
                 // Notice that every static has two `AllocId` that will resolve to the same
                 // thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID,
                 // and the other one is maps to `GlobalAlloc::Memory`, this is returned by
@@ -592,6 +593,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // be held throughout the match.
         match self.tcx.get_global_alloc(id) {
             Some(GlobalAlloc::Static(did)) => {
+                assert!(!self.tcx.is_thread_local_static(did));
                 // Use size and align of the type.
                 let ty = self.tcx.type_of(did);
                 let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index fd9815975c1..c15714260dc 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -141,6 +141,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         use rustc_middle::mir::Rvalue::*;
         match *rvalue {
+            ThreadLocalRef(did) => {
+                let id = M::thread_local_alloc_id(self, did)?;
+                let val = Scalar::Ptr(self.tag_global_base_pointer(id.into()));
+                self.write_scalar(val, dest)?;
+            }
+
             Use(ref operand) => {
                 // Avoid recomputing the layout
                 let op = self.eval_operand(operand, Some(dest.layout))?;
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index e962dfb2b3e..b6676e8263e 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -418,6 +418,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 // Skip validation entirely for some external statics
                 let alloc_kind = self.ecx.tcx.get_global_alloc(ptr.alloc_id);
                 if let Some(GlobalAlloc::Static(did)) = alloc_kind {
+                    assert!(!self.ecx.tcx.is_thread_local_static(did));
                     // See const_eval::machine::MemoryExtra::can_access_statics for why
                     // this check is so important.
                     // This check is reachable when the const just referenced the static,