From 0b87af9d4f7c6faa9e89496609f016dc3e3977e1 Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Sat, 27 Apr 2024 23:14:36 +0200 Subject: [PATCH 01/20] Add `-Z embed-source=yes` to embed source code in DWARF debug info --- .../src/debuginfo/metadata.rs | 9 +++++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 ++ compiler/rustc_interface/src/tests.rs | 1 + .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 9 +++++-- compiler/rustc_session/messages.ftl | 6 +++++ compiler/rustc_session/src/errors.rs | 14 +++++++++++ compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 25 +++++++++++++++++-- .../src/compiler-flags/embed-source.md | 12 +++++++++ 9 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/embed-source.md diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index ad63858861261..701ea62b21a7d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -629,6 +629,9 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> }; let hash_value = hex_encode(source_file.src_hash.hash_bytes()); + let source = + cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref()); + unsafe { llvm::LLVMRustDIBuilderCreateFile( DIB(cx), @@ -639,6 +642,8 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> hash_kind, hash_value.as_ptr().cast(), hash_value.len(), + source.map_or(ptr::null(), |x| x.as_ptr().cast()), + source.map_or(0, |x| x.len()), ) } } @@ -659,6 +664,8 @@ pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { llvm::ChecksumKind::None, hash_value.as_ptr().cast(), hash_value.len(), + ptr::null(), + 0, ) }) } @@ -943,6 +950,8 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( llvm::ChecksumKind::None, ptr::null(), 0, + ptr::null(), + 0, ); let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index c8e0e075eeabc..faa675b66c8a1 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1853,6 +1853,8 @@ extern "C" { CSKind: ChecksumKind, Checksum: *const c_char, ChecksumLen: size_t, + Source: *const c_char, + SourceLen: size_t, ) -> &'a DIFile; pub fn LLVMRustDIBuilderCreateSubroutineType<'a>( diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ce3b2f77f210a..c4704e38ce6fa 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -773,6 +773,7 @@ fn test_unstable_options_tracking_hash() { tracked!(direct_access_external_data, Some(true)); tracked!(dual_proc_macros, true); tracked!(dwarf_version, Some(5)); + tracked!(embed_source, true); tracked!(emit_thin_lto, false); tracked!(export_executable_symbols, true); tracked!(fewer_names, Some(true)); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 4cdd8af1008c0..6e700c31e6763 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -901,14 +901,19 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind, - const char *Checksum, size_t ChecksumLen) { + const char *Checksum, size_t ChecksumLen, + const char *Source, size_t SourceLen) { std::optional llvmCSKind = fromRust(CSKind); std::optional> CSInfo{}; if (llvmCSKind) CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen}); + std::optional oSource{}; + if (Source) + oSource = StringRef(Source, SourceLen); return wrap(Builder->createFile(StringRef(Filename, FilenameLen), - StringRef(Directory, DirectoryLen), CSInfo)); + StringRef(Directory, DirectoryLen), CSInfo, + oSource)); } extern "C" LLVMMetadataRef diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index b84280a3ccf3f..afd5360c81194 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -14,6 +14,12 @@ session_crate_name_empty = crate name must not be empty session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen +session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version} + +session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled + +session_embed_source_requires_llvm_backend = `-Zembed-source=y` is only supported on the LLVM codegen backend + session_expr_parentheses_needed = parentheses are required to parse this as an expression session_failed_to_create_profiler = failed to create profiler: {$err} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 5cc54a5855bbe..f708109b87a0c 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -165,6 +165,20 @@ pub(crate) struct UnsupportedDwarfVersion { pub(crate) dwarf_version: u32, } +#[derive(Diagnostic)] +#[diag(session_embed_source_insufficient_dwarf_version)] +pub(crate) struct EmbedSourceInsufficientDwarfVersion { + pub(crate) dwarf_version: u32, +} + +#[derive(Diagnostic)] +#[diag(session_embed_source_requires_debug_info)] +pub(crate) struct EmbedSourceRequiresDebugInfo; + +#[derive(Diagnostic)] +#[diag(session_embed_source_requires_llvm_backend)] +pub(crate) struct EmbedSourceRequiresLLVMBackend; + #[derive(Diagnostic)] #[diag(session_target_stack_protector_not_supported)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index bf54aae1cfeb0..13aac6669fe4f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1708,6 +1708,8 @@ options! { them only if an error has not been emitted"), ehcont_guard: bool = (false, parse_bool, [TRACKED], "generate Windows EHCont Guard tables"), + embed_source: bool = (false, parse_bool, [TRACKED], + "embed source text in DWARF debug sections (default: no)"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), emit_thin_lto: bool = (true, parse_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index be67baf57f6dc..634f3684b51aa 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -37,8 +37,9 @@ use rustc_target::spec::{ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CoverageLevel, CrateType, ErrorOutputType, FunctionReturn, Input, InstrumentCoverage, - OptLevel, OutFileName, OutputType, RemapPathScopeComponents, SwitchWithOptPath, + self, CoverageLevel, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, Input, + InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents, + SwitchWithOptPath, }; use crate::parse::{add_feature_diagnostics, ParseSess}; use crate::search_paths::{PathKind, SearchPath}; @@ -1300,6 +1301,26 @@ fn validate_commandline_args_with_session_available(sess: &Session) { .emit_err(errors::SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() }); } + if sess.opts.unstable_opts.embed_source { + let dwarf_version = + sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); + + let uses_llvm_backend = + matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm")); + + if dwarf_version < 5 { + sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version }); + } + + if sess.opts.debuginfo == DebugInfo::None { + sess.dcx().emit_warn(errors::EmbedSourceRequiresDebugInfo); + } + + if !uses_llvm_backend { + sess.dcx().emit_warn(errors::EmbedSourceRequiresLLVMBackend); + } + } + if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray { sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() }); } diff --git a/src/doc/unstable-book/src/compiler-flags/embed-source.md b/src/doc/unstable-book/src/compiler-flags/embed-source.md new file mode 100644 index 0000000000000..01a11e3779712 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/embed-source.md @@ -0,0 +1,12 @@ +# `embed-source` + +This flag controls whether the compiler embeds the program source code text into +the object debug information section. It takes one of the following values: + +* `y`, `yes`, `on` or `true`: put source code in debug info. +* `n`, `no`, `off`, `false` or no value: omit source code from debug info (the default). + +This flag is ignored in configurations that don't emit DWARF debug information +and is ignored on non-LLVM backends. `-Z embed-source` requires DWARFv5. Use +`-Z dwarf-version=5` to control the compiler's DWARF target version and `-g` to +enable debug info generation. From 608901b9c07d7d2f3e2803378c4f0cc07c61bc36 Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Tue, 16 Jul 2024 20:50:28 +0200 Subject: [PATCH 02/20] Add run-make test for -Zembed-source=yes --- tests/run-make/embed-source-dwarf/main.rs | 2 + tests/run-make/embed-source-dwarf/rmake.rs | 70 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/run-make/embed-source-dwarf/main.rs create mode 100644 tests/run-make/embed-source-dwarf/rmake.rs diff --git a/tests/run-make/embed-source-dwarf/main.rs b/tests/run-make/embed-source-dwarf/main.rs new file mode 100644 index 0000000000000..c80af84f41415 --- /dev/null +++ b/tests/run-make/embed-source-dwarf/main.rs @@ -0,0 +1,2 @@ +// hello +fn main() {} diff --git a/tests/run-make/embed-source-dwarf/rmake.rs b/tests/run-make/embed-source-dwarf/rmake.rs new file mode 100644 index 0000000000000..06d550121b0de --- /dev/null +++ b/tests/run-make/embed-source-dwarf/rmake.rs @@ -0,0 +1,70 @@ +//@ ignore-windows +//@ ignore-apple + +// LLVM 17's embed-source implementation requires that source code is attached +// for all files in the output DWARF debug info. This restriction was lifted in +// LLVM 18 (87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d). +//@ min-llvm-version: 18 + +// This test should be replaced with one in tests/debuginfo once we can easily +// tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB +// like setting an invalid source map path don't appear to work, maybe this'll +// become easier once GDB supports DWARFv6? + +use std::collections::HashMap; +use std::path::PathBuf; +use std::rc::Rc; + +use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; +use object::{Object, ObjectSection}; +use run_make_support::{gimli, object, rfs, rustc}; + +fn main() { + let output = PathBuf::from("embed-source-main"); + rustc() + .input("main.rs") + .output(&output) + .arg("-g") + .arg("-Zembed-source=yes") + .arg("-Zdwarf-version=5") + .run(); + let output = rfs::read(output); + let obj = object::File::parse(output.as_slice()).unwrap(); + let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; + let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { + let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap()); + Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian)) + }) + .unwrap(); + + let mut sources = HashMap::new(); + + let mut iter = dwarf.units(); + while let Some(header) = iter.next().unwrap() { + let unit = dwarf.unit(header).unwrap(); + let unit = unit.unit_ref(&dwarf); + + if let Some(program) = &unit.line_program { + let header = program.header(); + for file in header.file_names() { + if let Some(source) = file.source() { + let path = unit + .attr_string(file.path_name()) + .unwrap() + .to_string_lossy() + .unwrap() + .to_string(); + let source = + unit.attr_string(source).unwrap().to_string_lossy().unwrap().to_string(); + if !source.is_empty() { + sources.insert(path, source); + } + } + } + } + } + + dbg!(&sources); + assert_eq!(sources.len(), 1); + assert_eq!(sources.get("main.rs").unwrap(), "// hello\nfn main() {}\n"); +} From 6899f5a8e12986ee16e028f1597963d0de668aca Mon Sep 17 00:00:00 2001 From: Mrmaxmeier Date: Tue, 6 Aug 2024 20:31:12 +0200 Subject: [PATCH 03/20] -Zembed-source: Don't try to warn about incompatible codegen backends --- compiler/rustc_session/messages.ftl | 2 -- compiler/rustc_session/src/errors.rs | 4 ---- compiler/rustc_session/src/session.rs | 7 ------- 3 files changed, 13 deletions(-) diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index afd5360c81194..01c371ee49884 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -18,8 +18,6 @@ session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled -session_embed_source_requires_llvm_backend = `-Zembed-source=y` is only supported on the LLVM codegen backend - session_expr_parentheses_needed = parentheses are required to parse this as an expression session_failed_to_create_profiler = failed to create profiler: {$err} diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index f708109b87a0c..15bbd4ff7bf4b 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -175,10 +175,6 @@ pub(crate) struct EmbedSourceInsufficientDwarfVersion { #[diag(session_embed_source_requires_debug_info)] pub(crate) struct EmbedSourceRequiresDebugInfo; -#[derive(Diagnostic)] -#[diag(session_embed_source_requires_llvm_backend)] -pub(crate) struct EmbedSourceRequiresLLVMBackend; - #[derive(Diagnostic)] #[diag(session_target_stack_protector_not_supported)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 634f3684b51aa..e2ef144e732a4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1305,9 +1305,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { let dwarf_version = sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); - let uses_llvm_backend = - matches!(sess.opts.unstable_opts.codegen_backend.as_deref(), None | Some("llvm")); - if dwarf_version < 5 { sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version }); } @@ -1315,10 +1312,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { if sess.opts.debuginfo == DebugInfo::None { sess.dcx().emit_warn(errors::EmbedSourceRequiresDebugInfo); } - - if !uses_llvm_backend { - sess.dcx().emit_warn(errors::EmbedSourceRequiresLLVMBackend); - } } if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray { From 803cbaf5fb5021eafaa60578ed33d708370ba3c0 Mon Sep 17 00:00:00 2001 From: Rezwan ahmed sami Date: Sun, 18 Aug 2024 01:11:18 +0600 Subject: [PATCH 04/20] Add f16 and f128 to tests/ui/consts/const-float-bits-conv.rs --- tests/ui/consts/const-float-bits-conv.rs | 65 +++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs index 45e8ea570ed73..2c4df96562a9d 100644 --- a/tests/ui/consts/const-float-bits-conv.rs +++ b/tests/ui/consts/const-float-bits-conv.rs @@ -3,8 +3,9 @@ #![feature(const_float_bits_conv)] #![feature(const_float_classify)] +#![feature(f16)] +#![feature(f128)] #![allow(unused_macro_rules)] - // Don't promote const fn nop(x: T) -> T { x } @@ -28,6 +29,36 @@ fn has_broken_floats() -> bool { std::env::var("TARGET").is_ok_and(|v| v.contains("i586")) } +fn f16(){ + const_assert!((1f16).to_bits(), 0x3c00); + const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00); + const_assert!((12.5f16).to_bits(), 0x4a40); + const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40); + const_assert!((1337f16).to_bits(), 0x6539); + const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539); + const_assert!((-14.25f16).to_bits(), 0xcb20); + const_assert!(f16::from_bits(0x3c00), 1.0); + const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0); + const_assert!(f16::from_bits(0x4a40), 12.5); + const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5); + const_assert!(f16::from_bits(0x5be0), 252.0); + const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0); + const_assert!(f16::from_bits(0xcb20), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply! + const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155; + const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA; + + const_assert!(f16::from_bits(QUIET_NAN).is_nan()); + const_assert!(f16::from_bits(SIGNALING_NAN).is_nan()); + const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN); + if !has_broken_floats() { + const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN); + } +} + fn f32() { const_assert!((1f32).to_bits(), 0x3f800000); const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000); @@ -88,7 +119,39 @@ fn f64() { } } +fn f128() { + const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); + const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); + const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000); + const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000); + const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000); + const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000); + const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000); + const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0); + const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0); + const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5); + const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5); + const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0); + assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0); + const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply! + const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA; + const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555; + + const_assert!(f128::from_bits(QUIET_NAN).is_nan()); + const_assert!(f128::from_bits(SIGNALING_NAN).is_nan()); + const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN); + if !has_broken_floats() { + const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN); + } +} + fn main() { + f16(); f32(); f64(); + f128(); } From 9f39427228d09d7a06b9dd55a4f52b4b9ac15817 Mon Sep 17 00:00:00 2001 From: Rezwan ahmed sami Date: Sun, 18 Aug 2024 11:12:40 +0600 Subject: [PATCH 05/20] Added #[cfg(target_arch = x86_64)] to f16 and f128 --- tests/ui/consts/const-float-bits-conv.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs index 2c4df96562a9d..3a526c54dc376 100644 --- a/tests/ui/consts/const-float-bits-conv.rs +++ b/tests/ui/consts/const-float-bits-conv.rs @@ -29,6 +29,7 @@ fn has_broken_floats() -> bool { std::env::var("TARGET").is_ok_and(|v| v.contains("i586")) } +#[cfg(target_arch = "x86_64")] fn f16(){ const_assert!((1f16).to_bits(), 0x3c00); const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00); @@ -119,6 +120,7 @@ fn f64() { } } +#[cfg(target_arch = "x86_64")] fn f128() { const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000); const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000); @@ -150,8 +152,11 @@ fn f128() { } fn main() { - f16(); + #[cfg(target_arch = "x86_64")] + { + f16(); + f128(); + } f32(); f64(); - f128(); } From 275a526dd3d3f97e197b70b20f0235d929177859 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 21 Aug 2024 22:32:03 -0700 Subject: [PATCH 06/20] library: Move unstable API of new_uninit to new features - `new_zeroed` variants move to `new_zeroed_alloc` - the `write` fn moves to `box_uninit_write` The remainder will be stabilized in upcoming patches, as it was decided to only stabilize `uninit*` and `assume_init`. --- compiler/rustc_index/src/lib.rs | 1 + library/alloc/src/boxed.rs | 9 ++++++--- library/alloc/src/rc.rs | 6 ++++-- library/alloc/src/sync.rs | 10 ++++++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index b5e4f02a8d15c..b9d2a43206b1e 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,6 +2,7 @@ #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))] +#![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] // tidy-alphabetical-end pub mod bit_set; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7de412595993a..c8e8d2a22ca48 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -293,6 +293,7 @@ impl Box { /// /// ``` /// #![feature(new_uninit)] + /// #![feature(new_zeroed_alloc)] /// /// let zero = Box::::new_zeroed(); /// let zero = unsafe { zero.assume_init() }; @@ -303,7 +304,7 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Box> { Self::new_zeroed_in(Global) @@ -684,6 +685,7 @@ impl Box<[T]> { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// let values = Box::<[u32]>::new_zeroed_slice(3); @@ -694,7 +696,7 @@ impl Box<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } @@ -955,6 +957,7 @@ impl Box, A> { /// # Examples /// /// ``` + /// #![feature(box_uninit_write)] /// #![feature(new_uninit)] /// /// let big_box = Box::<[usize; 1024]>::new_uninit(); @@ -972,7 +975,7 @@ impl Box, A> { /// assert_eq!(*x, i); /// } /// ``` - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "box_uninit_write", issue = "129397")] #[inline] pub fn write(mut boxed: Self, value: T) -> Box { unsafe { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index bdee06154faec..f153aa6d3be9a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -539,6 +539,7 @@ impl Rc { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::rc::Rc; @@ -551,7 +552,7 @@ impl Rc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Rc> { unsafe { @@ -1000,6 +1001,7 @@ impl Rc<[T]> { /// /// ``` /// #![feature(new_uninit)] + /// #![feature(new_zeroed_alloc)] /// /// use std::rc::Rc; /// @@ -1011,7 +1013,7 @@ impl Rc<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit]> { unsafe { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2c0d19b0ada09..4a3522f1a641b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -542,6 +542,7 @@ impl Arc { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::sync::Arc; @@ -555,7 +556,7 @@ impl Arc { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Arc> { unsafe { @@ -1134,6 +1135,7 @@ impl Arc<[T]> { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::sync::Arc; @@ -1147,7 +1149,7 @@ impl Arc<[T]> { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { unsafe { @@ -1191,7 +1193,7 @@ impl Arc<[T], A> { /// assert_eq!(*values, [1, 2, 3]) /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) } @@ -1220,7 +1222,7 @@ impl Arc<[T], A> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { unsafe { From f62b9e0179434218040f42ee58bb99c1bf27c6d7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Jul 2024 20:27:17 +0300 Subject: [PATCH 07/20] rustc: Simplify getting sysroot library directory --- compiler/rustc_codegen_ssa/src/back/link.rs | 27 +++++++++------------ compiler/rustc_session/src/filesearch.rs | 16 +----------- compiler/rustc_session/src/session.rs | 16 ++---------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7bad9d33e7d31..ca439460adc11 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1317,11 +1317,9 @@ fn link_sanitizer_runtime( name: &str, ) { fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf { - let session_tlib = - filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple()); - let path = session_tlib.join(filename); + let path = sess.target_tlib_path.dir.join(filename); if path.exists() { - return session_tlib; + return sess.target_tlib_path.dir.clone(); } else { let default_sysroot = filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); @@ -1612,19 +1610,18 @@ fn print_native_static_libs( } fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf { - let fs = sess.target_filesearch(PathKind::Native); - let file_path = fs.get_lib_path().join(name); + let file_path = sess.target_tlib_path.dir.join(name); if file_path.exists() { return file_path; } // Special directory with objects used only in self-contained linkage mode if self_contained { - let file_path = fs.get_self_contained_lib_path().join(name); + let file_path = sess.target_tlib_path.dir.join("self-contained").join(name); if file_path.exists() { return file_path; } } - for search_path in fs.search_paths() { + for search_path in sess.target_filesearch(PathKind::Native).search_paths() { let file_path = search_path.dir.join(name); if file_path.exists() { return file_path; @@ -2131,7 +2128,7 @@ fn add_library_search_dirs( | LinkSelfContainedComponents::UNWIND | LinkSelfContainedComponents::MINGW, ) { - let lib_path = sess.target_filesearch(PathKind::Native).get_self_contained_lib_path(); + let lib_path = sess.target_tlib_path.dir.join("self-contained"); cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); } @@ -2146,8 +2143,7 @@ fn add_library_search_dirs( || sess.target.os == "fuchsia" || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty() { - let lib_path = sess.target_filesearch(PathKind::Native).get_lib_path(); - cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); + cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir)); } // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks @@ -2859,15 +2855,14 @@ fn add_upstream_native_libraries( // // The returned path will always have `fix_windows_verbatim_for_gcc()` applied to it. fn rehome_sysroot_lib_dir(sess: &Session, lib_dir: &Path) -> PathBuf { - let sysroot_lib_path = sess.target_filesearch(PathKind::All).get_lib_path(); + let sysroot_lib_path = &sess.target_tlib_path.dir; let canonical_sysroot_lib_path = - { try_canonicalize(&sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) }; + { try_canonicalize(sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) }; let canonical_lib_dir = try_canonicalize(lib_dir).unwrap_or_else(|_| lib_dir.to_path_buf()); if canonical_lib_dir == canonical_sysroot_lib_path { - // This path, returned by `target_filesearch().get_lib_path()`, has - // already had `fix_windows_verbatim_for_gcc()` applied if needed. - sysroot_lib_path + // This path already had `fix_windows_verbatim_for_gcc()` applied if needed. + sysroot_lib_path.clone() } else { fix_windows_verbatim_for_gcc(lib_dir) } diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 63ca5fefd9faf..d78f4a78de732 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -5,14 +5,11 @@ use std::{env, fs}; use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use smallvec::{smallvec, SmallVec}; -use tracing::debug; use crate::search_paths::{PathKind, SearchPath}; #[derive(Clone)] pub struct FileSearch<'a> { - sysroot: &'a Path, - triple: &'a str, cli_search_paths: &'a [SearchPath], tlib_path: &'a SearchPath, kind: PathKind, @@ -32,23 +29,12 @@ impl<'a> FileSearch<'a> { .chain(std::iter::once(self.tlib_path)) } - pub fn get_lib_path(&self) -> PathBuf { - make_target_lib_path(self.sysroot, self.triple) - } - - pub fn get_self_contained_lib_path(&self) -> PathBuf { - self.get_lib_path().join("self-contained") - } - pub fn new( - sysroot: &'a Path, - triple: &'a str, cli_search_paths: &'a [SearchPath], tlib_path: &'a SearchPath, kind: PathKind, ) -> FileSearch<'a> { - debug!("using sysroot = {}, triple = {}", sysroot.display(), triple); - FileSearch { sysroot, triple, cli_search_paths, tlib_path, kind } + FileSearch { cli_search_paths, tlib_path, kind } } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 693867c3853da..b073950a750b4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -439,22 +439,10 @@ impl Session { } pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { - filesearch::FileSearch::new( - &self.sysroot, - self.opts.target_triple.triple(), - &self.opts.search_paths, - &self.target_tlib_path, - kind, - ) + filesearch::FileSearch::new(&self.opts.search_paths, &self.target_tlib_path, kind) } pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { - filesearch::FileSearch::new( - &self.sysroot, - config::host_triple(), - &self.opts.search_paths, - &self.host_tlib_path, - kind, - ) + filesearch::FileSearch::new(&self.opts.search_paths, &self.host_tlib_path, kind) } /// Returns a list of directories where target-specific tool binaries are located. Some fallback From 585804fceeeb0f95fc18fbd4a072dfc9c63bee14 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 20 Aug 2024 15:57:16 +1000 Subject: [PATCH 08/20] Check that `library/profiler_builtins` actually found some source files The current `build.rs` will automatically skip source files that don't exist. An unfortunate side-effect is that if _no_ files could be found (e.g. because the directory was wrong), the build fails with a mysterious linker error. We can reduce the awkwardness of this by explicitly checking that at least one source file was found. --- library/profiler_builtins/build.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index 9d1c1ba305bc5..177b027e4f175 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -84,12 +84,16 @@ fn main() { let root = Path::new("../../src/llvm-project/compiler-rt"); let src_root = root.join("lib").join("profile"); + assert!(src_root.exists(), "profiler runtime source directory not found: {src_root:?}"); + let mut n_sources_found = 0u32; for src in profile_sources { let path = src_root.join(src); if path.exists() { cfg.file(path); + n_sources_found += 1; } } + assert!(n_sources_found > 0, "couldn't find any profiler runtime source files in {src_root:?}"); cfg.include(root.join("include")); cfg.warnings(false); From 4acc531f83623be093407fe0749acf2b65cc2a56 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 19 Aug 2024 23:00:37 +1000 Subject: [PATCH 09/20] Build `library/profiler_builtins` from `ci-llvm` if appropriate --- library/profiler_builtins/build.rs | 12 ++++--- src/bootstrap/src/core/build_steps/compile.rs | 31 ++++++++++++------- src/bootstrap/src/utils/change_tracker.rs | 5 +++ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index 177b027e4f175..c1e0e5c1c8975 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -3,7 +3,7 @@ //! See the build.rs for libcompiler_builtins crate for details. use std::env; -use std::path::Path; +use std::path::PathBuf; fn main() { println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB"); @@ -79,9 +79,13 @@ fn main() { cfg.define("COMPILER_RT_HAS_ATOMICS", Some("1")); } - // Note that this should exist if we're going to run (otherwise we just - // don't build profiler builtins at all). - let root = Path::new("../../src/llvm-project/compiler-rt"); + // Get the LLVM `compiler-rt` directory from bootstrap. + println!("cargo:rerun-if-env-changed=RUST_COMPILER_RT_FOR_PROFILER"); + let root = PathBuf::from(env::var("RUST_COMPILER_RT_FOR_PROFILER").unwrap_or_else(|_| { + let path = "../../src/llvm-project/compiler-rt"; + println!("RUST_COMPILER_RT_FOR_PROFILER was not set; falling back to {path:?}"); + path.to_owned() + })); let src_root = root.join("lib").join("profile"); assert!(src_root.exists(), "profiler runtime source directory not found: {src_root:?}"); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4353cfadd8d35..58b7e0dd21707 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -199,16 +199,6 @@ impl Step for Std { builder.require_submodule("library/stdarch", None); - // Profiler information requires LLVM's compiler-rt - if builder.config.profiler { - builder.require_submodule( - "src/llvm-project", - Some( - "The `build.profiler` config option requires `compiler-rt` sources from LLVM.", - ), - ); - } - let mut target_deps = builder.ensure(StartupObjects { compiler, target }); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); @@ -473,8 +463,25 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } + // Paths needed by `library/profiler_builtins/build.rs`. if let Some(path) = builder.config.profiler_path(target) { cargo.env("LLVM_PROFILER_RT_LIB", path); + } else if builder.config.profiler_enabled(target) { + let compiler_rt = if builder.config.llvm_from_ci { + // There's a copy of `compiler-rt` in the CI LLVM tarball, + // so we don't need to check out the LLVM submodule. + builder.config.ci_llvm_root().join("compiler-rt") + } else { + builder.require_submodule("src/llvm-project", { + Some("The `build.profiler` config option requires `compiler-rt` sources from LLVM.") + }); + builder.src.join("src/llvm-project/compiler-rt") + }; + assert!(compiler_rt.exists(), "compiler-rt directory not found: {compiler_rt:?}"); + // Currently this is separate from the env var used by `compiler_builtins` + // (below) so that adding support for CI LLVM here doesn't risk breaking + // the compiler builtins. But they could be unified if desired. + cargo.env("RUST_COMPILER_RT_FOR_PROFILER", compiler_rt); } // Determine if we're going to compile in optimized C intrinsics to @@ -507,8 +514,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car ); let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); assert!(compiler_builtins_root.exists()); - // Note that `libprofiler_builtins/build.rs` also computes this so if - // you're changing something here please also change that. + // The path to `compiler-rt` is also used by `profiler_builtins` (above), + // so if you're changing something here please also change that as appropriate. cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); " compiler-builtins-c" } else { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index c629f04c00ecd..54eb0feee092f 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -230,4 +230,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "./x test --rustc-args was renamed to --compiletest-rustc-args as it only applies there. ./x miri --rustc-args was also removed.", }, + ChangeInfo { + change_id: 129295, + severity: ChangeSeverity::Info, + summary: "The `build.profiler` option now uses source code from `download-ci-llvm` if possible, instead of syncing the `src/llvm-project` submodule.", + }, ]; From cee7f18d64bd461d3e36d2ea63b0d1867c680af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 15:02:13 +0000 Subject: [PATCH 10/20] compiletest: implement `needs-lvm-zstd` directive --- src/tools/compiletest/src/command-list.rs | 1 + src/tools/compiletest/src/header.rs | 101 ++++++++++++++++++++++ src/tools/compiletest/src/header/needs.rs | 10 ++- 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index 7f8080235c870..a559d6f81a240 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -141,6 +141,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-force-clang-based-tests", "needs-git-hash", "needs-llvm-components", + "needs-llvm-zstd", "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 1fc24301c85e6..933913eb47c34 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1203,6 +1203,107 @@ pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option { None } +/// For tests using the `needs-llvm-zstd` directive: +/// - for local LLVM builds, try to find the static zstd library in the llvm-config system libs. +/// - for `download-ci-llvm`, see if `lld` was built with zstd support. +pub fn llvm_has_libzstd(config: &Config) -> bool { + // Strategy 1: works for local builds but not with `download-ci-llvm`. + // + // We check whether `llvm-config` returns the zstd library. Bootstrap's `llvm.libzstd` will only + // ask to statically link it when building LLVM, so we only check if the list of system libs + // contains a path to that static lib, and that it exists. + // + // See compiler/rustc_llvm/build.rs for more details and similar expectations. + fn is_zstd_in_config(llvm_bin_dir: &Path) -> Option<()> { + let llvm_config_path = llvm_bin_dir.join("llvm-config"); + let output = Command::new(llvm_config_path).arg("--system-libs").output().ok()?; + assert!(output.status.success(), "running llvm-config --system-libs failed"); + + let libs = String::from_utf8(output.stdout).ok()?; + for lib in libs.split_whitespace() { + if lib.ends_with("libzstd.a") && Path::new(lib).exists() { + return Some(()); + } + } + + None + } + + // Strategy 2: `download-ci-llvm`'s `llvm-config --system-libs` will not return any libs to + // use. + // + // The CI artifacts also don't contain the bootstrap config used to build them: otherwise we + // could have looked at the `llvm.libzstd` config. + // + // We infer whether `LLVM_ENABLE_ZSTD` was used to build LLVM as a byproduct of testing whether + // `lld` supports it. If not, an error will be emitted: "LLVM was not built with + // LLVM_ENABLE_ZSTD or did not find zstd at build time". + #[cfg(unix)] + fn is_lld_built_with_zstd(llvm_bin_dir: &Path) -> Option<()> { + let lld_path = llvm_bin_dir.join("lld"); + if lld_path.exists() { + // We can't call `lld` as-is, it expects to be invoked by a compiler driver using a + // different name. Prepare a temporary symlink to do that. + let lld_symlink_path = llvm_bin_dir.join("ld.lld"); + if !lld_symlink_path.exists() { + std::os::unix::fs::symlink(lld_path, &lld_symlink_path).ok()?; + } + + // Run `lld` with a zstd flag. We expect this command to always error here, we don't + // want to link actual files and don't pass any. + let output = Command::new(&lld_symlink_path) + .arg("--compress-debug-sections=zstd") + .output() + .ok()?; + assert!(!output.status.success()); + + // Look for a specific error caused by LLVM not being built with zstd support. We could + // also look for the "no input files" message, indicating the zstd flag was accepted. + let stderr = String::from_utf8(output.stderr).ok()?; + let zstd_available = !stderr.contains("LLVM was not built with LLVM_ENABLE_ZSTD"); + + // We don't particularly need to clean the link up (so the previous commands could fail + // in theory but won't in practice), but we can try. + std::fs::remove_file(lld_symlink_path).ok()?; + + if zstd_available { + return Some(()); + } + } + + None + } + + #[cfg(not(unix))] + fn is_lld_built_with_zstd(_llvm_bin_dir: &Path) -> Option<()> { + None + } + + if let Some(llvm_bin_dir) = &config.llvm_bin_dir { + // Strategy 1: for local LLVM builds. + if is_zstd_in_config(llvm_bin_dir).is_some() { + return true; + } + + // Strategy 2: for LLVM artifacts built on CI via `download-ci-llvm`. + // + // It doesn't work for cases where the artifacts don't contain the linker, but it's + // best-effort: CI has `llvm.libzstd` and `lld` enabled on the x64 linux artifacts, so it + // will at least work there. + // + // If this can be improved and expanded to less common cases in the future, it should. + if config.target == "x86_64-unknown-linux-gnu" + && config.host == config.target + && is_lld_built_with_zstd(llvm_bin_dir).is_some() + { + return true; + } + } + + // Otherwise, all hope is lost. + false +} + /// Takes a directive of the form " [- ]", /// returns the numeric representation of and as /// tuple: ( as u32, as u32) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 8f935d5b74441..e04abea0bf987 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -1,5 +1,5 @@ use crate::common::{Config, Sanitizer}; -use crate::header::IgnoreDecision; +use crate::header::{llvm_has_libzstd, IgnoreDecision}; pub(super) fn handle_needs( cache: &CachedNeedsConditions, @@ -144,6 +144,11 @@ pub(super) fn handle_needs( condition: cache.symlinks, ignore_reason: "ignored if symlinks are unavailable", }, + Need { + name: "needs-llvm-zstd", + condition: cache.llvm_zstd, + ignore_reason: "ignored if LLVM wasn't build with zstd for ELF section compression", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { @@ -210,6 +215,8 @@ pub(super) struct CachedNeedsConditions { rust_lld: bool, dlltool: bool, symlinks: bool, + /// Whether LLVM built with zstd, for the `needs-llvm-zstd` directive. + llvm_zstd: bool, } impl CachedNeedsConditions { @@ -253,6 +260,7 @@ impl CachedNeedsConditions { .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" }) .exists(), + llvm_zstd: llvm_has_libzstd(&config), dlltool: find_dlltool(&config), symlinks: has_symlinks(), } From 16b444d63a27388cb5c639c15d628606317b7ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 15:09:20 +0000 Subject: [PATCH 11/20] mark `rust-lld-compress-debug-sections` test as needing zstd also make it fail if there's a compression issue --- .../rust-lld-compress-debug-sections/rmake.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs b/tests/run-make/rust-lld-compress-debug-sections/rmake.rs index ea4997fab8099..9889659046ea7 100644 --- a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs +++ b/tests/run-make/rust-lld-compress-debug-sections/rmake.rs @@ -1,12 +1,13 @@ // Checks the `compress-debug-sections` option on rust-lld. //@ needs-rust-lld +//@ needs-llvm-zstd //@ only-linux //@ ignore-cross-compile // FIXME: This test isn't comprehensive and isn't covering all possible combinations. -use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc}; +use run_make_support::{llvm_readobj, run_in_tmpdir, rustc}; fn check_compression(compression: &str, to_find: &str) { run_in_tmpdir(|| { @@ -17,19 +18,8 @@ fn check_compression(compression: &str, to_find: &str) { .arg("-Cdebuginfo=full") .link_arg(&format!("-Wl,--compress-debug-sections={compression}")) .input("main.rs") - .run_unchecked(); - let stderr = out.stderr_utf8(); - if stderr.is_empty() { - llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); - } else { - assert_contains( - stderr, - format!( - "LLVM was not built with LLVM_ENABLE_{to_find} \ - or did not find {compression} at build time" - ), - ); - } + .run(); + llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); }); } From 8b5118ca17bb11f76ac7bdf96b3cf91293f5be8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 15:52:58 +0000 Subject: [PATCH 12/20] make `compressed-debuginfo` test about zlib only zlib is seemingly always enabled, so we can test it unconditionally --- tests/run-make/compressed-debuginfo/rmake.rs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 5ba1a1852d51b..362b2e2e1e449 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -1,11 +1,9 @@ -// Checks the `debuginfo-compression` option. +// Checks the always enabled `debuginfo-compression` option: zlib. //@ only-linux //@ ignore-cross-compile -// FIXME: This test isn't comprehensive and isn't covering all possible combinations. - -use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc}; +use run_make_support::{llvm_readobj, run_in_tmpdir, rustc}; fn check_compression(compression: &str, to_find: &str) { run_in_tmpdir(|| { @@ -17,19 +15,10 @@ fn check_compression(compression: &str, to_find: &str) { .arg(&format!("-Zdebuginfo-compression={compression}")) .input("foo.rs") .run(); - let stderr = out.stderr_utf8(); - if stderr.is_empty() { - llvm_readobj().arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); - } else { - assert_contains( - stderr, - format!("unknown debuginfo compression algorithm {compression}"), - ); - } + llvm_readobj().arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); }); } fn main() { check_compression("zlib", "ZLIB"); - check_compression("zstd", "ZSTD"); } From de40866abb3dc046ede122bfae81bf84ce08ba77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 16:22:04 +0000 Subject: [PATCH 13/20] prepare test for expanding scope --- .../main.rs | 0 .../rmake.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/run-make/{rust-lld-compress-debug-sections => compressed-debuginfo-zstd}/main.rs (100%) rename tests/run-make/{rust-lld-compress-debug-sections => compressed-debuginfo-zstd}/rmake.rs (100%) diff --git a/tests/run-make/rust-lld-compress-debug-sections/main.rs b/tests/run-make/compressed-debuginfo-zstd/main.rs similarity index 100% rename from tests/run-make/rust-lld-compress-debug-sections/main.rs rename to tests/run-make/compressed-debuginfo-zstd/main.rs diff --git a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs similarity index 100% rename from tests/run-make/rust-lld-compress-debug-sections/rmake.rs rename to tests/run-make/compressed-debuginfo-zstd/rmake.rs From 9d24aa898d575f5b7a74f72aa5fe8efcacd39d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 16:59:00 +0000 Subject: [PATCH 14/20] expand zstd debuginfo compression test it now checks zlib and zstd, via rustc and rust-lld --- .../compressed-debuginfo-zstd/rmake.rs | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs index 9889659046ea7..8356373e949aa 100644 --- a/tests/run-make/compressed-debuginfo-zstd/rmake.rs +++ b/tests/run-make/compressed-debuginfo-zstd/rmake.rs @@ -1,24 +1,37 @@ -// Checks the `compress-debug-sections` option on rust-lld. +// Checks debuginfo compression both for the always-enabled zlib, and when the optional zstd is +// enabled: +// - via rustc's `debuginfo-compression`, +// - and via rust-lld's `compress-debug-sections` -//@ needs-rust-lld -//@ needs-llvm-zstd +//@ needs-llvm-zstd: we want LLVM/LLD to be built with zstd support +//@ needs-rust-lld: the system linker will most likely not support zstd //@ only-linux //@ ignore-cross-compile -// FIXME: This test isn't comprehensive and isn't covering all possible combinations. - -use run_make_support::{llvm_readobj, run_in_tmpdir, rustc}; +use run_make_support::{llvm_readobj, run_in_tmpdir, Rustc}; fn check_compression(compression: &str, to_find: &str) { + // check compressed debug sections via rustc flag + prepare_and_check(to_find, |rustc| { + rustc.arg(&format!("-Zdebuginfo-compression={compression}")) + }); + + // check compressed debug sections via rust-lld flag + prepare_and_check(to_find, |rustc| { + rustc.link_arg(&format!("-Wl,--compress-debug-sections={compression}")) + }); +} + +fn prepare_and_check &mut Rustc>(to_find: &str, prepare_rustc: F) { run_in_tmpdir(|| { - let out = rustc() + let mut rustc = Rustc::new(); + rustc .arg("-Zlinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .arg("-Cdebuginfo=full") - .link_arg(&format!("-Wl,--compress-debug-sections={compression}")) - .input("main.rs") - .run(); + .input("main.rs"); + prepare_rustc(&mut rustc).run(); llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find); }); } From 182edede6085202dc748e538253a68d7aeff4781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sat, 10 Aug 2024 22:25:22 +0000 Subject: [PATCH 15/20] move and rename zstd script move it where it's used, and name it like the other scripts --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 6 +++--- .../zstd.sh => host-x86_64/dist-x86_64-linux/build-zstd.sh} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename src/ci/docker/{scripts/zstd.sh => host-x86_64/dist-x86_64-linux/build-zstd.sh} (100%) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 61e9694f1e2ae..e857f38e68a85 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -62,9 +62,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/ RUN ./build-clang.sh ENV CC=clang CXX=clang++ -# rustc's LLVM needs zstd. -COPY scripts/zstd.sh /tmp/ -RUN ./zstd.sh +# Build zstd to enable `llvm.libzstd`. +COPY host-x86_64/dist-x86_64-linux/build-zstd.sh /tmp/ +RUN ./build-zstd.sh COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/scripts/zstd.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh similarity index 100% rename from src/ci/docker/scripts/zstd.sh rename to src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh From 595052921f22c8184fe233e93b233a5db0a06936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 11 Aug 2024 15:02:13 +0000 Subject: [PATCH 16/20] strip whitespace for ignored tests reason comments --- src/tools/compiletest/src/header/needs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index e04abea0bf987..72b1b9c6d480a 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -174,7 +174,7 @@ pub(super) fn handle_needs( } else { return IgnoreDecision::Ignore { reason: if let Some(comment) = comment { - format!("{} ({comment})", need.ignore_reason) + format!("{} ({})", need.ignore_reason, comment.trim()) } else { need.ignore_reason.into() }, From 9d29bf9a6be3f740a92b200d527c7ee9e819a75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 11 Aug 2024 19:05:30 +0000 Subject: [PATCH 17/20] enable `llvm.libzstd` on test x64 linux builder --- src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile index 19683317126ab..83c2aa8cfb3b7 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile @@ -28,5 +28,6 @@ ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-sanitizers \ --enable-profiler \ - --enable-compiler-docs + --enable-compiler-docs \ + --set llvm.libzstd=true ENV SCRIPT python3 ../x.py --stage 2 test From 0452bf4981071b5eee30d7eed4a613072ec27acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 20 Aug 2024 14:04:44 +0000 Subject: [PATCH 18/20] allow `llvm.libzstd` with `download-ci-llvm = true` but warn about it --- src/bootstrap/src/core/config/config.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ce23b7735f8bd..bdfee55d8d183 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1885,6 +1885,22 @@ impl Config { warn("link-shared"); } + // FIXME(#129153): instead of all the ad-hoc `download-ci-llvm` checks that follow, + // use the `builder-config` present in tarballs since #128822 to compare the local + // config to the ones used to build the LLVM artifacts on CI, and only notify users + // if they've chosen a different value. + + if libzstd.is_some() { + println!( + "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ + like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ + artifacts builder config." + ); + println!( + "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." + ); + } + // None of the LLVM options, except assertions, are supported // when using downloaded LLVM. We could just ignore these but // that's potentially confusing, so force them to not be @@ -1894,7 +1910,6 @@ impl Config { check_ci_llvm!(optimize_toml); check_ci_llvm!(thin_lto); check_ci_llvm!(release_debuginfo); - check_ci_llvm!(libzstd); check_ci_llvm!(targets); check_ci_llvm!(experimental_targets); check_ci_llvm!(clang_cl); From 318dfb405f1744dbdb94e83c5ba6969d712c09aa Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 1 Aug 2024 13:17:34 -0400 Subject: [PATCH 19/20] rewrite libtest-thread-limit to rmake --- Cargo.lock | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/libtest-thread-limit/Makefile | 7 -- tests/run-make/libtest-thread-limit/rmake.rs | 64 +++++++++++++++++++ tests/run-make/libtest-thread-limit/test.rs | 7 +- 7 files changed, 73 insertions(+), 9 deletions(-) delete mode 100644 tests/run-make/libtest-thread-limit/Makefile create mode 100644 tests/run-make/libtest-thread-limit/rmake.rs diff --git a/Cargo.lock b/Cargo.lock index a18219b56837e..97146fcfd516d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3129,6 +3129,7 @@ dependencies = [ "bstr", "build_helper", "gimli 0.31.0", + "libc", "object 0.36.3", "regex", "serde_json", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 1a13d56b0e42f..77df6e7beb591 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -12,3 +12,4 @@ regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace gimli = "0.31.0" build_helper = { path = "../build_helper" } serde_json = "1.0" +libc = "0.2" diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index fc20fd3b2e86a..d010ed29f1d26 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -36,6 +36,7 @@ pub mod rfs { // Re-exports of third-party library crates. pub use bstr; pub use gimli; +pub use libc; pub use object; pub use regex; pub use serde_json; diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f55abb513b80d..0f7213c536a89 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -6,7 +6,6 @@ run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile -run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile diff --git a/tests/run-make/libtest-thread-limit/Makefile b/tests/run-make/libtest-thread-limit/Makefile deleted file mode 100644 index 9496fa30159a6..0000000000000 --- a/tests/run-make/libtest-thread-limit/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -# only-linux - -all: - $(RUSTC) test.rs --test --target $(TARGET) - $(shell ulimit -p 0 && $(call RUN,test)) diff --git a/tests/run-make/libtest-thread-limit/rmake.rs b/tests/run-make/libtest-thread-limit/rmake.rs new file mode 100644 index 0000000000000..be0eeaf1717db --- /dev/null +++ b/tests/run-make/libtest-thread-limit/rmake.rs @@ -0,0 +1,64 @@ +// libtest used to panic if it hit the thread limit. This often resulted in spurious test failures +// (thread 'main' panicked at 'called Result::unwrap() on an Err value: Os +// { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }' ... +// error: test failed, to rerun pass '--lib'). +// Since the fix in #81546, the test should continue to run synchronously +// if it runs out of threads. Therefore, this test's final execution step +// should succeed without an error. +// See https://github.com/rust-lang/rust/pull/81546 + +//@ only-linux +// Reason: thread limit modification +//@ ignore-cross-compile +// Reason: this test fails armhf-gnu, reasons unknown + +use std::ffi::{self, CStr, CString}; +use std::path::PathBuf; + +use run_make_support::{libc, run, rustc}; + +fn main() { + rustc().input("test.rs").arg("--test").run(); + + // We need to emulate an environment for libtest where threads are exhausted and spawning + // new threads are guaranteed to fail. This was previously achieved by ulimit shell builtin + // that called out to prlimit64 underneath to set resource limits (specifically thread + // number limits). Now that we don't have a shell, we need to implement that ourselves. + // See https://linux.die.net/man/2/setrlimit + + // The fork + exec is required because we cannot first try to limit the number of + // processes/threads to 1 and then try to spawn a new process to run the test. We need to + // setrlimit and run the libtest test program in the same process. + let pid = unsafe { libc::fork() }; + assert!(pid >= 0); + + // If the process ID is 0, this is the child process responsible for running the test + // program. + if pid == 0 { + let test = CString::new("test").unwrap(); + // The argv array should be terminated with a NULL pointer. + let argv = [test.as_ptr(), std::ptr::null()]; + // rlim_cur is soft limit, rlim_max is hard limit. + // By setting the limit very low (max 1), we ensure that libtest is unable to create new + // threads. + let rlimit = libc::rlimit { rlim_cur: 1, rlim_max: 1 }; + // RLIMIT_NPROC: The maximum number of processes (or, more precisely on Linux, + // threads) that can be created for the real user ID of the calling process. Upon + // encountering this limit, fork(2) fails with the error EAGAIN. + // Therefore, set the resource limit to RLIMIT_NPROC. + let ret = unsafe { libc::setrlimit(libc::RLIMIT_NPROC, &rlimit as *const libc::rlimit) }; + assert_eq!(ret, 0); + + // Finally, execute the 2 tests in test.rs. + let ret = unsafe { libc::execv(test.as_ptr(), argv.as_ptr()) }; + assert_eq!(ret, 0); + } else { + // Otherwise, other process IDs indicate that this is the parent process. + + let mut status: libc::c_int = 0; + let ret = unsafe { libc::waitpid(pid, &mut status as *mut libc::c_int, 0) }; + assert_eq!(ret, pid); + assert!(libc::WIFEXITED(status)); + assert_eq!(libc::WEXITSTATUS(status), 0); + } +} diff --git a/tests/run-make/libtest-thread-limit/test.rs b/tests/run-make/libtest-thread-limit/test.rs index 87e1d51917106..d4eb12426158b 100644 --- a/tests/run-make/libtest-thread-limit/test.rs +++ b/tests/run-make/libtest-thread-limit/test.rs @@ -10,7 +10,12 @@ fn spawn_thread_would_block() { THREAD_ID.set(thread::current().id()).unwrap(); } +// Tests are run in alphabetical order, and the second test is dependent on the +// first to set THREAD_ID. Do not rename the tests in such a way that `test_run_in_same_thread` +// would run before `spawn_thread_would_block`. +// See https://doc.rust-lang.org/rustc/tests/index.html#--shuffle + #[test] -fn run_in_same_thread() { +fn test_run_in_same_thread() { assert_eq!(*THREAD_ID.get().unwrap(), thread::current().id()); } From 4e0ca2b41a392d685c5fa5fbfd7aa41e28f5f8d1 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 23 Aug 2024 09:28:30 +0200 Subject: [PATCH 20/20] CI: rfl: move to temporary commit Link: https://github.com/rust-lang/rust/pull/129416 Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index d690aac27fae6..389abb2fdd38c 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,7 +2,7 @@ set -euo pipefail -LINUX_VERSION=v6.11-rc1 +LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee # Build rustc, rustdoc and cargo ../x.py build --stage 1 library rustdoc @@ -28,7 +28,7 @@ rm -rf linux || true # Download Linux at a specific commit mkdir -p linux git -C linux init -git -C linux remote add origin https://github.com/torvalds/linux.git +git -C linux remote add origin https://github.com/Rust-for-Linux/linux.git git -C linux fetch --depth 1 origin ${LINUX_VERSION} git -C linux checkout FETCH_HEAD