Skip to content

Commit 4017676

Browse files
committed
forbid toggling x87 and fpregs on hard-float targets
1 parent 2c30751 commit 4017676

12 files changed

+129
-2
lines changed

compiler/rustc_feature/src/unstable.rs

+1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ declare_features! (
340340
(unstable, sse4a_target_feature, "1.27.0", Some(44839)),
341341
(unstable, tbm_target_feature, "1.27.0", Some(44839)),
342342
(unstable, wasm_target_feature, "1.30.0", Some(44839)),
343+
(unstable, x87_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
343344
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!
344345
// Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
345346
// !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!!

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2171,6 +2171,7 @@ symbols! {
21712171
writeln_macro,
21722172
x86_amx_intrinsics,
21732173
x87_reg,
2174+
x87_target_feature,
21742175
xer,
21752176
xmm_reg,
21762177
xop_target_feature,

compiler/rustc_target/src/spec/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -2594,6 +2594,18 @@ impl TargetOptions {
25942594
.collect();
25952595
}
25962596
}
2597+
2598+
pub(crate) fn has_feature(&self, search_feature: &str) -> bool {
2599+
self.features.split(',').any(|f| {
2600+
if let Some(f) = f.strip_prefix('+')
2601+
&& f == search_feature
2602+
{
2603+
true
2604+
} else {
2605+
false
2606+
}
2607+
})
2608+
}
25972609
}
25982610

25992611
impl Default for TargetOptions {

compiler/rustc_target/src/target_features.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub enum Stability<AllowToggle> {
3232
/// This target feature is unstable. It is only present in `#[cfg(target_feature)]` on
3333
/// nightly and using it in `#[target_feature]` requires enabling the given nightly feature.
3434
Unstable {
35+
/// This must be a *language* feature, or else rustc will ICE when reporting a missing
36+
/// feature gate!
3537
nightly_feature: Symbol,
3638
/// See `Stable::allow_toggle` comment above.
3739
allow_toggle: AllowToggle,
@@ -168,6 +170,22 @@ const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
168170
("dotprod", unstable(sym::arm_target_feature), &["neon"]),
169171
("dsp", unstable(sym::arm_target_feature), &[]),
170172
("fp-armv8", unstable(sym::arm_target_feature), &["vfp4"]),
173+
(
174+
"fpregs",
175+
Stability::Unstable {
176+
nightly_feature: sym::arm_target_feature,
177+
allow_toggle: |target: &Target| {
178+
// Only allow toggling this if the target has `soft-float` set. With `soft-float`,
179+
// `fpregs` isn't needed so changing it cannot affect the ABI.
180+
if target.has_feature("soft-float") {
181+
Ok(())
182+
} else {
183+
Err("unsound on hard-float targets because it changes float ABI")
184+
}
185+
},
186+
},
187+
&[],
188+
),
171189
("i8mm", unstable(sym::arm_target_feature), &["neon"]),
172190
("mclass", unstable(sym::arm_target_feature), &[]),
173191
("neon", unstable(sym::arm_target_feature), &["vfp3"]),
@@ -191,7 +209,6 @@ const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
191209
("vfp4", unstable(sym::arm_target_feature), &["vfp3"]),
192210
("virtualization", unstable(sym::arm_target_feature), &[]),
193211
// tidy-alphabetical-end
194-
// FIXME: need to also forbid turning off `fpregs` on hardfloat targets
195212
];
196213

197214
const AARCH64_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
@@ -444,13 +461,28 @@ const X86_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
444461
("tbm", unstable(sym::tbm_target_feature), &[]),
445462
("vaes", unstable(sym::avx512_target_feature), &["avx2", "aes"]),
446463
("vpclmulqdq", unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
464+
(
465+
"x87",
466+
Stability::Unstable {
467+
nightly_feature: sym::x87_target_feature,
468+
allow_toggle: |target: &Target| {
469+
// Only allow toggling this if the target has `soft-float` set. With `soft-float`,
470+
// `fpregs` isn't needed so changing it cannot affect the ABI.
471+
if target.has_feature("soft-float") {
472+
Ok(())
473+
} else {
474+
Err("unsound on hard-float targets because it changes float ABI")
475+
}
476+
},
477+
},
478+
&[],
479+
),
447480
("xop", unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
448481
("xsave", STABLE, &[]),
449482
("xsavec", STABLE, &["xsave"]),
450483
("xsaveopt", STABLE, &["xsave"]),
451484
("xsaves", STABLE, &["xsave"]),
452485
// tidy-alphabetical-end
453-
// FIXME: need to also forbid turning off `x87` on hardfloat targets
454486
];
455487

456488
const HEXAGON_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
2+
//@ needs-llvm-components: x86
3+
//@ build-pass
4+
#![feature(no_core, lang_items, x87_target_feature)]
5+
#![no_std]
6+
#![no_core]
7+
8+
#[lang = "sized"]
9+
pub trait Sized {}
10+
11+
#[target_feature(enable = "x87")]
12+
pub unsafe fn my_fun() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ compile-flags: --target=x86_64-unknown-none --crate-type=lib
2+
//@ needs-llvm-components: x86
3+
//@ compile-flags: -Ctarget-feature=-x87
4+
//@ build-pass
5+
#![feature(no_core, lang_items)]
6+
#![no_std]
7+
#![no_core]
8+
9+
#[lang = "sized"]
10+
pub trait Sized {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: unstable feature specified for `-Ctarget-feature`: `x87`
2+
|
3+
= note: this feature is not stably supported; its behavior can change in the future
4+
5+
warning: 1 warning emitted
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
2+
//@ needs-llvm-components: x86
3+
#![feature(no_core, lang_items)]
4+
#![no_std]
5+
#![no_core]
6+
7+
#[lang = "sized"]
8+
pub trait Sized {}
9+
10+
#[target_feature(enable = "x87")]
11+
//~^ERROR: cannot be toggled with
12+
pub unsafe fn my_fun() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: target feature `x87` cannot be toggled with `#[target_feature]`: unsound on hard-float targets because it changes float ABI
2+
--> $DIR/forbidden-hardfloat-target-feature-attribute.rs:10:18
3+
|
4+
LL | #[target_feature(enable = "x87")]
5+
| ^^^^^^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
2+
//@ needs-llvm-components: x86
3+
//@ check-pass
4+
#![feature(no_core, lang_items)]
5+
#![no_std]
6+
#![no_core]
7+
#![allow(unexpected_cfgs)]
8+
9+
#[lang = "sized"]
10+
pub trait Sized {}
11+
12+
// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this
13+
// complains about the missing macro rather than showing the error... but that's good enough.
14+
#[cfg(not(target_feature = "x87"))]
15+
compile_error!("the x87 feature *should* be exposed in `cfg`");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
2+
//@ needs-llvm-components: x86
3+
//@ compile-flags: -Ctarget-feature=-x87
4+
// For now this is just a warning.
5+
//@ build-pass
6+
#![feature(no_core, lang_items)]
7+
#![no_std]
8+
#![no_core]
9+
10+
#[lang = "sized"]
11+
pub trait Sized {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
warning: target feature `x87` cannot be toggled with `-Ctarget-feature`: unsound on hard-float targets because it changes float ABI
2+
|
3+
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4+
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
5+
6+
warning: 1 warning emitted
7+

0 commit comments

Comments
 (0)