disallow naked_asm!
outside of #[naked]
functions
This commit is contained in:
parent
26b2b8d162
commit
6ca5ec7b4e
11 changed files with 132 additions and 16 deletions
|
@ -1221,6 +1221,13 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
|
|||
pub attr: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_naked_asm_outside_naked_fn)]
|
||||
pub(crate) struct NakedAsmOutsideNakedFn {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_attr_only_in_functions)]
|
||||
pub(crate) struct AttrOnlyInFunctions {
|
||||
|
|
|
@ -6,6 +6,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{ExprKind, HirIdSet, InlineAsmOperand, StmtKind};
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
|
||||
|
@ -14,8 +15,9 @@ use rustc_span::Span;
|
|||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::errors::{
|
||||
NakedFunctionsAsmBlock, NakedFunctionsAsmOptions, NakedFunctionsMustUseNoreturn,
|
||||
NakedFunctionsOperands, NoPatterns, ParamsNotAllowed, UndefinedNakedFunctionAbi,
|
||||
NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
|
||||
NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
|
||||
UndefinedNakedFunctionAbi,
|
||||
};
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
|
@ -29,11 +31,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let naked = tcx.has_attr(def_id, sym::naked);
|
||||
if !naked {
|
||||
continue;
|
||||
}
|
||||
|
||||
let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) {
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
|
@ -48,10 +45,17 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
|
|||
};
|
||||
|
||||
let body = tcx.hir().body(body_id);
|
||||
check_abi(tcx, def_id, fn_header.abi);
|
||||
check_no_patterns(tcx, body.params);
|
||||
check_no_parameters_use(tcx, body);
|
||||
check_asm(tcx, def_id, body);
|
||||
|
||||
if tcx.has_attr(def_id, sym::naked) {
|
||||
check_abi(tcx, def_id, fn_header.abi);
|
||||
check_no_patterns(tcx, body.params);
|
||||
check_no_parameters_use(tcx, body);
|
||||
check_asm(tcx, def_id, body);
|
||||
} else {
|
||||
// `naked_asm!` is not allowed outside of functions marked as `#[naked]`
|
||||
let mut visitor = CheckNakedAsmInNakedFn { tcx };
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,3 +280,25 @@ impl<'tcx> Visitor<'tcx> for CheckInlineAssembly<'tcx> {
|
|||
self.check_expr(expr, expr.span);
|
||||
}
|
||||
}
|
||||
|
||||
struct CheckNakedAsmInNakedFn<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for CheckNakedAsmInNakedFn<'tcx> {
|
||||
type NestedFilter = OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let ExprKind::InlineAsm(inline_asm) = expr.kind {
|
||||
if let rustc_ast::AsmMacro::NakedAsm = inline_asm.asm_macro {
|
||||
self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span: expr.span });
|
||||
}
|
||||
}
|
||||
|
||||
hir::intravisit::walk_expr(self, expr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue