diff options
| author | bors <bors@rust-lang.org> | 2023-09-22 05:07:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-09-22 05:07:45 +0000 |
| commit | aace2dfa37f4589b0071530d2ed7b352f6196704 (patch) | |
| tree | 085e424b22822d32e05954baa744c3b27e9fa42f /compiler | |
| parent | b7573187180a6ad13ba557f85b7e19a51f8fdaf1 (diff) | |
| parent | 9102816bc4deca950b66cce402ea45573acc8fa0 (diff) | |
| download | rust-aace2dfa37f4589b0071530d2ed7b352f6196704.tar.gz rust-aace2dfa37f4589b0071530d2ed7b352f6196704.zip | |
Auto merge of #115910 - eduardosm:lang-fns-target-features, r=cjgillot
Prevent using `#[target_feature]` on lang item functions Fixes https://github.com/rust-lang/rust/issues/109411 and also prevents from using `#[target_feature]` on other `fn` lang items to mitigate the concerns from https://github.com/rust-lang/rust/issues/109411#issuecomment-1477030273.
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 4f8ce99417a..dc0776c5dad 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -407,6 +407,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 2d94354e3e1..12118a0268b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -118,7 +118,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) @@ -591,10 +591,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] |
