Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
&mut sess.early_sess.opts.target_modifiers,
&target_config,
&sess.early_sess.target,
&*codegen_backend,
);

sess.check_config = parse_check_cfg(&sess, config.crate_check_cfg);
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub(crate) fn add_target_modifiers(
tmod: &mut BTreeMap<OptionsTargetModifiers, String>,
target_config: &TargetConfig,
target: &Target,
cg_backend: &dyn CodegenBackend,
) {
// Record relevant target features as target modifier.
// Join all target-modifier target features into a single comma-separated string,
Expand All @@ -108,6 +109,9 @@ pub(crate) fn add_target_modifiers(
.collect::<Vec<_>>()
.join(",");
tmod.insert(OptionsTargetModifiers::TargetFeatures, target_feature_modifier);

// Record the codegen backend name as target modifier.
tmod.insert(OptionsTargetModifiers::CodegenBackendName, cg_backend.name().to_string());
}

/// Ensures that all target features required by the ABI are present.
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ impl CStore {
assert!(local_features.len() > 0 || extern_features.len() > 0);

let diag = format!(
"mixing target features will cause an ABI mismatch in crate `{local_crate}`"
"mixing target features may cause an ABI mismatch in crate `{local_crate}`"

@RalfJung RalfJung Nov 9, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly a drive-by fix -- not all target feature mixing will cause ABI trouble, so I used "may" in the new message and updated the old one to match.

View changes since the review

);
let mut diag = tcx.dcx().struct_warn(diag);
diag.help("some target features modify the ABI so Rust crates compiled with different values for these target features cannot be used together safely");
Expand All @@ -411,6 +411,16 @@ impl CStore {
diag.help("if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=target-feature` to silence this warning");
diag.emit();
}
"codegen-backend-name" => {
let diag = format!(
"mixing codegen backends while using backend-specific target features may cause an ABI mismatch in crate `{local_crate}`"
);
let mut diag = tcx.dcx().struct_err(diag);
diag.help("this crate has `-Zllvm-target-features` set, which means different codegen backends could interpret the target features differently, or ignore them entirely");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
diag.help("this crate has `-Zllvm-target-features` set, which means different codegen backends could interpret the target features differently, or ignore them entirely");
diag.help("this crate has `-Zllvm-target-feature` set, which means different codegen backends could interpret the target features differently, or ignore them entirely");

Probably grep to see if this happened anywhere else.

diag.help("some target features modify the ABI so Rust crates compiled with different target features cannot be used together safely");
diag.help("if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=codegen-backend-name` to silence this warning");
diag.emit();
}
_ => panic!("unhandled synthetic target feature {opt_name}"),
}
return;
Expand Down
37 changes: 36 additions & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,25 @@ mod target_modifier_consistency_check {
};
l_tech_value == r_tech_value
}
pub(super) fn codegen_backend_name(
sess: &Session,
l: &TargetModifier,
r: Option<&TargetModifier>,
) -> bool {
let l_val = l.value_name.as_str();
let r_val = match r {
Some(r) => r.value_name.as_str(),
None => option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("dummy"),
};
if l_val == r_val {
// Same codegen backend: all good.
// (We assume codegen backends with the same name are compatible wrt target features.)
return true;
}
// If the codegen backends differ, there must be no LLVM target features. (Those are
// themselves a target modifier so we know they are consistent across the crate graph.)
sess.opts.unstable_opts.llvm_target_feature.is_empty()
}
}

impl TargetModifier {
Expand Down Expand Up @@ -207,6 +226,9 @@ impl TargetModifier {
return target_modifier_consistency_check::target_cpu(sess, self, other);
}
},
OptionsTargetModifiers::CodegenBackendName => {
return target_modifier_consistency_check::codegen_backend_name(sess, self, other);
}
_ => {}
};
match other {
Expand Down Expand Up @@ -246,9 +268,14 @@ macro_rules! top_level_options {
$tmod_variant($tmod_enum),
)?
)*

// Synthetic target modifiers, manually computed.

/// List of target features that are actually target modifiers.
TargetFeatures,
/// Name of the codegen backend.
/// (Not the full path to the .so file to avoid storing file system paths.)
CodegenBackendName,
}

impl OptionsTargetModifiers {
Expand All @@ -268,6 +295,13 @@ macro_rules! top_level_options {
tech_value: format!("{:?}", user_value),
}
}
Self::CodegenBackendName => {
ExtendedTargetModifierInfo {
prefix: String::new(),
name: "codegen-backend-name".into(),
tech_value: format!("{:?}", user_value),
}
}

#[allow(unreachable_patterns)]
_ => panic!("unknown target modifier option: {self:?}"),
Expand All @@ -286,7 +320,7 @@ macro_rules! top_level_options {
)*

// Synthetic target modifiers. The names must match `reparse` above.
if flag_name == "target-feature" {
if flag_name == "target-feature" || flag_name == "codegen-backend-name" {
return true;
}

Expand Down Expand Up @@ -350,6 +384,7 @@ macro_rules! top_level_options {
)?
)*
tmod_push_impl(OptionsTargetModifiers::TargetFeatures, &self.target_modifiers, &mut mods);
tmod_push_impl(OptionsTargetModifiers::CodegenBackendName, &self.target_modifiers, &mut mods);
mods.sort_by(|a, b| a.opt.cmp(&b.opt));
mods
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest/codegen_units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl TestCx<'_> {
const PREFIX: &str = "MONO_ITEM ";
const CGU_MARKER: &str = "@@";

// Some MonoItems can contain {closure@/path/to/checkout/tests/codgen-units/test.rs}
// Some MonoItems can contain {closure@/path/to/checkout/tests/codegen-units/test.rs}
// To prevent the current dir from leaking, we just replace the entire path to the test
// file with TEST_PATH.
let actual: Vec<MonoItem> = proc_res
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! A crate that uses the default codegen backend and an LLVM target feature.

//@ compile-flags: --target arm-unknown-linux-gnueabi --emit=metadata
//@ needs-llvm-components: arm
//@ compile-flags: -Zllvm-target-feature=+thumb2

#![feature(no_core)]
#![no_core]
2 changes: 1 addition & 1 deletion tests/ui-fulldeps/codegen-backend/hotplug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//@ normalize-stdout: "libthe_backend.dylib" -> "libthe_backend.so"
//@ normalize-stdout: "the_backend.dll" -> "libthe_backend.so"

// Pick a target that requires no target features, so that no warning is shown
// Pick a target that requires no target features in the ABI check, so that no warning is shown
// about missing target features.
//@ compile-flags: --target arm-unknown-linux-gnueabi
//@ needs-llvm-components: arm
Expand Down
20 changes: 20 additions & 0 deletions tests/ui-fulldeps/codegen-backend/llvm-target-features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! When using llvm-target-features, we cannot mix codegen backends.

//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
//@ ignore-backends: gcc

//@ aux-codegen-backend: the_backend.rs
//@ aux-build: with_llvm_target_feature.rs

// Pick a target that requires no target features in the ABI check, so that no warning is shown
// about missing target features.
//@ compile-flags: --target arm-unknown-linux-gnueabi --crate-type=lib
//@ needs-llvm-components: arm
//@ compile-flags: -Zllvm-target-feature=+thumb2

#![feature(no_core)]
#![no_core]

extern crate with_llvm_target_feature;

//~? ERROR: mixing codegen backends while using backend-specific target features may cause an ABI mismatch
8 changes: 8 additions & 0 deletions tests/ui-fulldeps/codegen-backend/llvm-target-features.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: mixing codegen backends while using backend-specific target features may cause an ABI mismatch in crate `llvm_target_features`
|
= help: this crate has `-Zllvm-target-features` set, which means different codegen backends could interpret the target features differently, or ignore them entirely
= help: some target features modify the ABI so Rust crates compiled with different target features cannot be used together safely
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=codegen-backend-name` to silence this warning

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
warning: mixing target features will cause an ABI mismatch in crate `abi_relevant_target_modifier`
warning: mixing target features may cause an ABI mismatch in crate `abi_relevant_target_modifier`
|
= help: some target features modify the ABI so Rust crates compiled with different values for these target features cannot be used together safely
= help: the target feature atomics-32 is enabled in `using_atomics_32` but disabled in this crate
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/target-feature/abi-relevant-target-modifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@

extern crate using_atomics_32;

//[baseline]~? WARN mixing target features will cause an ABI mismatch
//[baseline]~? WARN mixing target features may cause an ABI mismatch
Loading