mirror of
https://github.com/rust-lang/rust.git
synced 2025-12-30 01:55:29 +00:00
-Zretpoline and -Zretpoline-external-thunk flags (target modifiers) to enable retpoline-related target features
This commit is contained in:
parent
7c10378e1f
commit
5601490c9d
@ -2,9 +2,6 @@ codegen_gcc_unknown_ctarget_feature_prefix =
|
||||
unknown feature specified for `-Ctarget-feature`: `{$feature}`
|
||||
.note = features must begin with a `+` to enable or `-` to disable it
|
||||
|
||||
codegen_gcc_forbidden_ctarget_feature =
|
||||
target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason}
|
||||
|
||||
codegen_gcc_unwinding_inline_asm =
|
||||
GCC backend does not support unwinding from inline asm
|
||||
|
||||
@ -26,10 +23,6 @@ codegen_gcc_unknown_ctarget_feature =
|
||||
.possible_feature = you might have meant: `{$rust_feature}`
|
||||
.consider_filing_feature_request = consider filing a feature request
|
||||
|
||||
codegen_gcc_unstable_ctarget_feature =
|
||||
unstable feature specified for `-Ctarget-feature`: `{$feature}`
|
||||
.note = this feature is not stably supported; its behavior can change in the future
|
||||
|
||||
codegen_gcc_missing_features =
|
||||
add the missing features in a `target_feature` attribute
|
||||
|
||||
|
||||
@ -17,21 +17,6 @@ pub(crate) struct UnknownCTargetFeature<'a> {
|
||||
pub rust_feature: PossibleFeature<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_gcc_unstable_ctarget_feature)]
|
||||
#[note]
|
||||
pub(crate) struct UnstableCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_gcc_forbidden_ctarget_feature)]
|
||||
pub(crate) struct ForbiddenCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
pub enabled: &'a str,
|
||||
pub reason: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum PossibleFeature<'a> {
|
||||
#[help(codegen_gcc_possible_feature)]
|
||||
|
||||
@ -5,13 +5,17 @@ use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::features::{StabilityExt, retpoline_features_by_flags};
|
||||
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
||||
use crate::errors::{
|
||||
ForbiddenCTargetFeature, PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix,
|
||||
UnstableCTargetFeature,
|
||||
};
|
||||
use crate::errors::{PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix};
|
||||
|
||||
fn gcc_features_by_flags(sess: &Session) -> Vec<&str> {
|
||||
let mut features: Vec<&str> = Vec::new();
|
||||
retpoline_features_by_flags(sess, &mut features);
|
||||
features
|
||||
}
|
||||
|
||||
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
|
||||
/// `--target` and similar).
|
||||
@ -45,7 +49,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
|
||||
|
||||
// Compute implied features
|
||||
let mut all_rust_features = vec![];
|
||||
for feature in sess.opts.cg.target_feature.split(',') {
|
||||
for feature in sess.opts.cg.target_feature.split(',').chain(gcc_features_by_flags(sess)) {
|
||||
if let Some(feature) = feature.strip_prefix('+') {
|
||||
all_rust_features.extend(
|
||||
UnordSet::from(sess.target.implied_target_features(feature))
|
||||
@ -94,18 +98,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
|
||||
sess.dcx().emit_warn(unknown_feature);
|
||||
}
|
||||
Some(&(_, stability, _)) => {
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
sess.dcx().emit_warn(ForbiddenCTargetFeature {
|
||||
feature,
|
||||
enabled: if enable { "enabled" } else { "disabled" },
|
||||
reason,
|
||||
});
|
||||
} else if stability.requires_nightly().is_some() {
|
||||
// An unstable feature. Warn about using it. (It makes little sense
|
||||
// to hard-error here since we just warn about fully unknown
|
||||
// features above).
|
||||
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
|
||||
}
|
||||
stability.verify_feature_enabled_by_flag(sess, enable, feature);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,11 +10,6 @@ codegen_llvm_dynamic_linking_with_lto =
|
||||
|
||||
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
|
||||
|
||||
codegen_llvm_forbidden_ctarget_feature =
|
||||
target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}
|
||||
.note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
codegen_llvm_forbidden_ctarget_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
codegen_llvm_from_llvm_diag = {$message}
|
||||
|
||||
codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}
|
||||
@ -76,10 +71,6 @@ codegen_llvm_unknown_ctarget_feature_prefix =
|
||||
|
||||
codegen_llvm_unknown_debuginfo_compression = unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo
|
||||
|
||||
codegen_llvm_unstable_ctarget_feature =
|
||||
unstable feature specified for `-Ctarget-feature`: `{$feature}`
|
||||
.note = this feature is not stably supported; its behavior can change in the future
|
||||
|
||||
codegen_llvm_write_bytecode = failed to write bytecode to {$path}: {$err}
|
||||
|
||||
codegen_llvm_write_ir = failed to write LLVM IR to {$path}
|
||||
|
||||
@ -24,23 +24,6 @@ pub(crate) struct UnknownCTargetFeature<'a> {
|
||||
pub rust_feature: PossibleFeature<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_unstable_ctarget_feature)]
|
||||
#[note]
|
||||
pub(crate) struct UnstableCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_llvm_forbidden_ctarget_feature)]
|
||||
#[note]
|
||||
#[note(codegen_llvm_forbidden_ctarget_feature_issue)]
|
||||
pub(crate) struct ForbiddenCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
pub enabled: &'a str,
|
||||
pub reason: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum PossibleFeature<'a> {
|
||||
#[help(codegen_llvm_possible_feature)]
|
||||
|
||||
@ -16,6 +16,7 @@ use rustc_fs_util::path_to_c_string;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{PrintKind, PrintRequest};
|
||||
use rustc_session::features::{StabilityExt, retpoline_features_by_flags};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport};
|
||||
use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES};
|
||||
@ -23,8 +24,7 @@ use smallvec::{SmallVec, smallvec};
|
||||
|
||||
use crate::back::write::create_informational_target_machine;
|
||||
use crate::errors::{
|
||||
FixedX18InvalidArch, ForbiddenCTargetFeature, PossibleFeature, UnknownCTargetFeature,
|
||||
UnknownCTargetFeaturePrefix, UnstableCTargetFeature,
|
||||
FixedX18InvalidArch, PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix,
|
||||
};
|
||||
use crate::llvm;
|
||||
|
||||
@ -707,6 +707,12 @@ pub(crate) fn target_cpu(sess: &Session) -> &str {
|
||||
handle_native(cpu_name)
|
||||
}
|
||||
|
||||
fn llvm_features_by_flags(sess: &Session) -> Vec<&str> {
|
||||
let mut features: Vec<&str> = Vec::new();
|
||||
retpoline_features_by_flags(sess, &mut features);
|
||||
features
|
||||
}
|
||||
|
||||
/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
|
||||
/// `--target` and similar).
|
||||
pub(crate) fn global_llvm_features(
|
||||
@ -787,7 +793,7 @@ pub(crate) fn global_llvm_features(
|
||||
|
||||
// Compute implied features
|
||||
let mut all_rust_features = vec![];
|
||||
for feature in sess.opts.cg.target_feature.split(',') {
|
||||
for feature in sess.opts.cg.target_feature.split(',').chain(llvm_features_by_flags(sess)) {
|
||||
if let Some(feature) = feature.strip_prefix('+') {
|
||||
all_rust_features.extend(
|
||||
UnordSet::from(sess.target.implied_target_features(feature))
|
||||
@ -840,18 +846,7 @@ pub(crate) fn global_llvm_features(
|
||||
sess.dcx().emit_warn(unknown_feature);
|
||||
}
|
||||
Some((_, stability, _)) => {
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
sess.dcx().emit_warn(ForbiddenCTargetFeature {
|
||||
feature,
|
||||
enabled: if enable { "enabled" } else { "disabled" },
|
||||
reason,
|
||||
});
|
||||
} else if stability.requires_nightly().is_some() {
|
||||
// An unstable feature. Warn about using it. It makes little sense
|
||||
// to hard-error here since we just warn about fully unknown
|
||||
// features above.
|
||||
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
|
||||
}
|
||||
stability.verify_feature_enabled_by_flag(sess, enable, feature);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::features::StabilityExt;
|
||||
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
@ -66,7 +67,7 @@ pub(crate) fn from_target_feature_attr(
|
||||
|
||||
// Only allow target features whose feature gates have been enabled
|
||||
// and which are permitted to be toggled.
|
||||
if let Err(reason) = stability.toggle_allowed() {
|
||||
if let Err(reason) = stability.is_toggle_permitted(tcx.sess) {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature,
|
||||
|
||||
@ -40,6 +40,11 @@ session_file_is_not_writeable = output file {$file} is not writeable -- check it
|
||||
|
||||
session_file_write_fail = failed to write `{$path}` due to error `{$err}`
|
||||
|
||||
session_forbidden_ctarget_feature =
|
||||
target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}
|
||||
.note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
session_forbidden_ctarget_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
session_function_return_requires_x86_or_x86_64 = `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64
|
||||
|
||||
session_function_return_thunk_extern_requires_non_large_code_model = `-Zfunction-return=thunk-extern` is only supported on non-large code models
|
||||
@ -132,6 +137,9 @@ session_target_stack_protector_not_supported = `-Z stack-protector={$stack_prote
|
||||
session_unleashed_feature_help_named = skipping check for `{$gate}` feature
|
||||
session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate
|
||||
|
||||
session_unstable_ctarget_feature =
|
||||
unstable feature specified for `-Ctarget-feature`: `{$feature}`
|
||||
.note = this feature is not stably supported; its behavior can change in the future
|
||||
session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto`
|
||||
|
||||
session_unsupported_crate_type_for_target =
|
||||
|
||||
@ -2649,6 +2649,15 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||
|
||||
let prints = collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
|
||||
|
||||
// -Zretpoline-external-thunk also requires -Zretpoline
|
||||
if unstable_opts.retpoline_external_thunk {
|
||||
unstable_opts.retpoline = true;
|
||||
target_modifiers.insert(
|
||||
OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::retpoline),
|
||||
"true".to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
let cg = cg;
|
||||
|
||||
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
|
||||
|
||||
@ -501,3 +501,20 @@ pub(crate) struct SoftFloatIgnored;
|
||||
#[note]
|
||||
#[note(session_soft_float_deprecated_issue)]
|
||||
pub(crate) struct SoftFloatDeprecated;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_forbidden_ctarget_feature)]
|
||||
#[note]
|
||||
#[note(session_forbidden_ctarget_feature_issue)]
|
||||
pub(crate) struct ForbiddenCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
pub enabled: &'a str,
|
||||
pub reason: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_unstable_ctarget_feature)]
|
||||
#[note]
|
||||
pub(crate) struct UnstableCTargetFeature<'a> {
|
||||
pub feature: &'a str,
|
||||
}
|
||||
|
||||
59
compiler/rustc_session/src/features.rs
Normal file
59
compiler/rustc_session/src/features.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use rustc_target::target_features::Stability;
|
||||
|
||||
use crate::Session;
|
||||
use crate::errors::{ForbiddenCTargetFeature, UnstableCTargetFeature};
|
||||
|
||||
pub trait StabilityExt {
|
||||
/// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`.
|
||||
/// Otherwise, some features also may only be enabled by flag (target modifier).
|
||||
/// (It might still be nightly-only even if this returns `true`, so make sure to also check
|
||||
/// `requires_nightly`.)
|
||||
fn is_toggle_permitted(&self, sess: &Session) -> Result<(), &'static str>;
|
||||
|
||||
/// Check that feature is correctly enabled/disabled by command line flag (emits warnings)
|
||||
fn verify_feature_enabled_by_flag(&self, sess: &Session, enable: bool, feature: &str);
|
||||
}
|
||||
|
||||
impl StabilityExt for Stability {
|
||||
fn is_toggle_permitted(&self, sess: &Session) -> Result<(), &'static str> {
|
||||
match self {
|
||||
Stability::Forbidden { reason } => Err(reason),
|
||||
Stability::TargetModifierOnly { reason, flag } => {
|
||||
if !sess.opts.target_feature_flag_enabled(*flag) { Err(reason) } else { Ok(()) }
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
fn verify_feature_enabled_by_flag(&self, sess: &Session, enable: bool, feature: &str) {
|
||||
if let Err(reason) = self.is_toggle_permitted(sess) {
|
||||
sess.dcx().emit_warn(ForbiddenCTargetFeature {
|
||||
feature,
|
||||
enabled: if enable { "enabled" } else { "disabled" },
|
||||
reason,
|
||||
});
|
||||
} else if self.requires_nightly().is_some() {
|
||||
// An unstable feature. Warn about using it. It makes little sense
|
||||
// to hard-error here since we just warn about fully unknown
|
||||
// features above.
|
||||
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retpoline_features_by_flags(sess: &Session, features: &mut Vec<&str>) {
|
||||
// -Zretpoline without -Zretpoline-external-thunk enables
|
||||
// retpoline-indirect-branches and retpoline-indirect-calls target features
|
||||
let unstable_opts = &sess.opts.unstable_opts;
|
||||
if unstable_opts.retpoline && !unstable_opts.retpoline_external_thunk {
|
||||
features.push("+retpoline-indirect-branches");
|
||||
features.push("+retpoline-indirect-calls");
|
||||
}
|
||||
// -Zretpoline-external-thunk (maybe, with -Zretpoline too) enables
|
||||
// retpoline-external-thunk, retpoline-indirect-branches and
|
||||
// retpoline-indirect-calls target features
|
||||
if unstable_opts.retpoline_external_thunk {
|
||||
features.push("+retpoline-external-thunk");
|
||||
features.push("+retpoline-indirect-branches");
|
||||
features.push("+retpoline-indirect-calls");
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,7 @@ pub use session::*;
|
||||
pub mod output;
|
||||
|
||||
pub use getopts;
|
||||
pub mod features;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
|
||||
@ -290,6 +290,14 @@ macro_rules! top_level_options {
|
||||
mods.sort_by(|a, b| a.opt.cmp(&b.opt));
|
||||
mods
|
||||
}
|
||||
|
||||
pub fn target_feature_flag_enabled(&self, flag: &str) -> bool {
|
||||
match flag {
|
||||
"retpoline" => self.unstable_opts.retpoline,
|
||||
"retpoline-external-thunk" => self.unstable_opts.retpoline_external_thunk,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -2446,6 +2454,11 @@ options! {
|
||||
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
||||
"directory into which to write optimization remarks (if not specified, they will be \
|
||||
written to standard error output)"),
|
||||
retpoline: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
|
||||
"enables retpoline-indirect-branches and retpoline-indirect-calls target features (default: no)"),
|
||||
retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
|
||||
"enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \
|
||||
target features (default: no)"),
|
||||
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
|
||||
"use a sanitizer"),
|
||||
sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
|
||||
|
||||
@ -34,6 +34,9 @@ pub enum Stability {
|
||||
/// particular for features are actually ABI configuration flags (not all targets are as nice as
|
||||
/// RISC-V and have an explicit way to set the ABI separate from target features).
|
||||
Forbidden { reason: &'static str },
|
||||
/// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be set
|
||||
/// by target modifier flag. Target modifier flags are tracked to be consistent in linked modules.
|
||||
TargetModifierOnly { reason: &'static str, flag: &'static str },
|
||||
}
|
||||
use Stability::*;
|
||||
|
||||
@ -49,6 +52,7 @@ impl<CTX> HashStable<CTX> for Stability {
|
||||
Stability::Forbidden { reason } => {
|
||||
reason.hash_stable(hcx, hasher);
|
||||
}
|
||||
Stability::TargetModifierOnly { .. } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,16 +78,7 @@ impl Stability {
|
||||
Stability::Unstable(nightly_feature) => Some(nightly_feature),
|
||||
Stability::Stable { .. } => None,
|
||||
Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`.
|
||||
/// (It might still be nightly-only even if this returns `true`, so make sure to also check
|
||||
/// `requires_nightly`.)
|
||||
pub fn toggle_allowed(&self) -> Result<(), &'static str> {
|
||||
match self {
|
||||
Stability::Forbidden { reason } => Err(reason),
|
||||
_ => Ok(()),
|
||||
Stability::TargetModifierOnly { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -453,6 +448,30 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
||||
("prfchw", Unstable(sym::prfchw_target_feature), &[]),
|
||||
("rdrand", Stable, &[]),
|
||||
("rdseed", Stable, &[]),
|
||||
(
|
||||
"retpoline-external-thunk",
|
||||
Stability::TargetModifierOnly {
|
||||
reason: "use `retpoline-external-thunk` target modifier flag instead",
|
||||
flag: "retpoline-external-thunk",
|
||||
},
|
||||
&[],
|
||||
),
|
||||
(
|
||||
"retpoline-indirect-branches",
|
||||
Stability::TargetModifierOnly {
|
||||
reason: "use `retpoline` target modifier flag instead",
|
||||
flag: "retpoline",
|
||||
},
|
||||
&[],
|
||||
),
|
||||
(
|
||||
"retpoline-indirect-calls",
|
||||
Stability::TargetModifierOnly {
|
||||
reason: "use `retpoline` target modifier flag instead",
|
||||
flag: "retpoline",
|
||||
},
|
||||
&[],
|
||||
),
|
||||
("rtm", Unstable(sym::rtm_target_feature), &[]),
|
||||
("sha", Stable, &["sse2"]),
|
||||
("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
|
||||
|
||||
@ -18,6 +18,7 @@ use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::{DefId, DefIdSet};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::features::StabilityExt;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustdoc_json_types as types;
|
||||
// It's important to use the FxHashMap from rustdoc_json_types here, instead of
|
||||
@ -148,7 +149,7 @@ fn target(sess: &rustc_session::Session) -> types::Target {
|
||||
.copied()
|
||||
.filter(|(_, stability, _)| {
|
||||
// Describe only target features which the user can toggle
|
||||
stability.toggle_allowed().is_ok()
|
||||
stability.is_toggle_permitted(sess).is_ok()
|
||||
})
|
||||
.map(|(name, stability, implied_features)| {
|
||||
types::TargetFeature {
|
||||
@ -164,7 +165,7 @@ fn target(sess: &rustc_session::Session) -> types::Target {
|
||||
// Imply only target features which the user can toggle
|
||||
feature_stability
|
||||
.get(name)
|
||||
.map(|stability| stability.toggle_allowed().is_ok())
|
||||
.map(|stability| stability.is_toggle_permitted(sess).is_ok())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.map(String::from)
|
||||
|
||||
29
tests/codegen/retpoline.rs
Normal file
29
tests/codegen/retpoline.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// ignore-tidy-linelength
|
||||
// Test that the
|
||||
// `retpoline-external-thunk`, `retpoline-indirect-branches`, `retpoline-indirect-calls`
|
||||
// target features are (not) emitted when the `retpoline/retpoline-external-thunk` flag is (not) set.
|
||||
|
||||
//@ revisions: disabled enabled_retpoline enabled_retpoline_external_thunk
|
||||
//@ needs-llvm-components: x86
|
||||
//@ compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//@ [enabled_retpoline] compile-flags: -Zretpoline
|
||||
//@ [enabled_retpoline_external_thunk] compile-flags: -Zretpoline-external-thunk
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn foo() {
|
||||
// CHECK: @foo() unnamed_addr #0
|
||||
|
||||
// disabled-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+retpoline-external-thunk{{.*}} }
|
||||
// disabled-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+retpoline-indirect-branches{{.*}} }
|
||||
// disabled-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+retpoline-indirect-calls{{.*}} }
|
||||
|
||||
// enabled_retpoline: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+retpoline-indirect-branches,+retpoline-indirect-calls{{.*}} }
|
||||
// enabled_retpoline_external_thunk: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+retpoline-external-thunk,+retpoline-indirect-branches,+retpoline-indirect-calls{{.*}} }
|
||||
}
|
||||
@ -212,6 +212,9 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
|
||||
`relax`
|
||||
`relaxed-simd`
|
||||
`reserve-x18`
|
||||
`retpoline-external-thunk`
|
||||
`retpoline-indirect-branches`
|
||||
`retpoline-indirect-calls`
|
||||
`rtm`
|
||||
`sb`
|
||||
`scq`
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
warning: target feature `retpoline-external-thunk` cannot be enabled with `-Ctarget-feature`: use `x86-retpoline` target modifier flag instead
|
||||
|
|
||||
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
warning: target feature `retpoline-external-thunk` cannot be enabled with `-Ctarget-feature`: use `retpoline-external-thunk` target modifier flag instead
|
||||
|
|
||||
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
warning: target feature `retpoline-indirect-branches` cannot be enabled with `-Ctarget-feature`: use `retpoline` target modifier flag instead
|
||||
|
|
||||
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
warning: target feature `retpoline-indirect-calls` cannot be enabled with `-Ctarget-feature`: use `retpoline` target modifier flag instead
|
||||
|
|
||||
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
23
tests/ui/target-feature/retpoline-target-feature-flag.rs
Normal file
23
tests/ui/target-feature/retpoline-target-feature-flag.rs
Normal file
@ -0,0 +1,23 @@
|
||||
//@ revisions: by_flag by_feature1 by_feature2 by_feature3
|
||||
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
|
||||
//@ needs-llvm-components: x86
|
||||
//@ [by_flag]compile-flags: -Zretpoline
|
||||
|
||||
//@ [by_feature1]compile-flags: -Ctarget-feature=+retpoline-external-thunk
|
||||
//@ [by_feature2]compile-flags: -Ctarget-feature=+retpoline-indirect-branches
|
||||
//@ [by_feature3]compile-flags: -Ctarget-feature=+retpoline-indirect-calls
|
||||
//@ [by_flag]build-pass
|
||||
// For now this is just a warning.
|
||||
//@ [by_feature1]build-pass
|
||||
//@ [by_feature2]build-pass
|
||||
//@ [by_feature3]build-pass
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
//[by_feature1]~? WARN target feature `retpoline-external-thunk` cannot be enabled with `-Ctarget-feature`: use `retpoline-external-thunk` target modifier flag instead
|
||||
//[by_feature2]~? WARN target feature `retpoline-indirect-branches` cannot be enabled with `-Ctarget-feature`: use `retpoline` target modifier flag instead
|
||||
//[by_feature3]~? WARN target feature `retpoline-indirect-calls` cannot be enabled with `-Ctarget-feature`: use `retpoline` target modifier flag instead
|
||||
Loading…
x
Reference in New Issue
Block a user