Skip to content

Commit 9b31273

Browse files
Don't perform invalid checks in codegen_attrs
Some attributes are only valid on function items. When checking these attributes, codegen_attrs previously sometimes called `fn_sig` on the item they were attached to without first ensuring that the item was a function. This led to an ICE (#105594), since `fn_sig` can only be called on functions. After this change, we skip calling `fn_sig` if the item the attribute is attached to must be a function but invalidly isn't, because `check_attr` will reject such cases without codegen_attrs's intervention.
1 parent 918d0ac commit 9b31273

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_ast::{ast, MetaItemKind, NestedMetaItem};
22
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
33
use rustc_errors::struct_span_err;
44
use rustc_hir as hir;
5+
use rustc_hir::def::DefKind;
56
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
67
use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem};
78
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -60,6 +61,21 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
6061

6162
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
6263

64+
// In some cases, attribute are only valid on functions, but it's the `check_attr`
65+
// pass that check that they aren't used anywhere else, rather this module.
66+
// In these cases, we bail from performing further checks that are only meaningful for
67+
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
68+
// report a delayed bug, just in case `check_attr` isn't doing its job.
69+
let validate_fn_only_attr = |attr_sp| -> bool {
70+
let def_kind = tcx.def_kind(did);
71+
if let DefKind::Fn | DefKind::AssocFn = def_kind {
72+
true
73+
} else {
74+
tcx.sess.delay_span_bug(attr_sp, "this attribute can only be applied to functions");
75+
false
76+
}
77+
};
78+
6379
let mut inline_span = None;
6480
let mut link_ordinal_span = None;
6581
let mut no_sanitize_span = None;
@@ -197,7 +213,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
197213
}
198214
}
199215
} else if attr.has_name(sym::cmse_nonsecure_entry) {
200-
if !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. }) {
216+
if validate_fn_only_attr(attr.span)
217+
&& !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. })
218+
{
201219
struct_span_err!(
202220
tcx.sess,
203221
attr.span,
@@ -214,7 +232,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
214232
} else if attr.has_name(sym::thread_local) {
215233
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
216234
} else if attr.has_name(sym::track_caller) {
217-
if !tcx.is_closure(did.to_def_id()) && tcx.fn_sig(did).abi() != abi::Abi::Rust {
235+
if !tcx.is_closure(did.to_def_id())
236+
&& validate_fn_only_attr(attr.span)
237+
&& tcx.fn_sig(did).abi() != abi::Abi::Rust
238+
{
218239
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
219240
.emit();
220241
}

0 commit comments

Comments
 (0)