diff options
| author | Ralf Jung <post@ralfj.de> | 2024-12-26 18:32:22 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-12-31 12:41:20 +0100 |
| commit | 2bf27e09beb4cd1c5f01369e7086e36b3de04f5c (patch) | |
| tree | cbc3c2d940b7b06fbe2d03a5234f20459295a028 /compiler/rustc_codegen_ssa | |
| parent | 41b579660c0af700d42abe5b71856098db007783 (diff) | |
| download | rust-2bf27e09beb4cd1c5f01369e7086e36b3de04f5c.tar.gz rust-2bf27e09beb4cd1c5f01369e7086e36b3de04f5c.zip | |
explicitly model that certain ABIs require/forbid certain target features
Diffstat (limited to 'compiler/rustc_codegen_ssa')
| -rw-r--r-- | compiler/rustc_codegen_ssa/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/target_features.rs | 52 |
2 files changed, 26 insertions, 28 deletions
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 56188714b44..484f467068a 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -67,7 +67,7 @@ codegen_ssa_failed_to_write = failed to write {$path}: {$error} codegen_ssa_field_associated_value_expected = associated value expected for `{$name}` codegen_ssa_forbidden_target_feature_attr = - target feature `{$feature}` cannot be toggled with `#[target_feature]`: {$reason} + target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason} codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 7e80d014ea2..af9ff311061 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -32,7 +32,7 @@ pub(crate) fn from_target_feature_attr( .emit(); }; let rust_features = tcx.features(); - let mut added_target_features = Vec::new(); + let (_abi_enable, abi_disable) = tcx.sess.target.abi_required_features(); for item in list { // Only `enable = ...` is accepted in the meta-item list. if !item.has_name(sym::enable) { @@ -47,7 +47,7 @@ pub(crate) fn from_target_feature_attr( }; // We allow comma separation to enable multiple features. - added_target_features.extend(value.as_str().split(',').filter_map(|feature| { + for feature in value.as_str().split(',') { let Some(stability) = rust_target_features.get(feature) else { let msg = format!("the feature named `{feature}` is not valid for this target"); let mut err = tcx.dcx().struct_span_err(item.span(), msg); @@ -59,7 +59,7 @@ pub(crate) fn from_target_feature_attr( } } err.emit(); - return None; + continue; }; // Only allow target features whose feature gates have been enabled @@ -80,31 +80,25 @@ pub(crate) fn from_target_feature_attr( format!("the target feature `{feature}` is currently unstable"), ) .emit(); + } else { + // Add this and the implied features. + let feature_sym = Symbol::intern(feature); + for &name in tcx.implied_target_features(feature_sym) { + // But ensure the ABI does not forbid enabling this. + // Here we do assume that LLVM doesn't add even more implied features + // we don't know about, at least no features that would have ABI effects! + if abi_disable.contains(&name.as_str()) { + tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr { + span: item.span(), + feature: name.as_str(), + reason: "this feature is incompatible with the target ABI", + }); + } + target_features.push(TargetFeature { name, implied: name != feature_sym }) + } } - Some(Symbol::intern(feature)) - })); - } - - // Add explicit features - target_features.extend( - added_target_features.iter().copied().map(|name| TargetFeature { name, implied: false }), - ); - - // Add implied features - let mut implied_target_features = UnordSet::new(); - for feature in added_target_features.iter() { - implied_target_features.extend(tcx.implied_target_features(*feature).clone()); - } - for feature in added_target_features.iter() { - implied_target_features.remove(feature); + } } - target_features.extend( - implied_target_features - .into_sorted_stable_ord() - .iter() - .copied() - .map(|name| TargetFeature { name, implied: true }), - ) } /// Computes the set of target features used in a function for the purposes of @@ -163,9 +157,13 @@ pub(crate) fn provide(providers: &mut Providers) { .collect() } }, - implied_target_features: |tcx, feature| { + implied_target_features: |tcx, feature: Symbol| { + let feature = feature.as_str(); UnordSet::from(tcx.sess.target.implied_target_features(std::iter::once(feature))) .into_sorted_stable_ord() + .into_iter() + .map(|s| Symbol::intern(s)) + .collect() }, asm_target_features, ..*providers |
