| //@ check-pass | |
| //@ known-bug: #49682 | |
| //@ edition:2021 | |
| // Should fail. Keeping references to thread local statics can result in a | |
| // use-after-free. | |
| #![feature(thread_local)] | |
| use std::sync::atomic::{AtomicUsize, Ordering}; | |
| use std::thread; | |
| #[allow(dead_code)] | |
| #[thread_local] | |
| static FOO: AtomicUsize = AtomicUsize::new(0); | |
| #[allow(dead_code)] | |
| async fn bar() {} | |
| #[allow(dead_code)] | |
| async fn foo() { | |
| let r = &FOO; | |
| bar().await; | |
| r.load(Ordering::SeqCst); | |
| } | |
| fn main() { | |
| // &FOO = 0x7fd1e9cbf6d0 | |
| _ = thread::spawn(|| { | |
| let g = foo(); | |
| println!("&FOO = {:p}", &FOO); | |
| g | |
| }) | |
| .join() | |
| .unwrap(); | |
| // &FOO = 0x7fd1e9cc0f50 | |
| println!("&FOO = {:p}", &FOO); | |
| // &FOO = 0x7fd1e9cbf6d0 | |
| thread::spawn(move || { | |
| println!("&FOO = {:p}", &FOO); | |
| }) | |
| .join() | |
| .unwrap(); | |
| } |