Skip to content

Commit aace2df

Browse files
committed
Auto merge of rust-lang#115910 - eduardosm:lang-fns-target-features, r=cjgillot
Prevent using `#[target_feature]` on lang item functions Fixes rust-lang#109411 and also prevents from using `#[target_feature]` on other `fn` lang items to mitigate the concerns from rust-lang#109411 (comment).
2 parents b757318 + 9102816 commit aace2df

7 files changed

+99
-3
lines changed

Diff for: compiler/rustc_passes/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ passes_invalid_stability =
407407
.label = invalid stability version
408408
.item = the stability attribute annotates this item
409409
410+
passes_lang_item_fn_with_target_feature =
411+
`{$name}` language item function is not allowed to have `#[target_feature]`
412+
.label = `{$name}` language item function is not allowed to have `#[target_feature]`
413+
410414
passes_lang_item_on_incorrect_target =
411415
`{$name}` language item must be applied to a {$expected_target}
412416
.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
@@ -118,7 +118,7 @@ impl CheckAttrVisitor<'_> {
118118
sym::coverage => self.check_coverage(hir_id, attr, span, target),
119119
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
120120
sym::marker => self.check_marker(hir_id, attr, span, target),
121-
sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
121+
sym::target_feature => self.check_target_feature(hir_id, attr, span, target, attrs),
122122
sym::thread_local => self.check_thread_local(attr, span, target),
123123
sym::track_caller => {
124124
self.check_track_caller(hir_id, attr.span, attrs, span, target)
@@ -591,10 +591,36 @@ impl CheckAttrVisitor<'_> {
591591
attr: &Attribute,
592592
span: Span,
593593
target: Target,
594+
attrs: &[Attribute],
594595
) -> bool {
595596
match target {
596-
Target::Fn
597-
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
597+
Target::Fn => {
598+
// `#[target_feature]` is not allowed in language items.
599+
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
600+
// Calling functions with `#[target_feature]` is
601+
// not unsafe on WASM, see #84988
602+
&& !self.tcx.sess.target.is_like_wasm
603+
&& !self.tcx.sess.opts.actually_rustdoc
604+
{
605+
let hir::Node::Item(item) = self.tcx.hir().get(hir_id) else {
606+
unreachable!();
607+
};
608+
let hir::ItemKind::Fn(sig, _, _) = item.kind else {
609+
// target is `Fn`
610+
unreachable!();
611+
};
612+
613+
self.tcx.sess.emit_err(errors::LangItemWithTargetFeature {
614+
attr_span: attr.span,
615+
name: lang_item,
616+
sig_span: sig.span,
617+
});
618+
false
619+
} else {
620+
true
621+
}
622+
}
623+
Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
598624
// FIXME: #[target_feature] was previously erroneously allowed on statements and some
599625
// crates used this, so only emit a warning.
600626
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)