diff options
Diffstat (limited to 'compiler/rustc_passes')
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/naked_functions.rs | 48 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/stability.rs | 18 |
7 files changed, 71 insertions, 46 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index e7f208d5ad5..5369f54afb9 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -484,6 +484,9 @@ passes_must_not_suspend = passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target} +passes_naked_asm_outside_naked_fn = + the `naked_asm!` macro can only be used in functions marked with `#[naked]` + passes_naked_functions_asm_block = naked functions must contain a single asm block .label_multiple_asm = multiple asm blocks are unsupported in naked functions diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e41f89a3c9d..ee892c17376 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1905,10 +1905,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { || (int_reprs == 1 && is_c && item.is_some_and(|item| { - if let ItemLike::Item(item) = item { - return is_c_like_enum(item); - } - return false; + if let ItemLike::Item(item) = item { is_c_like_enum(item) } else { false } })) { self.tcx.emit_node_span_lint( @@ -2172,17 +2169,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr.span, errors::MacroExport::TooManyItems, ); - } else { - if meta_item_list[0].name_or_empty() != sym::local_inner_macros { - self.tcx.emit_node_span_lint( - INVALID_MACRO_EXPORT_ARGUMENTS, - hir_id, - meta_item_list[0].span(), - errors::MacroExport::UnknownItem { - name: meta_item_list[0].name_or_empty(), - }, - ); - } + } else if meta_item_list[0].name_or_empty() != sym::local_inner_macros { + self.tcx.emit_node_span_lint( + INVALID_MACRO_EXPORT_ARGUMENTS, + hir_id, + meta_item_list[0].span(), + errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() }, + ); } } else { // special case when `#[macro_export]` is applied to a macro 2.0 diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7f1e906ffd7..ef534c645a4 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -394,7 +394,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } - return false; + false } fn visit_node(&mut self, node: Node<'tcx>) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f5d982e1a5c..a985ecb019a 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1222,6 +1222,13 @@ pub(crate) struct NakedFunctionIncompatibleAttribute { } #[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 { #[primary_span] diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index db3eaea68b5..959b7ad147b 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1500,15 +1500,13 @@ impl<'tcx> Liveness<'_, 'tcx> { ); } } - } else { - if let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_node_span_lint( - lint::builtin::UNUSED_VARIABLES, - var_hir_id, - vec![span], - errors::UnusedVarMaybeCaptureRef { name }, - ); - } + } else if let Some(name) = self.should_warn(var) { + self.ir.tcx.emit_node_span_lint( + lint::builtin::UNUSED_VARIABLES, + var_hir_id, + vec![span], + errors::UnusedVarMaybeCaptureRef { name }, + ); } } } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index b72ce239c4a..ab6385dd7d7 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -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); + } +} diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index ba4c300ea61..e2c9067c0b9 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -174,16 +174,14 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI, // check if the function/method is const or the parent impl block is const - if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) { - if fn_sig.header.abi != Abi::RustIntrinsic && !fn_sig.header.is_const() { - if !self.in_trait_impl - || (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id())) - { - self.tcx - .dcx() - .emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span, const_span }); - } - } + if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) + && fn_sig.header.abi != Abi::RustIntrinsic + && !fn_sig.header.is_const() + && (!self.in_trait_impl || !self.tcx.is_const_fn_raw(def_id.to_def_id())) + { + self.tcx + .dcx() + .emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span, const_span }); } // `impl const Trait for Type` items forward their const stability to their |
