Skip to content

Commit a340e78

Browse files
committed
fix GCC backend
1 parent 006d35a commit a340e78

File tree

4 files changed

+59
-25
lines changed

4 files changed

+59
-25
lines changed

compiler/rustc_codegen_gcc/messages.ftl

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ codegen_gcc_lto_not_supported =
1111
codegen_gcc_tied_target_features = the target features {$features} must all be either enabled or disabled together
1212
.help = add the missing features in a `target_feature` attribute
1313
14+
codegen_gcc_forbidden_ctarget_feature =
15+
target feature `{$feature}` cannot be toggled with `-Ctarget-feature`
16+
1417
codegen_gcc_unwinding_inline_asm =
1518
GCC backend does not support unwinding from inline asm
1619
@@ -27,11 +30,15 @@ codegen_gcc_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdyl
2730
codegen_gcc_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$gcc_err})
2831
2932
codegen_gcc_unknown_ctarget_feature =
30-
unknown feature specified for `-Ctarget-feature`: `{$feature}`
31-
.note = it is still passed through to the codegen backend
33+
unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
34+
.note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
3235
.possible_feature = you might have meant: `{$rust_feature}`
3336
.consider_filing_feature_request = consider filing a feature request
3437
38+
codegen_gcc_unstable_ctarget_feature =
39+
unstable feature specified for `-Ctarget-feature`: `{$feature}`
40+
.note = this feature is not stably supported; its behavior can change in the future
41+
3542
codegen_gcc_missing_features =
3643
add the missing features in a `target_feature` attribute
3744

compiler/rustc_codegen_gcc/src/errors.rs

+13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ pub(crate) struct UnknownCTargetFeature<'a> {
2020
pub rust_feature: PossibleFeature<'a>,
2121
}
2222

23+
#[derive(Diagnostic)]
24+
#[diag(codegen_gcc_unstable_ctarget_feature)]
25+
#[note]
26+
pub(crate) struct UnstableCTargetFeature<'a> {
27+
pub feature: &'a str,
28+
}
29+
30+
#[derive(Diagnostic)]
31+
#[diag(codegen_gcc_forbidden_ctarget_feature)]
32+
pub(crate) struct ForbiddenCTargetFeature<'a> {
33+
pub feature: &'a str,
34+
}
35+
2336
#[derive(Subdiagnostic)]
2437
pub(crate) enum PossibleFeature<'a> {
2538
#[help(codegen_gcc_possible_feature)]

compiler/rustc_codegen_gcc/src/gcc_util.rs

+36-22
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ use gccjit::Context;
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_middle::bug;
55
use rustc_session::Session;
6-
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
6+
use rustc_target::target_features::{Stability, RUSTC_SPECIFIC_FEATURES};
77
use smallvec::{smallvec, SmallVec};
88

99
use crate::errors::{
10-
PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature,
11-
UnknownCTargetFeaturePrefix,
10+
ForbiddenCTargetFeature, PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature,
11+
UnknownCTargetFeaturePrefix, UnstableCTargetFeature,
1212
};
1313

1414
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
@@ -44,7 +44,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
4444
);
4545

4646
// -Ctarget-features
47-
let supported_features = sess.target.supported_target_features();
47+
let known_features = sess.target.known_target_features();
4848
let mut featsmap = FxHashMap::default();
4949
let feats = sess
5050
.opts
@@ -65,27 +65,41 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
6565

6666
let feature = backend_feature_name(s)?;
6767
// Warn against use of GCC specific feature names on the CLI.
68-
if diagnostics && !supported_features.iter().any(|&(v, _, _)| v == feature) {
69-
let rust_feature = supported_features.iter().find_map(|&(rust_feature, _, _)| {
70-
let gcc_features = to_gcc_features(sess, rust_feature);
71-
if gcc_features.contains(&feature) && !gcc_features.contains(&rust_feature) {
72-
Some(rust_feature)
73-
} else {
74-
None
68+
if diagnostics {
69+
let feature_state = known_features.iter().find(|&&(v, _, _)| v == feature);
70+
match feature_state {
71+
None => {
72+
let rust_feature =
73+
known_features.iter().find_map(|&(rust_feature, _, _)| {
74+
let gcc_features = to_gcc_features(sess, rust_feature);
75+
if gcc_features.contains(&feature)
76+
&& !gcc_features.contains(&rust_feature)
77+
{
78+
Some(rust_feature)
79+
} else {
80+
None
81+
}
82+
});
83+
let unknown_feature = if let Some(rust_feature) = rust_feature {
84+
UnknownCTargetFeature {
85+
feature,
86+
rust_feature: PossibleFeature::Some { rust_feature },
87+
}
88+
} else {
89+
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
90+
};
91+
sess.dcx().emit_warn(unknown_feature);
7592
}
76-
});
77-
let unknown_feature = if let Some(rust_feature) = rust_feature {
78-
UnknownCTargetFeature {
79-
feature,
80-
rust_feature: PossibleFeature::Some { rust_feature },
93+
Some((_, Stability::Stable, _)) => {}
94+
Some((_, Stability::Unstable(_), _)) => {
95+
// An unstable feature. Warn about using it.
96+
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
8197
}
82-
} else {
83-
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
84-
};
85-
sess.dcx().emit_warn(unknown_feature);
86-
}
98+
Some((_, Stability::Forbidden, _)) => {
99+
sess.dcx().emit_err(ForbiddenCTargetFeature { feature });
100+
}
101+
}
87102

88-
if diagnostics {
89103
// FIXME(nagisa): figure out how to not allocate a full hashset here.
90104
featsmap.insert(feature, enable_disable == '+');
91105
}

compiler/rustc_codegen_gcc/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ pub fn target_features(
484484
) -> Vec<Symbol> {
485485
// TODO(antoyo): use global_gcc_features.
486486
sess.target
487-
.supported_target_features()
487+
.known_target_features()
488488
.iter()
489489
.filter_map(|&(feature, gate, _)| {
490490
if sess.is_nightly_build() || allow_unstable || gate.is_stable() {

0 commit comments

Comments
 (0)