diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ed351354c441d..4bec6c7791a21 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -156,7 +156,7 @@ impl Step for RustbookSrc { let index = out.join("index.html"); let rustbook = builder.tool_exe(Tool::Rustbook); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - if up_to_date(&src, &index) && up_to_date(&rustbook, &index) { + if builder.config.dry_run || up_to_date(&src, &index) && up_to_date(&rustbook, &index) { return; } builder.info(&format!("Rustbook ({}) - {}", target, name)); diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 773fab36be221..5b712e2024232 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -78,19 +78,20 @@ mod imp { use crate::marker::PhantomData; use crate::os::unix::prelude::*; use crate::ptr; + use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering}; use crate::sys_common::mutex::Mutex; - static mut ARGC: isize = 0; - static mut ARGV: *const *const u8 = ptr::null(); + static ARGC: AtomicIsize = AtomicIsize::new(0); + static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut()); // We never call `ENV_LOCK.init()`, so it is UB to attempt to // acquire this mutex reentrantly! static LOCK: Mutex = Mutex::new(); unsafe fn really_init(argc: isize, argv: *const *const u8) { let _guard = LOCK.lock(); - ARGC = argc; - ARGV = argv; + ARGC.store(argc, Ordering::Relaxed); + ARGV.store(argv as *mut _, Ordering::Relaxed); } #[inline(always)] @@ -126,8 +127,8 @@ mod imp { pub unsafe fn cleanup() { let _guard = LOCK.lock(); - ARGC = 0; - ARGV = ptr::null(); + ARGC.store(0, Ordering::Relaxed); + ARGV.store(ptr::null_mut(), Ordering::Relaxed); } pub fn args() -> Args { @@ -137,9 +138,11 @@ mod imp { fn clone() -> Vec { unsafe { let _guard = LOCK.lock(); - (0..ARGC) + let argc = ARGC.load(Ordering::Relaxed); + let argv = ARGV.load(Ordering::Relaxed); + (0..argc) .map(|i| { - let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char); + let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char); OsStringExt::from_vec(cstr.to_bytes().to_vec()) }) .collect() diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 5e10357835056..c74fc2b590316 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -48,6 +48,7 @@ mod imp { use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE}; use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV}; + use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering}; use crate::sys::unix::os::page_size; use crate::sys_common::thread_info; @@ -113,8 +114,8 @@ mod imp { } } - static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut(); - static mut NEED_ALTSTACK: bool = false; + static MAIN_ALTSTACK: AtomicPtr = AtomicPtr::new(ptr::null_mut()); + static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false); pub unsafe fn init() { let mut action: sigaction = mem::zeroed(); @@ -125,17 +126,17 @@ mod imp { action.sa_flags = SA_SIGINFO | SA_ONSTACK; action.sa_sigaction = signal_handler as sighandler_t; sigaction(signal, &action, ptr::null_mut()); - NEED_ALTSTACK = true; + NEED_ALTSTACK.store(true, Ordering::Relaxed); } } let handler = make_handler(); - MAIN_ALTSTACK = handler._data; + MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed); mem::forget(handler); } pub unsafe fn cleanup() { - Handler { _data: MAIN_ALTSTACK }; + Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) }; } unsafe fn get_stackp() -> *mut libc::c_void { @@ -176,7 +177,7 @@ mod imp { } pub unsafe fn make_handler() -> Handler { - if !NEED_ALTSTACK { + if !NEED_ALTSTACK.load(Ordering::Relaxed) { return Handler::null(); } let mut stack = mem::zeroed(); diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 7b3d69dcaa015..c1bda6b430e13 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -246,10 +246,11 @@ pub mod guard { use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; use crate::ops::Range; + use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::os; // This is initialized in init() and only read from after - static mut PAGE_SIZE: usize = 0; + static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); pub type Guard = Range; @@ -275,7 +276,7 @@ pub mod guard { let stackaddr = if libc::pthread_main_np() == 1 { // main thread - current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE + current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed) } else { // new thread current_stack.ss_sp as usize - current_stack.ss_size @@ -310,7 +311,8 @@ pub mod guard { // Precondition: PAGE_SIZE is initialized. unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { - assert!(PAGE_SIZE != 0); + let page_size = PAGE_SIZE.load(Ordering::Relaxed); + assert!(page_size != 0); let stackaddr = get_stack_start()?; // Ensure stackaddr is page aligned! A parent process might @@ -319,16 +321,17 @@ pub mod guard { // stackaddr < stackaddr + stacksize, so if stackaddr is not // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize - let remainder = (stackaddr as usize) % PAGE_SIZE; + let remainder = (stackaddr as usize) % page_size; Some(if remainder == 0 { stackaddr } else { - ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void + ((stackaddr as usize) + page_size - remainder) as *mut libc::c_void }) } pub unsafe fn init() -> Option { - PAGE_SIZE = os::page_size(); + let page_size = os::page_size(); + PAGE_SIZE.store(page_size, Ordering::Relaxed); let stackaddr = get_stack_start_aligned()?; @@ -344,7 +347,7 @@ pub mod guard { // faulting, so our handler can report "stack overflow", and // trust that the kernel's own stack guard will work. let stackaddr = stackaddr as usize; - Some(stackaddr - PAGE_SIZE..stackaddr) + Some(stackaddr - page_size..stackaddr) } else { // Reallocate the last page of the stack. // This ensures SIGBUS will be raised on @@ -356,7 +359,7 @@ pub mod guard { // no permissions at all. See issue #50313. let result = mmap( stackaddr, - PAGE_SIZE, + page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, @@ -366,7 +369,7 @@ pub mod guard { panic!("failed to allocate a guard page"); } - let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE); + let result = mprotect(stackaddr, page_size, PROT_NONE); if result != 0 { panic!("failed to protect the guard page"); } @@ -374,14 +377,14 @@ pub mod guard { let guardaddr = stackaddr as usize; let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 }; - Some(guardaddr..guardaddr + offset * PAGE_SIZE) + Some(guardaddr..guardaddr + offset * page_size) } } #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] pub unsafe fn current() -> Option { let stackaddr = get_stack_start()? as usize; - Some(stackaddr - PAGE_SIZE..stackaddr) + Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr) } #[cfg(any( @@ -413,7 +416,7 @@ pub mod guard { ret = if cfg!(target_os = "freebsd") { // FIXME does freebsd really fault *below* the guard addr? let guardaddr = stackaddr - guardsize; - Some(guardaddr - PAGE_SIZE..guardaddr) + Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr) } else if cfg!(target_os = "netbsd") { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "gnu")) { diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index c49997c6c33f6..136b33208c293 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -88,9 +88,10 @@ const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute //~^ ERROR is undefined behavior // All variants are uninhabited but also have data. -const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(1u64) }; +// Use `0` as constant to make behavior endianess-independent. +const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; //~^ ERROR is undefined behavior -const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(1u64) }; +const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; //~^ ERROR is undefined behavior fn main() { diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index 217bfb628a018..7b3ee535c8ec6 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -87,18 +87,18 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:91:1 + --> $DIR/ub-enum.rs:92:1 | -LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(1u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0.1 +LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0.1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:93:1 + --> $DIR/ub-enum.rs:94:1 | -LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(1u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at ..0.1 +LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at ..0.1 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index f5a4a4b46e706..8b0983e89ad9a 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit f5a4a4b46e706697abe4bd136503ecc09aa23b61 +Subproject commit 8b0983e89ad9a28b142eccf3755a8c9aaeb37852