mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-11-04 06:56:14 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			47 lines
		
	
	
		
			843 B
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			47 lines
		
	
	
		
			843 B
		
	
	
	
		
			Rust
		
	
	
	
	
	
//@ 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();
 | 
						|
}
 |