From 763ff1c49fd6671d64709fe269c2d3a130dce4a6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 19 Apr 2022 14:56:07 -0400 Subject: [PATCH] do not consider thread-local allocations read-only --- src/thread.rs | 7 +++++-- tests/run-pass/concurrency/thread_locals.rs | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/thread.rs b/src/thread.rs index 96131dba3ca6..27bc9566d8fd 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -10,6 +10,7 @@ use log::trace; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::mir::Mutability; use crate::sync::SynchronizationState; use crate::*; @@ -571,9 +572,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx throw_unsup_format!("foreign thread-local statics are not supported"); } let allocation = tcx.eval_static_initializer(def_id)?; + let mut allocation = allocation.inner().clone(); + // This allocation will be deallocated when the thread dies, so it is not in read-only memory. + allocation.mutability = Mutability::Mut; // Create a fresh allocation with this content. - let new_alloc = - this.allocate_raw_ptr(allocation.inner().clone(), MiriMemoryKind::Tls.into()); + let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into()); this.machine.threads.set_thread_local_alloc(def_id, new_alloc); Ok(new_alloc) } diff --git a/tests/run-pass/concurrency/thread_locals.rs b/tests/run-pass/concurrency/thread_locals.rs index 7938284bd634..5b11539f7f11 100644 --- a/tests/run-pass/concurrency/thread_locals.rs +++ b/tests/run-pass/concurrency/thread_locals.rs @@ -16,6 +16,10 @@ static mut A: u8 = 0; static mut B: u8 = 0; static mut C: u8 = 0; +// Regression test for https://github.com/rust-lang/rust/issues/96191. +#[thread_local] +static READ_ONLY: u8 = 42; + unsafe fn get_a_ref() -> *mut u8 { &mut A } @@ -25,6 +29,8 @@ struct Sender(*mut u8); unsafe impl Send for Sender {} fn main() { + let _val = READ_ONLY; + let ptr = unsafe { let x = get_a_ref(); *x = 5;