Skip to content

Commit d101971

Browse files
committed
weak lang items are not allowed to be #[track_caller]
1 parent b758149 commit d101971

7 files changed

+70
-7
lines changed

compiler/rustc_passes/messages.ftl

+11-2
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,18 @@ passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]
394394
395395
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
396396
397+
passes_lang_item_fn = {$name ->
398+
[panic_impl] `#[panic_handler]`
399+
*[other] `{$name}` language item
400+
} function
401+
397402
passes_lang_item_fn_with_target_feature =
398-
`{$name}` language item function is not allowed to have `#[target_feature]`
399-
.label = `{$name}` language item function is not allowed to have `#[target_feature]`
403+
{passes_lang_item_fn} is not allowed to have `#[target_feature]`
404+
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`
405+
406+
passes_lang_item_fn_with_track_caller =
407+
{passes_lang_item_fn} is not allowed to have `#[track_caller]`
408+
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`
400409
401410
passes_lang_item_on_incorrect_target =
402411
`{$name}` language item must be applied to a {$expected_target}

compiler/rustc_passes/src/check_attr.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use rustc_data_structures::fx::FxHashMap;
1111
use rustc_errors::StashKey;
1212
use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan};
1313
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
14-
use rustc_hir as hir;
1514
use rustc_hir::def_id::LocalModDefId;
1615
use rustc_hir::intravisit::{self, Visitor};
16+
use rustc_hir::{self as hir};
1717
use rustc_hir::{
1818
self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
1919
};
@@ -519,7 +519,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
519519
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
520520
false
521521
}
522-
Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true,
522+
Target::Fn => {
523+
// `#[track_caller]` is not valid on weak lang items because they are called via
524+
// `extern` declarations and `#[track_caller]` would alter their ABI.
525+
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
526+
&& let Some(item) = hir::LangItem::from_name(lang_item)
527+
&& item.is_weak()
528+
{
529+
let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
530+
531+
self.dcx().emit_err(errors::LangItemWithTrackCaller {
532+
attr_span,
533+
name: lang_item,
534+
sig_span: sig.span,
535+
});
536+
false
537+
} else {
538+
true
539+
}
540+
}
541+
Target::Method(..) | Target::ForeignFn | Target::Closure => true,
523542
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
524543
// `#[track_caller]` attribute with just a lint, because we previously
525544
// erroneously allowed it and some crates used it accidentally, to be compatible

compiler/rustc_passes/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,16 @@ pub struct MissingLangItem {
819819
pub name: Symbol,
820820
}
821821

822+
#[derive(Diagnostic)]
823+
#[diag(passes_lang_item_fn_with_track_caller)]
824+
pub struct LangItemWithTrackCaller {
825+
#[primary_span]
826+
pub attr_span: Span,
827+
pub name: Symbol,
828+
#[label]
829+
pub sig_span: Span,
830+
}
831+
822832
#[derive(Diagnostic)]
823833
#[diag(passes_lang_item_fn_with_target_feature)]
824834
pub struct LangItemWithTargetFeature {

tests/ui/panic-handler/panic-handler-with-target-feature.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use core::panic::PanicInfo;
99

1010
#[panic_handler]
1111
#[target_feature(enable = "avx2")]
12-
//~^ ERROR `panic_impl` language item function is not allowed to have `#[target_feature]`
12+
//~^ ERROR `#[panic_handler]` function is not allowed to have `#[target_feature]`
1313
fn panic(info: &PanicInfo) -> ! {
1414
unimplemented!();
1515
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error: `panic_impl` language item function is not allowed to have `#[target_feature]`
1+
error: `#[panic_handler]` function is not allowed to have `#[target_feature]`
22
--> $DIR/panic-handler-with-target-feature.rs:11:1
33
|
44
LL | #[target_feature(enable = "avx2")]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
LL |
77
LL | fn panic(info: &PanicInfo) -> ! {
8-
| ------------------------------- `panic_impl` language item function is not allowed to have `#[target_feature]`
8+
| ------------------------------- `#[panic_handler]` function is not allowed to have `#[target_feature]`
99

1010
error: aborting due to 1 previous error
1111

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ compile-flags:-C panic=abort
2+
//@ only-x86_64
3+
4+
#![no_std]
5+
#![no_main]
6+
7+
use core::panic::PanicInfo;
8+
9+
#[panic_handler]
10+
#[track_caller]
11+
//~^ ERROR `#[panic_handler]` function is not allowed to have `#[track_caller]`
12+
fn panic(info: &PanicInfo) -> ! {
13+
unimplemented!();
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: `#[panic_handler]` function is not allowed to have `#[track_caller]`
2+
--> $DIR/panic-handler-with-track-caller.rs:10:1
3+
|
4+
LL | #[track_caller]
5+
| ^^^^^^^^^^^^^^^
6+
LL |
7+
LL | fn panic(info: &PanicInfo) -> ! {
8+
| ------------------------------- `#[panic_handler]` function is not allowed to have `#[target_feature]`
9+
10+
error: aborting due to 1 previous error
11+

0 commit comments

Comments
 (0)