Validate that naked functions are never inlined

Reject all uses of the inline attribute on naked functions.

rust-lang/rfcs#2774
rust-lang/rfcs#2972
This commit is contained in:
Nathaniel McCallum 2021-08-02 15:03:43 -04:00
parent 6be8a06bcf
commit 157e0a0e8f
4 changed files with 112 additions and 2 deletions

View file

@ -2720,6 +2720,9 @@
/// The asm block must not contain any operands other than `const` and
/// `sym`. Additionally, naked function should specify a non-Rust ABI.
///
/// Naked functions cannot be inlined. All forms of the `inline` attribute
/// are prohibited.
///
/// While other definitions of naked functions were previously accepted,
/// they are unsupported and might not work reliably. This is a
/// [future-incompatible] lint that will transition into hard error in

View file

@ -1,6 +1,6 @@
//! Checks validity of naked functions.
use rustc_ast::InlineAsmOptions;
use rustc_ast::{Attribute, InlineAsmOptions};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor};
@ -70,10 +70,20 @@ fn visit_fn(
check_no_patterns(self.tcx, body.params);
check_no_parameters_use(self.tcx, body);
check_asm(self.tcx, hir_id, body, span);
check_inline(self.tcx, hir_id, attrs);
}
}
}
/// Check that the function isn't inlined.
fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) {
for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) {
tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| {
lint.build("naked functions cannot be inlined").emit();
});
}
}
/// Checks that function uses non-Rust ABI.
fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) {
if abi == Abi::Rust {

View file

@ -167,3 +167,46 @@ pub extern "C" fn valid_b() {
pub unsafe extern "C" fn valid_att_syntax() {
asm!("", options(noreturn, att_syntax));
}
#[naked]
pub unsafe extern "C" fn inline_none() {
asm!("", options(noreturn));
}
#[naked]
#[inline]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn));
}
#[naked]
#[inline(always)]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn));
}
#[naked]
#[inline(never)]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn));
}
#[naked]
#[inline]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
#[inline(always)]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
#[inline(never)]
//~^ WARN naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_all() {
asm!("", options(noreturn));
}

View file

@ -296,5 +296,59 @@ LL | pub unsafe extern "Rust" fn rust_abi() {
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
error: aborting due to 8 previous errors; 19 warnings emitted
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:177:1
|
LL | #[inline]
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:185:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:193:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:201:1
|
LL | #[inline]
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:204:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:207:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
error: aborting due to 8 previous errors; 25 warnings emitted