From c955add18c88427eaf09ec2086e3f8a9ccd30021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 2 Dec 2022 00:00:00 +0000 Subject: [PATCH 1/2] Disable coverage instrumentation for naked functions --- compiler/rustc_hir_analysis/src/collect.rs | 4 ++++ src/test/codegen/naked-nocoverage.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/test/codegen/naked-nocoverage.rs diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index d623e72613944..3b602a6561fd1 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -2073,6 +2073,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { } } + if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE; + } + // Weak lang items have the same semantics as "std internal" symbols in the // sense that they're preserved through all our LTO passes and only // strippable by the linker. diff --git a/src/test/codegen/naked-nocoverage.rs b/src/test/codegen/naked-nocoverage.rs new file mode 100644 index 0000000000000..91a6260bf2aa2 --- /dev/null +++ b/src/test/codegen/naked-nocoverage.rs @@ -0,0 +1,19 @@ +// Checks that naked functions are not instrumented by -Cinstrument-coverage. +// Regression test for issue #105170. +// +// needs-asm-support +// needs-profiler-support +// compile-flags: -Cinstrument-coverage +#![crate_type = "lib"] +#![feature(naked_functions)] +use std::arch::asm; + +#[naked] +#[no_mangle] +pub unsafe extern "C" fn f() { + // CHECK: define void @f() + // CHECK-NEXT: start: + // CHECK-NEXT: call void asm + // CHECK-NEXT: unreachable + asm!("", options(noreturn)); +} From b740cdcf43f6d686f52d3f85100a0ff5ff0c043d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 2 Dec 2022 00:00:00 +0000 Subject: [PATCH 2/2] Mark naked functions as never inline in codegen_fn_attrs Use code generation attributes to ensure that naked functions are never inline, replacing separate checks in MIR inliner and LLVM code generation. --- compiler/rustc_codegen_llvm/src/attributes.rs | 13 ++++++------- compiler/rustc_hir_analysis/src/collect.rs | 1 + compiler/rustc_mir_transform/src/inline.rs | 4 ---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a8b47633519aa..f3bdacf608555 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -258,13 +258,12 @@ pub fn from_fn_attrs<'ll, 'tcx>( OptimizeAttr::Speed => {} } - let inline = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { - InlineAttr::Never - } else if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) { - InlineAttr::Hint - } else { - codegen_fn_attrs.inline - }; + let inline = + if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) { + InlineAttr::Hint + } else { + codegen_fn_attrs.inline + }; to_add.extend(inline_attr(cx, inline)); // The `uwtable` attribute according to LLVM is: diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 3b602a6561fd1..b7084303aafb1 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -2075,6 +2075,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE; + codegen_fn_attrs.inline = InlineAttr::Never; } // Weak lang items have the same semantics as "std internal" symbols in the diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9174f04887e42..bf670c5c26a77 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -363,10 +363,6 @@ impl<'tcx> Inliner<'tcx> { return Err("C variadic"); } - if callee_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { - return Err("naked"); - } - if callee_attrs.flags.contains(CodegenFnAttrFlags::COLD) { return Err("cold"); }