Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #136045

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8099510
Fix linking for symbols starting with ?
checkraisefold Sep 25, 2024
784d47b
Add a test
checkraisefold Dec 31, 2024
a4c628c
Significant test improvements
checkraisefold Dec 31, 2024
f81ebfb
Match LLVM behavior more closely
checkraisefold Jan 14, 2025
bf36338
Accept tidy changes
checkraisefold Jan 14, 2025
9c3b53d
Apply tidy suggestion (2)
checkraisefold Jan 14, 2025
893d81f
on s390x, use `PassMode::Direct` for vector types
folkertdev Jan 20, 2025
9d6a1c9
Shorten linker output even more when `--verbose` is not present
jyn514 Jan 18, 2025
2a544ab
Target modifiers (special marked options) are recorded in metainfo an…
azhogin Nov 17, 2024
a745b60
Only use linker-flavor=gnu-cc if we're actually going to compare the …
jyn514 Jan 22, 2025
aaccb71
Fix sparcv8plus test on LLVM 20
nikic Jan 20, 2025
2718710
Fix x86_64-bigint-helpers test on LLVM 20
nikic Jan 20, 2025
dd52bfc
Reword "crate not found" resolve message
estebank Nov 18, 2024
7c885c1
Compare object files, not PATH
jyn514 Jan 19, 2025
7786f7f
run-make-support: add `sysroot` helper
jieyouxu Jan 21, 2025
1912d56
run-make-support: improve docs for `assert_exit_code`
jieyouxu Jan 22, 2025
388a52f
tests: port `translation` to rmake.rs
jieyouxu Jan 21, 2025
f9daba6
Rollup merge of #130808 - checkraisefold:fix-questionmark-linking, r=…
matthiaskrgr Jan 25, 2025
0724550
Rollup merge of #133138 - azhogin:azhogin/target-modifiers, r=davidtw…
matthiaskrgr Jan 25, 2025
e2c8f55
Rollup merge of #133154 - estebank:issue-133137, r=wesleywiser
matthiaskrgr Jan 25, 2025
da33dc3
Rollup merge of #135707 - jyn514:linker-messages-2, r=bjorn3
matthiaskrgr Jan 25, 2025
c8f74eb
Rollup merge of #135764 - nikic:llvm-20-test-fixes, r=wesleywiser
matthiaskrgr Jan 25, 2025
b73f4c2
Rollup merge of #135785 - folkertdev:s390x-vector-passmode-direct, r=…
matthiaskrgr Jan 25, 2025
3cc4dd1
Rollup merge of #135818 - jieyouxu:migrate-translation, r=compiler-er…
matthiaskrgr Jan 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3537,6 +3537,7 @@ dependencies = [
"ar_archive_writer",
"arrayvec",
"bitflags",
"bstr",
"cc",
"either",
"itertools",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
ar_archive_writer = "0.4.2"
arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
bstr = "1.11.3"
# Pinned so `cargo update` bumps don't cause breakage. Please also update the
# `cc` in `rustc_llvm` if you update the `cc` here.
cc = "=1.2.7"
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub(crate) struct Command {
args: Vec<OsString>,
env: Vec<(OsString, OsString)>,
env_remove: Vec<OsString>,
env_clear: bool,
}

#[derive(Clone)]
Expand All @@ -36,7 +37,13 @@ impl Command {
}

fn _new(program: Program) -> Command {
Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() }
Command {
program,
args: Vec::new(),
env: Vec::new(),
env_remove: Vec::new(),
env_clear: false,
}
}

pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
Expand Down Expand Up @@ -79,6 +86,11 @@ impl Command {
self
}

pub(crate) fn env_clear(&mut self) -> &mut Command {
self.env_clear = true;
self
}

fn _env_remove(&mut self, key: &OsStr) {
self.env_remove.push(key.to_owned());
}
Expand Down Expand Up @@ -106,6 +118,9 @@ impl Command {
for k in &self.env_remove {
ret.env_remove(k);
}
if self.env_clear {
ret.env_clear();
}
ret
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,7 @@ fn link_natively(
command: cmd,
escaped_output,
verbose: sess.opts.verbose,
sysroot_dir: sess.sysroot.clone(),
};
sess.dcx().emit_err(err);
// If MSVC's `link.exe` was expected but the return code
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
}

let prefix = match &target.arch[..] {
"x86" | "x86_64" if target.is_like_msvc && undecorated.starts_with("?") => {
return undecorated;
}
"x86" => Some('_'),
"x86_64" => None,
"arm64ec" => Some('#'),
Expand Down
62 changes: 47 additions & 15 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ pub(crate) struct LinkingFailed<'a> {
pub command: Command,
pub escaped_output: String,
pub verbose: bool,
pub sysroot_dir: PathBuf,
}

impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
Expand All @@ -364,6 +365,8 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
if self.verbose {
diag.note(format!("{:?}", self.command));
} else {
self.command.env_clear();

enum ArgGroup {
Regular(OsString),
Objects(usize),
Expand Down Expand Up @@ -398,26 +401,55 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
args.push(ArgGroup::Regular(arg));
}
}
self.command.args(args.into_iter().map(|arg_group| match arg_group {
ArgGroup::Regular(arg) => arg,
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
ArgGroup::Rlibs(dir, rlibs) => {
let mut arg = dir.into_os_string();
arg.push("/{");
let mut first = true;
for rlib in rlibs {
if !first {
arg.push(",");
let crate_hash = regex::bytes::Regex::new(r"-[0-9a-f]+\.rlib$").unwrap();
self.command.args(args.into_iter().map(|arg_group| {
match arg_group {
// SAFETY: we are only matching on ASCII, not any surrogate pairs, so any replacements we do will still be valid.
ArgGroup::Regular(arg) => unsafe {
use bstr::ByteSlice;
OsString::from_encoded_bytes_unchecked(
arg.as_encoded_bytes().replace(
self.sysroot_dir.as_os_str().as_encoded_bytes(),
b"<sysroot>",
),
)
},
ArgGroup::Objects(n) => OsString::from(format!("<{n} object files omitted>")),
ArgGroup::Rlibs(mut dir, rlibs) => {
let is_sysroot_dir = match dir.strip_prefix(&self.sysroot_dir) {
Ok(short) => {
dir = Path::new("<sysroot>").join(short);
true
}
Err(_) => false,
};
let mut arg = dir.into_os_string();
arg.push("/{");
let mut first = true;
for mut rlib in rlibs {
if !first {
arg.push(",");
}
first = false;
if is_sysroot_dir {
// SAFETY: Regex works one byte at a type, and our regex will not match surrogate pairs (because it only matches ascii).
rlib = unsafe {
OsString::from_encoded_bytes_unchecked(
crate_hash
.replace(rlib.as_encoded_bytes(), b"-*")
.into_owned(),
)
};
}
arg.push(rlib);
}
first = false;
arg.push(rlib);
arg.push("}.rlib");
arg
}
arg.push("}");
arg
}
}));

diag.note(format!("{:?}", self.command));
diag.note(format!("{:?}", self.command).trim_start_matches("env -i").to_owned());
diag.note("some arguments are omitted. use `--verbose` to show all linker arguments");
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0433.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ If you've expected to use a crate name:

```compile_fail
use ferris_wheel::BigO;
// error: failed to resolve: use of undeclared crate or module `ferris_wheel`
// error: failed to resolve: use of undeclared module or unlinked crate
```

Make sure the crate has been added as a dependency in `Cargo.toml`.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ fn configure_and_expand(

resolver.resolve_crate(&krate);

CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
krate
}

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_metadata/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ metadata_incompatible_rustc =
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)

metadata_incompatible_target_modifiers =
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
.note = `{$flag_name_prefixed}={$flag_local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$flag_extern_value}` in dependency `{$extern_crate}`
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely

metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error
metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$flag_extern_value}` in this crate or `{$flag_name_prefixed}={$flag_local_value}` in `{$extern_crate}`

metadata_incompatible_wasm_link =
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes

Expand Down Expand Up @@ -284,6 +292,8 @@ metadata_unknown_link_kind =
metadata_unknown_link_modifier =
unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed

metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`

metadata_unsupported_abi =
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture

Expand Down
120 changes: 118 additions & 2 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use rustc_hir::definitions::Definitions;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
use rustc_session::config::{self, CrateType, ExternLocation};
use rustc_session::config::{
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
TargetModifier,
};
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
use rustc_session::lint::{self, BuiltinLintDiag};
use rustc_session::output::validate_crate_name;
Expand All @@ -35,7 +38,9 @@ use tracing::{debug, info, trace};

use crate::errors;
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
use crate::rmeta::{
CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob, TargetModifiers,
};

/// The backend's way to give the crate store access to the metadata in a library.
/// Note that it returns the raw metadata bytes stored in the library file, whether
Expand Down Expand Up @@ -296,6 +301,96 @@ impl CStore {
}
}

fn report_target_modifiers_extended(
tcx: TyCtxt<'_>,
krate: &Crate,
mods: &Vec<TargetModifier>,
data: &CrateMetadata,
) {
let span = krate.spans.inner_span.shrink_to_lo();
let allowed_flag_mismatches = &tcx.sess.opts.cg.unsafe_allow_abi_mismatch;
let name = tcx.crate_name(LOCAL_CRATE);
let tmod_extender = |tmod: &TargetModifier| (tmod.extend(), tmod.clone());
let report_diff = |prefix: &String,
opt_name: &String,
flag_local_value: &String,
flag_extern_value: &String| {
if allowed_flag_mismatches.contains(&opt_name) {
return;
}
tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
span,
extern_crate: data.name(),
local_crate: name,
flag_name: opt_name.clone(),
flag_name_prefixed: format!("-{}{}", prefix, opt_name),
flag_local_value: flag_local_value.to_string(),
flag_extern_value: flag_extern_value.to_string(),
});
};
let mut it1 = mods.iter().map(tmod_extender);
let mut it2 = data.target_modifiers().iter().map(tmod_extender);
let mut left_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
let mut right_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
let no_val = "*".to_string();
loop {
left_name_val = left_name_val.or_else(|| it1.next());
right_name_val = right_name_val.or_else(|| it2.next());
match (&left_name_val, &right_name_val) {
(Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
cmp::Ordering::Equal => {
if l.0.tech_value != r.0.tech_value {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &r.1.value_name);
}
left_name_val = None;
right_name_val = None;
}
cmp::Ordering::Greater => {
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
right_name_val = None;
}
cmp::Ordering::Less => {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
left_name_val = None;
}
},
(Some(l), None) => {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
left_name_val = None;
}
(None, Some(r)) => {
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
right_name_val = None;
}
(None, None) => break,
}
}
}

pub fn report_incompatible_target_modifiers(&self, tcx: TyCtxt<'_>, krate: &Crate) {
for flag_name in &tcx.sess.opts.cg.unsafe_allow_abi_mismatch {
if !OptionsTargetModifiers::is_target_modifier(flag_name) {
tcx.dcx().emit_err(errors::UnknownTargetModifierUnsafeAllowed {
span: krate.spans.inner_span.shrink_to_lo(),
flag_name: flag_name.clone(),
});
}
}

if tcx.crate_types().contains(&CrateType::ProcMacro) {
return;
}
let mods = tcx.sess.opts.gather_target_modifiers();
for (_cnum, data) in self.iter_crate_data() {
if data.is_proc_macro_crate() {
continue;
}
if mods != *data.target_modifiers() {
Self::report_target_modifiers_extended(tcx, krate, &mods, data);
}
}
}

pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
CStore {
metadata_loader,
Expand Down Expand Up @@ -471,6 +566,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
};

let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
let target_modifiers = self.resolve_target_modifiers(&crate_root, &metadata, cnum)?;

let raw_proc_macros = if crate_root.is_proc_macro_crate() {
let temp_root;
Expand All @@ -495,6 +591,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
raw_proc_macros,
cnum,
cnum_map,
target_modifiers,
dep_kind,
source,
private_dep,
Expand Down Expand Up @@ -738,6 +835,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
Ok(crate_num_map)
}

fn resolve_target_modifiers(
&mut self,
crate_root: &CrateRoot,
metadata: &MetadataBlob,
krate: CrateNum,
) -> Result<TargetModifiers, CrateError> {
debug!("resolving target modifiers of external crate");
if crate_root.is_proc_macro_crate() {
return Ok(TargetModifiers::new());
}
let mods = crate_root.decode_target_modifiers(metadata);
let mut target_modifiers = TargetModifiers::with_capacity(mods.len());
for modifier in mods {
target_modifiers.push(modifier);
}
debug!("resolve_target_modifiers: target mods for {:?} is {:?}", krate, target_modifiers);
Ok(target_modifiers)
}

fn dlsym_proc_macros(
&self,
path: &Path,
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_metadata/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,28 @@ pub struct ImportNameTypeRaw {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(metadata_incompatible_target_modifiers)]
#[help]
#[note]
#[help(metadata_incompatible_target_modifiers_help_fix)]
#[help(metadata_incompatible_target_modifiers_help_allow)]
pub struct IncompatibleTargetModifiers {
#[primary_span]
pub span: Span,
pub extern_crate: Symbol,
pub local_crate: Symbol,
pub flag_name: String,
pub flag_name_prefixed: String,
pub flag_local_value: String,
pub flag_extern_value: String,
}

#[derive(Diagnostic)]
#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
pub struct UnknownTargetModifierUnsafeAllowed {
#[primary_span]
pub span: Span,
pub flag_name: String,
}
Loading
Loading