Skip to content

Commit

Permalink
Rollup merge of rust-lang#87652 - npmccallum:naked_inline, r=Amanieu
Browse files Browse the repository at this point in the history
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

cc `@joshtriplett` `@tmiasko` `@Amanieu`
  • Loading branch information
JohnTitor authored Aug 3, 2021
2 parents f69daa2 + 157e0a0 commit a14b283
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2720,6 +2720,9 @@ declare_lint! {
/// 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
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_passes/src/naked_functions.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -70,10 +70,20 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
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 {
Expand Down
43 changes: 43 additions & 0 deletions src/test/ui/asm/naked-functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,46 @@ pub unsafe extern "C" fn valid_c() {
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));
}
56 changes: 55 additions & 1 deletion src/test/ui/asm/naked-functions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit a14b283

Please sign in to comment.