From 93562dcec038ac3dceb91f67b5dd429ed02748d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 16 Mar 2024 06:00:05 +0100 Subject: [PATCH] Use `UnsafeCell` for fast constant thread locals --- library/std/src/sys/thread_local/fast_local.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs index 646dcd7f3a3e8..5b62d21af7951 100644 --- a/library/std/src/sys/thread_local/fast_local.rs +++ b/library/std/src/sys/thread_local/fast_local.rs @@ -22,13 +22,15 @@ pub macro thread_local_inner { const INIT_EXPR: $t = $init; // If the platform has support for `#[thread_local]`, use it. #[thread_local] - static mut VAL: $t = INIT_EXPR; + // We use `UnsafeCell` here instead of `static mut` to ensure any generated TLS shims + // have a nonnull attribute on their return value. + static VAL: $crate::cell::UnsafeCell<$t> = $crate::cell::UnsafeCell::new(INIT_EXPR); // If a dtor isn't needed we can do something "very raw" and // just get going. if !$crate::mem::needs_drop::<$t>() { unsafe { - return $crate::option::Option::Some(&VAL) + return $crate::option::Option::Some(&*VAL.get()) } } @@ -55,15 +57,15 @@ pub macro thread_local_inner { // so now. 0 => { $crate::thread::local_impl::Key::<$t>::register_dtor( - $crate::ptr::addr_of_mut!(VAL) as *mut $crate::primitive::u8, + VAL.get() as *mut $crate::primitive::u8, destroy, ); STATE.set(1); - $crate::option::Option::Some(&VAL) + $crate::option::Option::Some(&*VAL.get()) } // 1 == the destructor is registered and the value // is valid, so return the pointer. - 1 => $crate::option::Option::Some(&VAL), + 1 => $crate::option::Option::Some(&*VAL.get()), // otherwise the destructor has already run, so we // can't give access. _ => $crate::option::Option::None,