Skip to content

Commit 9102816

Browse files
committed
Prevent using #[target_feature] on lang item functions
1 parent cdd182c commit 9102816

7 files changed

+99
-3
lines changed

Diff for: compiler/rustc_passes/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ passes_invalid_stability =
404404
.label = invalid stability version
405405
.item = the stability attribute annotates this item
406406
407+
passes_lang_item_fn_with_target_feature =
408+
`{$name}` language item function is not allowed to have `#[target_feature]`
409+
.label = `{$name}` language item function is not allowed to have `#[target_feature]`
410+
407411
passes_lang_item_on_incorrect_target =
408412
`{$name}` language item must be applied to a {$expected_target}
409413
.label = attribute should be applied to a {$expected_target}, not a {$actual_target}

Diff for: compiler/rustc_passes/src/check_attr.rs

+29-3
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl CheckAttrVisitor<'_> {
110110
sym::coverage => self.check_coverage(hir_id, attr, span, target),
111111
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
112112
sym::marker => self.check_marker(hir_id, attr, span, target),
113-
sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
113+
sym::target_feature => self.check_target_feature(hir_id, attr, span, target, attrs),
114114
sym::thread_local => self.check_thread_local(attr, span, target),
115115
sym::track_caller => {
116116
self.check_track_caller(hir_id, attr.span, attrs, span, target)
@@ -571,10 +571,36 @@ impl CheckAttrVisitor<'_> {
571571
attr: &Attribute,
572572
span: Span,
573573
target: Target,
574+
attrs: &[Attribute],
574575
) -> bool {
575576
match target {
576-
Target::Fn
577-
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
577+
Target::Fn => {
578+
// `#[target_feature]` is not allowed in language items.
579+
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
580+
// Calling functions with `#[target_feature]` is
581+
// not unsafe on WASM, see #84988
582+
&& !self.tcx.sess.target.is_like_wasm
583+
&& !self.tcx.sess.opts.actually_rustdoc
584+
{
585+
let hir::Node::Item(item) = self.tcx.hir().get(hir_id) else {
586+
unreachable!();
587+
};
588+
let hir::ItemKind::Fn(sig, _, _) = item.kind else {
589+
// target is `Fn`
590+
unreachable!();
591+
};
592+
593+
self.tcx.sess.emit_err(errors::LangItemWithTargetFeature {
594+
attr_span: attr.span,
595+
name: lang_item,
596+
sig_span: sig.span,
597+
});
598+
false
599+
} else {
600+
true
601+
}
602+
}
603+
Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
578604
// FIXME: #[target_feature] was previously erroneously allowed on statements and some
579605
// crates used this, so only emit a warning.
580606
Target::Statement => {

Diff for: compiler/rustc_passes/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,16 @@ pub struct MissingLangItem {
808808
pub name: Symbol,
809809
}
810810

811+
#[derive(Diagnostic)]
812+
#[diag(passes_lang_item_fn_with_target_feature)]
813+
pub struct LangItemWithTargetFeature {
814+
#[primary_span]
815+
pub attr_span: Span,
816+
pub name: Symbol,
817+
#[label]
818+
pub sig_span: Span,
819+
}
820+
811821
#[derive(Diagnostic)]
812822
#[diag(passes_lang_item_on_incorrect_target, code = "E0718")]
813823
pub struct LangItemOnIncorrectTarget {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// only-x86_64
2+
// check-fail
3+
4+
#![feature(lang_items, no_core, target_feature_11)]
5+
#![no_core]
6+
7+
#[lang = "copy"]
8+
pub trait Copy {}
9+
#[lang = "sized"]
10+
pub trait Sized {}
11+
12+
#[lang = "start"]
13+
#[target_feature(enable = "avx2")]
14+
//~^ ERROR `start` language item function is not allowed to have `#[target_feature]`
15+
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
16+
0
17+
}
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: `start` language item function is not allowed to have `#[target_feature]`
2+
--> $DIR/start_lang_item_with_target_feature.rs:13:1
3+
|
4+
LL | #[target_feature(enable = "avx2")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
LL |
7+
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
8+
| ------------------------------------------------------------------------------------------- `start` language item function is not allowed to have `#[target_feature]`
9+
10+
error: aborting due to previous error
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// compile-flags:-C panic=abort
2+
// only-x86_64
3+
4+
#![feature(target_feature_11)]
5+
#![no_std]
6+
#![no_main]
7+
8+
use core::panic::PanicInfo;
9+
10+
#[panic_handler]
11+
#[target_feature(enable = "avx2")]
12+
//~^ ERROR `panic_impl` language item function is not allowed to have `#[target_feature]`
13+
fn panic(info: &PanicInfo) -> ! {
14+
unimplemented!();
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: `panic_impl` language item function is not allowed to have `#[target_feature]`
2+
--> $DIR/panic-handler-with-target-feature.rs:11:1
3+
|
4+
LL | #[target_feature(enable = "avx2")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
LL |
7+
LL | fn panic(info: &PanicInfo) -> ! {
8+
| ------------------------------- `panic_impl` language item function is not allowed to have `#[target_feature]`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)