weak lang items are not allowed to be #[track_caller]

This commit is contained in:
Ralf Jung 2024-04-17 12:17:29 +02:00
parent b7581490aa
commit d101971ab1
7 changed files with 70 additions and 7 deletions

View File

@ -394,9 +394,18 @@ passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
passes_lang_item_fn = {$name ->
[panic_impl] `#[panic_handler]`
*[other] `{$name}` language item
} function
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_fn} is not allowed to have `#[target_feature]`
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`
passes_lang_item_fn_with_track_caller =
{passes_lang_item_fn} is not allowed to have `#[track_caller]`
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`
passes_lang_item_on_incorrect_target =
`{$name}` language item must be applied to a {$expected_target}

View File

@ -11,9 +11,9 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::StashKey;
use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan};
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
use rustc_hir as hir;
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self as hir};
use rustc_hir::{
self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
};
@ -519,7 +519,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
false
}
Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true,
Target::Fn => {
// `#[track_caller]` is not valid on weak lang items because they are called via
// `extern` declarations and `#[track_caller]` would alter their ABI.
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
&& let Some(item) = hir::LangItem::from_name(lang_item)
&& item.is_weak()
{
let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
self.dcx().emit_err(errors::LangItemWithTrackCaller {
attr_span,
name: lang_item,
sig_span: sig.span,
});
false
} else {
true
}
}
Target::Method(..) | Target::ForeignFn | Target::Closure => true,
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[track_caller]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to be compatible

View File

@ -819,6 +819,16 @@ pub struct MissingLangItem {
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(passes_lang_item_fn_with_track_caller)]
pub struct LangItemWithTrackCaller {
#[primary_span]
pub attr_span: Span,
pub name: Symbol,
#[label]
pub sig_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_lang_item_fn_with_target_feature)]
pub struct LangItemWithTargetFeature {

View File

@ -9,7 +9,7 @@ use core::panic::PanicInfo;
#[panic_handler]
#[target_feature(enable = "avx2")]
//~^ ERROR `panic_impl` language item function is not allowed to have `#[target_feature]`
//~^ ERROR `#[panic_handler]` function is not allowed to have `#[target_feature]`
fn panic(info: &PanicInfo) -> ! {
unimplemented!();
}

View File

@ -1,11 +1,11 @@
error: `panic_impl` language item function is not allowed to have `#[target_feature]`
error: `#[panic_handler]` 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]`
| ------------------------------- `#[panic_handler]` function is not allowed to have `#[target_feature]`
error: aborting due to 1 previous error

View File

@ -0,0 +1,14 @@
//@ compile-flags:-C panic=abort
//@ only-x86_64
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
#[track_caller]
//~^ ERROR `#[panic_handler]` function is not allowed to have `#[track_caller]`
fn panic(info: &PanicInfo) -> ! {
unimplemented!();
}

View File

@ -0,0 +1,11 @@
error: `#[panic_handler]` function is not allowed to have `#[track_caller]`
--> $DIR/panic-handler-with-track-caller.rs:10:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
LL |
LL | fn panic(info: &PanicInfo) -> ! {
| ------------------------------- `#[panic_handler]` function is not allowed to have `#[target_feature]`
error: aborting due to 1 previous error