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_codegen_gcc/src/gcc_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_target::spec::Arch;

fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
target_features::retpoline_features_by_flags(sess, features);
target_features::sls_features_by_flags(sess, features);
// FIXME: LLVM also sets +reserve-x18 here under some conditions.
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {

target_features::retpoline_features_by_flags(sess, features);
target_features::sanitizer_features_by_flags(sess, features);
target_features::sls_features_by_flags(sess, features);

// -Zfixed-x18
if sess.opts.unstable_opts.fixed_x18 {
Expand Down
25 changes: 22 additions & 3 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::config::HardenSls;
use rustc_session::errors::feature_err;
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
use rustc_span::{Span, Symbol, edit_distance, sym};
Expand Down Expand Up @@ -308,12 +309,18 @@ pub fn cfg_target_feature<'a, const N: usize>(
sess.dcx().emit_warn(unknown_feature);
}
Some((_, stability, _)) => {
if let Err(reason) = stability.toggle_allowed() {
sess.dcx().emit_warn(errors::ForbiddenCTargetFeature {
if let Stability::Forbidden { reason, hard_error } = stability {
let diag = errors::ForbiddenCTargetFeature {
feature: base_feature,
enabled: if enable { "enabled" } else { "disabled" },
reason,
});
};

if *hard_error {
sess.dcx().emit_err(diag);
} else {
sess.dcx().emit_warn(diag);
}
} else if stability.requires_nightly(/* in_cfg */ false).is_some() {
// An unstable feature. Warn about using it. It makes little sense
// to hard-error here since we just warn about fully unknown
Expand Down Expand Up @@ -488,6 +495,18 @@ pub fn sanitizer_features_by_flags(sess: &Session, features: &mut Vec<String>) {
}
}

pub fn sls_features_by_flags(sess: &Session, features: &mut Vec<String>) {
match &sess.opts.unstable_opts.harden_sls {
HardenSls::None => (),
HardenSls::All => {
features.push("+harden-sls-ijmp".into());
features.push("+harden-sls-ret".into());
}
HardenSls::Return => features.push("+harden-sls-ret".into()),
HardenSls::IndirectJmp => features.push("+harden-sls-ijmp".into()),
}
}

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
rust_target_features: |tcx, cnum| {
Expand Down
20 changes: 16 additions & 4 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3069,10 +3069,11 @@ pub(crate) mod dep_tracking {
use super::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
HardenSls, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel,
OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks,
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
WasiExecModel,
};
use crate::lint;
use crate::utils::NativeLib;
Expand Down Expand Up @@ -3175,6 +3176,7 @@ pub(crate) mod dep_tracking {
Polonius,
InliningThreshold,
FunctionReturn,
HardenSls,
Align,
);

Expand Down Expand Up @@ -3389,6 +3391,16 @@ pub enum FunctionReturn {
ThunkExtern,
}

/// The different settings that the `-Zharden-sls` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum HardenSls {
#[default]
None,
All,
Return,
IndirectJmp,
}

/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
#[derive(Clone, Copy, Default, PartialEq, Debug)]
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`";
pub(crate) const parse_harden_sls: &str = "`none`, `all`, `return` or `indirect-jmp`";
pub(crate) const parse_wasm_c_abi: &str = "`spec`";
pub(crate) const parse_mir_include_spans: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
Expand Down Expand Up @@ -1986,6 +1987,17 @@ pub mod parse {
true
}

pub(crate) fn parse_harden_sls(slot: &mut HardenSls, v: Option<&str>) -> bool {
match v {
Some("none") => *slot = HardenSls::None,
Some("all") => *slot = HardenSls::All,
Some("return") => *slot = HardenSls::Return,
Some("indirect-jmp") => *slot = HardenSls::IndirectJmp,
_ => return false,
}
true
}

pub(crate) fn parse_wasm_c_abi(_slot: &mut (), v: Option<&str>) -> bool {
v == Some("spec")
}
Expand Down Expand Up @@ -2350,6 +2362,9 @@ options! {
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
"use the given `fontname` in graphviz output; can be overridden by setting \
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
harden_sls: HardenSls = (HardenSls::None, parse_harden_sls, [TRACKED] { TARGET_MODIFIER: HardenSls },
"flag to mitigate against straight line speculation (SLS) [none|all|return|indirect-jmp] \
(default: none)"),
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the `cfg(target_thread_local)` directive"),
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),
Expand Down
96 changes: 81 additions & 15 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! Note that these are similar to but not always identical to LLVM's feature names,
//! and Rust adds some features that do not correspond to LLVM features at all.
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_macros::StableHash;
use rustc_data_structures::stable_hasher::{StableHash, StableHashCtxt, StableHasher};
use rustc_span::{Symbol, sym};

use crate::spec::{Arch, FloatAbi, LlvmAbi, RustcAbi, Target};
Expand All @@ -12,7 +12,7 @@ use crate::spec::{Arch, FloatAbi, LlvmAbi, RustcAbi, Target};
pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];

/// Stability information for target features.
#[derive(Debug, Copy, Clone, StableHash)]
#[derive(Debug, Copy, Clone)]
pub enum Stability {
/// This target feature is stable, it can be used in `#[target_feature]` and
/// `#[cfg(target_feature)]`.
Expand All @@ -35,10 +35,35 @@ pub enum Stability {
/// set in the target spec. It is never set in `cfg(target_feature)`. Used in
/// 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 },
Forbidden {
reason: &'static str,
/// True if this is always an error, false if this can be reported as a warning when set via
/// `-Ctarget-feature`.
hard_error: bool,
},
}
use Stability::*;

impl StableHash for Stability {
#[inline]
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
std::mem::discriminant(self).stable_hash(hcx, hasher);
match self {
Stability::Stable => {}
Stability::Unstable(nightly_feature) => {
nightly_feature.stable_hash(hcx, hasher);
}
Stability::CfgStableToggleUnstable(nightly_feature) => {
nightly_feature.stable_hash(hcx, hasher);
}
Stability::Forbidden { reason, hard_error } => {
reason.stable_hash(hcx, hasher);
hard_error.stable_hash(hcx, hasher);
}
}
}
}

impl Stability {
/// Returns whether the feature can be used in `cfg(target_feature)` ever.
/// (It might still be nightly-only even if this returns `true`, so make sure to also check
Expand Down Expand Up @@ -85,14 +110,14 @@ impl Stability {
}

/// 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
/// (It might still be nightly-only even if this returns `Ok(())`, so make sure to also check
/// `requires_nightly`.)
pub fn toggle_allowed(&self) -> Result<(), &'static str> {
match self {
Stability::Unstable(_)
| Stability::CfgStableToggleUnstable(_)
| Stability::Stable { .. } => Ok(()),
Stability::Forbidden { reason } => Err(reason),
Stability::Forbidden { reason, hard_error: _ } => Err(reason),
}
}
}
Expand Down Expand Up @@ -149,7 +174,10 @@ static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("aes", Unstable(sym::arm_target_feature), &["neon"]),
(
"atomics-32",
Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
Stability::Forbidden {
reason: "unsound because it changes the ABI of atomic operations",
hard_error: false,
},
&[],
),
("crc", Unstable(sym::arm_target_feature), &[]),
Expand Down Expand Up @@ -225,7 +253,11 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// FEAT_FLAGM2
("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
// We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`.
("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]),
(
"fp-armv8",
Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`", hard_error: false },
&[],
),
// FEAT_FP8
("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
// FEAT_FP8DOT2
Expand Down Expand Up @@ -288,7 +320,11 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
// FEAT_RDM
("rdm", Stable, &["neon"]),
("reserve-x18", Forbidden { reason: "use `-Zfixed-x18` compiler flag instead" }, &[]),
(
"reserve-x18",
Forbidden { reason: "use `-Zfixed-x18` compiler flag instead", hard_error: false },
&[],
),
// FEAT_SB
("sb", Stable, &[]),
// FEAT_SHA1 & FEAT_SHA256
Expand Down Expand Up @@ -455,6 +491,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("fma4", Unstable(sym::fma4_target_feature), &["avx", "sse4a"]),
("fxsr", Stable, &[]),
("gfni", Stable, &["sse2"]),
(
"harden-sls-ijmp",
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true },
&[],
),
(
"harden-sls-ret",
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true },
&[],
),
("kl", Stable, &["sse2"]),
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
("lzcnt", Stable, &[]),
Expand All @@ -467,25 +513,38 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("rdseed", Stable, &[]),
(
"retpoline-external-thunk",
Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" },
Stability::Forbidden {
reason: "use `-Zretpoline-external-thunk` compiler flag instead",
hard_error: false,
},
&[],
),
(
"retpoline-indirect-branches",
Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
Stability::Forbidden {
reason: "use `-Zretpoline` compiler flag instead",
hard_error: false,
},
&[],
),
(
"retpoline-indirect-calls",
Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" },
Stability::Forbidden {
reason: "use `-Zretpoline` compiler flag instead",
hard_error: false,
},
&[],
),
("rtm", Unstable(sym::rtm_target_feature), &[]),
("sha", Stable, &["sse2"]),
("sha512", Stable, &["avx2"]),
("sm3", Stable, &["avx"]),
("sm4", Stable, &["avx2"]),
("soft-float", Stability::Forbidden { reason: "use a soft-float target instead" }, &[]),
(
"soft-float",
Stability::Forbidden { reason: "use a soft-float target instead", hard_error: false },
&[],
),
("sse", Stable, &[]),
("sse2", Stable, &["sse"]),
("sse3", Stable, &["sse2"]),
Expand Down Expand Up @@ -615,7 +674,10 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
(
"forced-atomics",
Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
Stability::Forbidden {
reason: "unsound because it changes the ABI of atomic operations",
hard_error: false,
},
&[],
),
("m", Stable, &[]),
Expand Down Expand Up @@ -872,7 +934,7 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("miscellaneous-extensions-3", Stable, &[]),
("miscellaneous-extensions-4", Stable, &[]),
("nnp-assist", Stable, &["vector"]),
("soft-float", Forbidden { reason: "unsupported ABI-configuration feature" }, &[]),
("soft-float", Forbidden { reason: "unsupported ABI-configuration feature", hard_error: false }, &[]),
("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
("vector", Stable, &[]),
("vector-enhancements-1", Stable, &["vector"]),
Expand Down Expand Up @@ -924,7 +986,11 @@ static AVR_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("rmw", Unstable(sym::avr_target_feature), &[]),
("spm", Unstable(sym::avr_target_feature), &[]),
("spmx", Unstable(sym::avr_target_feature), &[]),
("sram", Forbidden { reason: "devices that have no SRAM are unsupported" }, &[]),
(
"sram",
Forbidden { reason: "devices that have no SRAM are unsupported", hard_error: false },
&[],
),
("tinyencoding", Unstable(sym::avr_target_feature), &[]),
// tidy-alphabetical-end
];
Expand Down
14 changes: 8 additions & 6 deletions src/doc/rustc-dev-guide/src/tests/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,14 @@ See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ig

| Directive | Explanation | Supported test suites | Possible values |
|---------------------|----------------------------------------------------------------------------------------------|--------------------------------------------|--------------------------------------------------------------------------------------------|
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value |
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `<KEY>=<VALUE>` |
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name |
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
| `minicore-compile-flags` | Additional flags passed to `rustc` when building minicore | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
| `non-aux-compile-flags` | Additional flags passed to `rustc` when building the test (not for auxiliary builds) | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value |
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `<KEY>=<VALUE>` |
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name |
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |

<div class="warning">

Expand Down
5 changes: 5 additions & 0 deletions src/doc/rustc-dev-guide/src/tests/minicore.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ The `minicore` items must be kept up to date with `core`.
For consistent diagnostic output between using `core` and `minicore`, any `diagnostic`
attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`.

## Specific compile flags
`compile-flags` is used both for auxiliary builds (including minicore) and main test build.
`minicore-compile-flags` directive may be used to provide compile flags for minicore build only.
`non-aux-compile-flags` directive may be used to provide compile flags for main test only.

## Example codegen test that uses `minicore`

```rust,no_run
Expand Down
Loading
Loading