Prevent using #[target_feature]
on lang item functions
This commit is contained in:
parent
cdd182cbb2
commit
9102816bc4
@ -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}
|
||||
|
@ -110,7 +110,7 @@ fn check_attributes(
|
||||
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 @@ fn check_target_feature(
|
||||
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 => {
|
||||
|
@ -808,6 +808,16 @@ pub struct MissingLangItem {
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
19
tests/ui/lang-items/start_lang_item_with_target_feature.rs
Normal file
19
tests/ui/lang-items/start_lang_item_with_target_feature.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// only-x86_64
|
||||
// check-fail
|
||||
|
||||
#![feature(lang_items, no_core, target_feature_11)]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "start"]
|
||||
#[target_feature(enable = "avx2")]
|
||||
//~^ ERROR `start` language item function is not allowed to have `#[target_feature]`
|
||||
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error: `start` language item function is not allowed to have `#[target_feature]`
|
||||
--> $DIR/start_lang_item_with_target_feature.rs:13:1
|
||||
|
|
||||
LL | #[target_feature(enable = "avx2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
||||
| ------------------------------------------------------------------------------------------- `start` language item function is not allowed to have `#[target_feature]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
15
tests/ui/panic-handler/panic-handler-with-target-feature.rs
Normal file
15
tests/ui/panic-handler/panic-handler-with-target-feature.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// compile-flags:-C panic=abort
|
||||
// only-x86_64
|
||||
|
||||
#![feature(target_feature_11)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_handler]
|
||||
#[target_feature(enable = "avx2")]
|
||||
//~^ ERROR `panic_impl` language item function is not allowed to have `#[target_feature]`
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
unimplemented!();
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
error: `panic_impl` language item function is not allowed to have `#[target_feature]`
|
||||
--> $DIR/panic-handler-with-target-feature.rs:11:1
|
||||
|
|
||||
LL | #[target_feature(enable = "avx2")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | fn panic(info: &PanicInfo) -> ! {
|
||||
| ------------------------------- `panic_impl` language item function is not allowed to have `#[target_feature]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user