about summary refs log tree commit diff
path: root/compiler/rustc_passes
diff options
context:
space:
mode:
authorNathaniel McCallum <nathaniel@congru.us>2021-08-02 15:03:43 -0400
committerNathaniel McCallum <nathaniel@congru.us>2021-08-02 21:49:51 -0400
commit157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86 (patch)
tree7d397100e11380c2f4d0b2c2877c4e06e7ed160e /compiler/rustc_passes
parent6be8a06bcf2e7c45db2f9e3dd3c9c0e282562a93 (diff)
downloadrust-157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86.tar.gz
rust-157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86.zip
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
Diffstat (limited to 'compiler/rustc_passes')
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs12
1 files changed, 11 insertions, 1 deletions
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 89bc2e1a987..e05ec205b65 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -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 @@ 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 {