Skip to content

Commit 457fda1

Browse files
committed
coverage: Detach #[coverage(..)] from codegen attribute handling
1 parent fda509e commit 457fda1

File tree

4 files changed

+35
-22
lines changed

4 files changed

+35
-22
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

-17
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
124124
.emit();
125125
}
126126
}
127-
sym::coverage => {
128-
let inner = attr.meta_item_list();
129-
match inner.as_deref() {
130-
Some([item]) if item.has_name(sym::off) => {
131-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
132-
}
133-
Some([item]) if item.has_name(sym::on) => {
134-
// Allow #[coverage(on)] for being explicit, maybe also in future to enable
135-
// coverage on a smaller scope within an excluded larger scope.
136-
}
137-
Some(_) | None => {
138-
tcx.dcx()
139-
.span_delayed_bug(attr.span, "unexpected value of coverage attribute");
140-
}
141-
}
142-
}
143127
sym::rustc_std_internal_symbol => {
144128
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
145129
}
@@ -584,7 +568,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
584568
}
585569

586570
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
587-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
588571
codegen_fn_attrs.inline = InlineAttr::Never;
589572
}
590573

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ bitflags::bitflags! {
8787
/// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
8888
/// function as an entry function from Non-Secure code.
8989
const CMSE_NONSECURE_ENTRY = 1 << 13;
90-
/// `#[coverage(off)]`: indicates that the function should be ignored by
91-
/// the MIR `InstrumentCoverage` pass and not added to the coverage map
92-
/// during codegen.
93-
const NO_COVERAGE = 1 << 14;
90+
// (Bit 14 was used for `#[coverage(off)]`, but is now unused.)
9491
/// `#[used(linker)]`:
9592
/// indicates that neither LLVM nor the linker will eliminate this function.
9693
const USED_LINKER = 1 << 15;

compiler/rustc_middle/src/query/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,14 @@ rustc_queries! {
572572
separate_provide_extern
573573
}
574574

575+
/// Checks for `#[coverage(off)]` or `#[coverage(on)]`.
576+
///
577+
/// Returns `false` if `#[coverage(off)]` was found, or `true` if
578+
/// either `#[coverage(on)]` or no coverage attribute was found.
579+
query coverage_attr_on(key: LocalDefId) -> bool {
580+
desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) }
581+
}
582+
575583
/// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
576584
/// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
577585
/// have had a chance to potentially remove some of them.

compiler/rustc_mir_transform/src/coverage/query.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ use rustc_middle::query::TyCtxtAt;
66
use rustc_middle::ty::{self, TyCtxt};
77
use rustc_middle::util::Providers;
88
use rustc_span::def_id::LocalDefId;
9+
use rustc_span::sym;
910

1011
/// Registers query/hook implementations related to coverage.
1112
pub(crate) fn provide(providers: &mut Providers) {
1213
providers.hooks.is_eligible_for_coverage =
1314
|TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id);
15+
providers.queries.coverage_attr_on = coverage_attr_on;
1416
providers.queries.coverage_ids_info = coverage_ids_info;
1517
}
1618

@@ -38,14 +40,37 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
3840
return false;
3941
}
4042

41-
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
43+
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) {
44+
trace!("InstrumentCoverage skipped for {def_id:?} (`#[naked]`)");
45+
return false;
46+
}
47+
48+
if !tcx.coverage_attr_on(def_id) {
4249
trace!("InstrumentCoverage skipped for {def_id:?} (`#[coverage(off)]`)");
4350
return false;
4451
}
4552

4653
true
4754
}
4855

56+
/// Query implementation for `coverage_attr_on`.
57+
fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
58+
if let Some(attr) = tcx.get_attr(def_id, sym::coverage) {
59+
match attr.meta_item_list().as_deref() {
60+
Some([item]) if item.has_name(sym::off) => return false,
61+
Some([item]) if item.has_name(sym::on) => return true,
62+
Some(_) | None => {
63+
// Other possibilities should have been rejected by `rustc_parse::validate_attr`.
64+
tcx.dcx().span_bug(attr.span, "unexpected value of coverage attribute");
65+
}
66+
}
67+
}
68+
69+
// We didn't see an explicit coverage attribute, so
70+
// allow coverage instrumentation by default.
71+
true
72+
}
73+
4974
/// Query implementation for `coverage_ids_info`.
5075
fn coverage_ids_info<'tcx>(
5176
tcx: TyCtxt<'tcx>,

0 commit comments

Comments
 (0)