From 27011b4185f5341e579d2a02cabd3dc7d7aa7149 Mon Sep 17 00:00:00 2001 From: Michael Benfield Date: Tue, 6 Dec 2022 20:58:33 +0000 Subject: [PATCH 1/8] Use more LFS functions. On Linux, use mmap64, open64, openat64, and sendfile64 in place of their non-LFS counterparts. This is relevant to #94173. With these changes (together with rust-lang/backtrace-rs#501), the simple binaries I produce with rustc seem to have no non-LFS functions, so maybe #94173 is fixed. But I can't be sure if I've missed something and maybe some non-LFS functions could sneak in somehow. --- library/std/src/sys/unix/fs.rs | 7 ++++++- library/std/src/sys/unix/kernel_copy.rs | 6 +++++- library/std/src/sys/unix/mod.rs | 12 ++++++++++-- library/std/src/sys/unix/stack_overflow.rs | 7 +++++-- library/std/src/sys/unix/thread.rs | 7 +++++-- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 37a49f2d78acd..70fd7525225bf 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1743,8 +1743,13 @@ mod remove_dir_impl { use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::{cvt, cvt_r}; - #[cfg(not(all(target_os = "macos", not(target_arch = "aarch64")),))] + #[cfg(not(any( + target_os = "linux", + all(target_os = "macos", not(target_arch = "aarch64")) + )))] use libc::{fdopendir, openat, unlinkat}; + #[cfg(target_os = "linux")] + use libc::{fdopendir, openat64 as openat, unlinkat}; #[cfg(all(target_os = "macos", not(target_arch = "aarch64")))] use macos_weak::{fdopendir, openat, unlinkat}; diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs index 94546ca09d00d..6fa85e859c05b 100644 --- a/library/std/src/sys/unix/kernel_copy.rs +++ b/library/std/src/sys/unix/kernel_copy.rs @@ -61,6 +61,10 @@ use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use crate::sys::cvt; use crate::sys::weak::syscall; +#[cfg(not(target_os = "linux"))] +use libc::sendfile as sendfile64; +#[cfg(target_os = "linux")] +use libc::sendfile64; use libc::{EBADF, EINVAL, ENOSYS, EOPNOTSUPP, EOVERFLOW, EPERM, EXDEV}; #[cfg(test)] @@ -647,7 +651,7 @@ fn sendfile_splice(mode: SpliceMode, reader: RawFd, writer: RawFd, len: u64) -> let result = match mode { SpliceMode::Sendfile => { - cvt(unsafe { libc::sendfile(writer, reader, ptr::null_mut(), chunk_size) }) + cvt(unsafe { sendfile64(writer, reader, ptr::null_mut(), chunk_size) }) } SpliceMode::Splice => cvt(unsafe { splice(reader, ptr::null_mut(), writer, ptr::null_mut(), chunk_size, 0) diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 9055a011c515e..3d60941e84e39 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -95,6 +95,10 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { )))] 'poll: { use crate::sys::os::errno; + #[cfg(not(target_os = "linux"))] + use libc::open as open64; + #[cfg(target_os = "linux")] + use libc::open64; let pfds: &mut [_] = &mut [ libc::pollfd { fd: 0, events: 0, revents: 0 }, libc::pollfd { fd: 1, events: 0, revents: 0 }, @@ -116,7 +120,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { if pfd.revents & libc::POLLNVAL == 0 { continue; } - if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or @@ -139,9 +143,13 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { )))] { use crate::sys::os::errno; + #[cfg(not(target_os = "linux"))] + use libc::open as open64; + #[cfg(target_os = "linux")] + use libc::open64; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { - if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs index 75a5c0f927982..957e086798fd3 100644 --- a/library/std/src/sys/unix/stack_overflow.rs +++ b/library/std/src/sys/unix/stack_overflow.rs @@ -45,7 +45,10 @@ mod imp { use crate::thread; use libc::MAP_FAILED; - use libc::{mmap, munmap}; + #[cfg(not(target_os = "linux"))] + use libc::{mmap as mmap64, munmap}; + #[cfg(target_os = "linux")] + use libc::{mmap64, munmap}; use libc::{sigaction, sighandler_t, SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_DFL}; use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE}; use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV}; @@ -135,7 +138,7 @@ mod imp { #[cfg(not(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",)))] let flags = MAP_PRIVATE | MAP_ANON; let stackp = - mmap(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0); + mmap64(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0); if stackp == MAP_FAILED { panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error()); } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index c1d30dd9d521b..3f1568cbcc7e4 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -658,7 +658,10 @@ pub mod guard { ))] #[cfg_attr(test, allow(dead_code))] pub mod guard { - use libc::{mmap, mprotect}; + #[cfg(not(target_os = "linux"))] + use libc::{mmap as mmap64, mprotect}; + #[cfg(target_os = "linux")] + use libc::{mmap64, mprotect}; use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; use crate::io; @@ -808,7 +811,7 @@ pub mod guard { // read/write permissions and only then mprotect() it to // no permissions at all. See issue #50313. let stackptr = get_stack_start_aligned()?; - let result = mmap( + let result = mmap64( stackptr, page_size, PROT_READ | PROT_WRITE, From 6085d330339f6206cc449357db15d94328c207da Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sun, 11 Dec 2022 17:27:01 -0500 Subject: [PATCH 2/8] fix transmutes between pointers in different address spaces --- compiler/rustc_codegen_ssa/src/mir/block.rs | 13 +++++++---- src/test/codegen/avr/avr-func-addrspace.rs | 24 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index f3f5ddb52d6a4..eb42d4840d5c9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1810,15 +1810,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match (src.layout.abi, dst.layout.abi) { (abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => { // HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers. - if (src_scalar.primitive() == abi::Pointer) - == (dst_scalar.primitive() == abi::Pointer) - { + let src_is_ptr = src_scalar.primitive() == abi::Pointer; + let dst_is_ptr = dst_scalar.primitive() == abi::Pointer; + if src_is_ptr == dst_is_ptr { assert_eq!(src.layout.size, dst.layout.size); // NOTE(eddyb) the `from_immediate` and `to_immediate_scalar` // conversions allow handling `bool`s the same as `u8`s. let src = bx.from_immediate(src.immediate()); - let src_as_dst = bx.bitcast(src, bx.backend_type(dst.layout)); + // LLVM also doesn't like `bitcast`s between pointers in different address spaces. + let src_as_dst = if src_is_ptr { + bx.pointercast(src, bx.backend_type(dst.layout)) + } else { + bx.bitcast(src, bx.backend_type(dst.layout)) + }; Immediate(bx.to_immediate_scalar(src_as_dst, dst_scalar)).store(bx, dst); return; } diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index cbbcfad3ef483..e9740e30da483 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -9,7 +9,7 @@ // It also validates that functions can be called through function pointers // through traits. -#![feature(no_core, lang_items, unboxed_closures, arbitrary_self_types)] +#![feature(no_core, lang_items, intrinsics, unboxed_closures, arbitrary_self_types)] #![crate_type = "lib"] #![no_core] @@ -49,6 +49,10 @@ pub trait Fn: FnOnce { extern "rust-call" fn call(&self, args: Args) -> Self::Output; } +extern "rust-intrinsic" { + pub fn transmute(src: Src) -> Dst; +} + pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box; pub static mut STORAGE_BAR: u32 = 12; @@ -87,3 +91,21 @@ pub extern "C" fn test() { STORAGE_FOO(&1, &mut buf); } } + +// Validate that we can codegen transmutes between data ptrs and fn ptrs. + +// CHECK: define{{.+}}{{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}} @transmute_data_ptr_to_fn({{\{\}\*|ptr}}{{.*}} %x) +#[no_mangle] +pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() { + // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), + // as long as it doesn't cause a verifier error by using `bitcast`. + transmute(x) +} + +// CHECK: define{{.+}}{{\{\}\*|ptr}} @transmute_fn_ptr_to_data({{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}}{{.*}} %x) +#[no_mangle] +pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () { + // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), + // as long as it doesn't cause a verifier error by using `bitcast`. + transmute(x) +} From 3465d5fb168e99fd3a16a6b525feffbeca43647e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 12 Dec 2022 09:49:42 +0100 Subject: [PATCH 3/8] explain mem::forget(env_lock) in fork/exec --- library/std/src/sys/unix/process/process_unix.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 56a805cef7318..c0716a089bc38 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -66,14 +66,15 @@ impl Command { // // Note that as soon as we're done with the fork there's no need to hold // a lock any more because the parent won't do anything and the child is - // in its own process. Thus the parent drops the lock guard while the child - // forgets it to avoid unlocking it on a new thread, which would be invalid. + // in its own process. Thus the parent drops the lock guard immediately. + // The child calls `mem::forget` to leak the lock, which is crucial because + // releasing a lock is not async-signal-safe. let env_lock = sys::os::env_read_lock(); let (pid, pidfd) = unsafe { self.do_fork()? }; if pid == 0 { crate::panic::always_abort(); - mem::forget(env_lock); + mem::forget(env_lock); // avoid non-async-signal-safe unlocking drop(input); let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) }; let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; From 675fa0b3dd5fe14b43ad5b7862f4528df7322468 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 12 Dec 2022 18:29:33 +0000 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=9A=A8=20fix=20unsoundness=20in=20boo?= =?UTF-8?q?tstrap=20cache=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bootstrap/cache.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index be5c9bb078808..05f25af68ea8f 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -89,16 +89,16 @@ impl Hash for Interned { impl Deref for Interned { type Target = T::Target; - fn deref(&self) -> &'static Self::Target { + fn deref(&self) -> &Self::Target { let l = T::intern_cache().lock().unwrap(); - unsafe { mem::transmute::<&Self::Target, &'static Self::Target>(l.get(*self)) } + unsafe { mem::transmute::<&Self::Target, &Self::Target>(l.get(*self)) } } } impl, U: ?Sized> AsRef for Interned { - fn as_ref(&self) -> &'static U { + fn as_ref(&self) -> &U { let l = T::intern_cache().lock().unwrap(); - unsafe { mem::transmute::<&U, &'static U>(l.get(*self).as_ref()) } + unsafe { mem::transmute::<&U, &U>(l.get(*self).as_ref()) } } } From 19e7dbd288ddb5e4b59c1ef1c165cc8b301ee24f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 13 Dec 2022 10:20:37 +0100 Subject: [PATCH 5/8] Improve rustdoc markdown variable naming --- src/librustdoc/html/markdown.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 1e1c657b0bf22..b141820fe423c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -236,12 +236,12 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { return event; }; - let mut origtext = String::new(); + let mut original_text = String::new(); for event in &mut self.inner { match event { Event::End(Tag::CodeBlock(..)) => break, Event::Text(ref s) => { - origtext.push_str(s); + original_text.push_str(s); } _ => {} } @@ -258,7 +258,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> {
{}
\ ", lang, - Escape(&origtext), + Escape(&original_text), ) .into(), )); @@ -268,7 +268,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { CodeBlockKind::Indented => Default::default(), }; - let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); + let lines = original_text.lines().filter_map(|l| map_line(l).for_html()); let text = lines.intersperse("\n".into()).collect::(); compile_fail = parse_result.compile_fail; @@ -285,7 +285,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { if url.is_empty() { return None; } - let test = origtext + let test = original_text .lines() .map(|l| map_line(l).for_code()) .intersperse("\n".into()) From 6844b17bbe64ccefa006a0e6de267eed818227f9 Mon Sep 17 00:00:00 2001 From: Albert Larsan <74931857+albertlarsan68@users.noreply.github.com> Date: Mon, 12 Dec 2022 20:53:13 +0100 Subject: [PATCH 6/8] Add a test for #92481 --- src/test/ui/typeck/issue-92481.rs | 14 ++++++ src/test/ui/typeck/issue-92481.stderr | 62 +++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/test/ui/typeck/issue-92481.rs create mode 100644 src/test/ui/typeck/issue-92481.stderr diff --git a/src/test/ui/typeck/issue-92481.rs b/src/test/ui/typeck/issue-92481.rs new file mode 100644 index 0000000000000..0a6b1843d996c --- /dev/null +++ b/src/test/ui/typeck/issue-92481.rs @@ -0,0 +1,14 @@ +//check-fail + +#![crate_type="lib"] + +fn r({) { + Ok { //~ ERROR mismatched types [E0308] + d..||_=m + } +} +//~^^^^^ ERROR expected parameter name, found `{` +//~| ERROR expected one of `,`, `:`, or `}`, found `..` +//~^^^^^ ERROR cannot find value `d` in this scope [E0425] +//~| ERROR cannot find value `m` in this scope [E0425] +//~| ERROR variant `Result<_, _>::Ok` has no field named `d` [E0559] diff --git a/src/test/ui/typeck/issue-92481.stderr b/src/test/ui/typeck/issue-92481.stderr new file mode 100644 index 0000000000000..ee96e8f6367bf --- /dev/null +++ b/src/test/ui/typeck/issue-92481.stderr @@ -0,0 +1,62 @@ +error: expected parameter name, found `{` + --> $DIR/issue-92481.rs:5:6 + | +LL | fn r({) { + | ^ expected parameter name + +error: expected one of `,`, `:`, or `}`, found `..` + --> $DIR/issue-92481.rs:5:6 + | +LL | fn r({) { + | ^ unclosed delimiter +LL | Ok { +LL | d..||_=m + | -^ + | | + | help: `}` may belong here + +error[E0425]: cannot find value `d` in this scope + --> $DIR/issue-92481.rs:7:9 + | +LL | d..||_=m + | ^ not found in this scope + +error[E0425]: cannot find value `m` in this scope + --> $DIR/issue-92481.rs:7:16 + | +LL | d..||_=m + | ^ not found in this scope + +error[E0559]: variant `Result<_, _>::Ok` has no field named `d` + --> $DIR/issue-92481.rs:7:9 + | +LL | d..||_=m + | ^ field does not exist + | + ::: $SRC_DIR/core/src/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | -- `Result<_, _>::Ok` defined here + | +help: `Result<_, _>::Ok` is a tuple variant, use the appropriate syntax + | +LL | Result<_, _>::Ok(/* fields */) + | + +error[E0308]: mismatched types + --> $DIR/issue-92481.rs:6:5 + | +LL | fn r({) { + | - help: a return type might be missing here: `-> _` +LL | / Ok { +LL | | d..||_=m +LL | | } + | |_____^ expected `()`, found enum `Result` + | + = note: expected unit type `()` + found enum `Result<_, _>` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0425, E0559. +For more information about an error, try `rustc --explain E0308`. From f7db4f0a4ceb5175155fdddb7e3609e4de33ddc5 Mon Sep 17 00:00:00 2001 From: Albert Larsan <74931857+albertlarsan68@users.noreply.github.com> Date: Wed, 14 Dec 2022 13:40:34 +0100 Subject: [PATCH 7/8] Bless test --- src/test/ui/typeck/issue-92481.stderr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/ui/typeck/issue-92481.stderr b/src/test/ui/typeck/issue-92481.stderr index ee96e8f6367bf..cd778a649b621 100644 --- a/src/test/ui/typeck/issue-92481.stderr +++ b/src/test/ui/typeck/issue-92481.stderr @@ -32,11 +32,9 @@ error[E0559]: variant `Result<_, _>::Ok` has no field named `d` | LL | d..||_=m | ^ field does not exist + --> $SRC_DIR/core/src/result.rs:LL:COL | - ::: $SRC_DIR/core/src/result.rs:LL:COL - | -LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), - | -- `Result<_, _>::Ok` defined here + = note: `Result<_, _>::Ok` defined here | help: `Result<_, _>::Ok` is a tuple variant, use the appropriate syntax | From 060e033c9c3c4d8b8f1563dc6650e300ab122acc Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 14 Dec 2022 12:41:11 +0000 Subject: [PATCH 8/8] Remove fee1-dead from reviewers .. for now. I have been burned out a bit from reviews and I think I should take a break. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 19e8334fc1aa3..46a3bab42a17e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -467,7 +467,6 @@ compiler-team-contributors = [ "@compiler-errors", "@eholk", "@jackh726", - "@fee1-dead", "@TaKO8Ki", "@Nilstrieb", ]