diff options
| author | Eduardo Sánchez Muñoz <eduardosm-dev@e64.io> | 2023-09-18 20:11:01 +0200 |
|---|---|---|
| committer | Eduardo Sánchez Muñoz <eduardosm-dev@e64.io> | 2023-09-18 20:11:01 +0200 |
| commit | 9102816bc4deca950b66cce402ea45573acc8fa0 (patch) | |
| tree | 296d4a2f98e5e11085c69703c6d8fd322bdd3982 /compiler | |
| parent | cdd182cbb2d11bb25d2dabdd752cc5980e0ac059 (diff) | |
| download | rust-9102816bc4deca950b66cce402ea45573acc8fa0.tar.gz rust-9102816bc4deca950b66cce402ea45573acc8fa0.zip | |
Prevent using `#[target_feature]` on lang item functions
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 4 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 10 |
3 files changed, 43 insertions, 3 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 56f4b387df8..4354e40183e 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -404,6 +404,10 @@ passes_invalid_stability = .label = invalid stability version .item = the stability attribute annotates this item +passes_lang_item_fn_with_target_feature = + `{$name}` language item function is not allowed to have `#[target_feature]` + .label = `{$name}` language item function is not allowed to have `#[target_feature]` + passes_lang_item_on_incorrect_target = `{$name}` language item must be applied to a {$expected_target} .label = attribute should be applied to a {$expected_target}, not a {$actual_target} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d10bc33db52..e0b0916d432 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -110,7 +110,7 @@ impl CheckAttrVisitor<'_> { sym::coverage => self.check_coverage(hir_id, attr, span, target), sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target), sym::marker => self.check_marker(hir_id, attr, span, target), - sym::target_feature => self.check_target_feature(hir_id, attr, span, target), + sym::target_feature => self.check_target_feature(hir_id, attr, span, target, attrs), sym::thread_local => self.check_thread_local(attr, span, target), sym::track_caller => { self.check_track_caller(hir_id, attr.span, attrs, span, target) @@ -571,10 +571,36 @@ impl CheckAttrVisitor<'_> { attr: &Attribute, span: Span, target: Target, + attrs: &[Attribute], ) -> bool { match target { - Target::Fn - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + Target::Fn => { + // `#[target_feature]` is not allowed in language items. + if let Some((lang_item, _)) = hir::lang_items::extract(attrs) + // Calling functions with `#[target_feature]` is + // not unsafe on WASM, see #84988 + && !self.tcx.sess.target.is_like_wasm + && !self.tcx.sess.opts.actually_rustdoc + { + let hir::Node::Item(item) = self.tcx.hir().get(hir_id) else { + unreachable!(); + }; + let hir::ItemKind::Fn(sig, _, _) = item.kind else { + // target is `Fn` + unreachable!(); + }; + + self.tcx.sess.emit_err(errors::LangItemWithTargetFeature { + attr_span: attr.span, + name: lang_item, + sig_span: sig.span, + }); + false + } else { + true + } + } + Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. Target::Statement => { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 8b65e301b74..2ec6a0b9241 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -809,6 +809,16 @@ pub struct MissingLangItem { } #[derive(Diagnostic)] +#[diag(passes_lang_item_fn_with_target_feature)] +pub struct LangItemWithTargetFeature { + #[primary_span] + pub attr_span: Span, + pub name: Symbol, + #[label] + pub sig_span: Span, +} + +#[derive(Diagnostic)] #[diag(passes_lang_item_on_incorrect_target, code = "E0718")] pub struct LangItemOnIncorrectTarget { #[primary_span] |
