Skip to content

Commit 8814b92

Browse files
committed
Auto merge of rust-lang#126630 - GuillaumeGomez:rollup-hlwbpa2, r=GuillaumeGomez
Rollup of 5 pull requests Successful merges: - rust-lang#125988 (Migrate `run-make/used` to `rmake.rs`) - rust-lang#126500 (Migrate `error-found-staticlib-instead-crate`, `output-filename-conflicts-with-directory`, `output-filename-overwrites-input`, `native-link-modifier-verbatim-rustc` and `native-link-verbatim-linker` `run-make` tests to `rmake.rs` format) - rust-lang#126583 (interpret: better error when we ran out of memory) - rust-lang#126587 (coverage: Add debugging flag `-Zcoverage-options=no-mir-spans`) - rust-lang#126621 (More thorough status-quo tests for `#[coverage(..)]`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents af3d100 + 9f455d3 commit 8814b92

File tree

34 files changed

+992
-88
lines changed

34 files changed

+992
-88
lines changed

compiler/rustc_interface/src/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ fn test_unstable_options_tracking_hash() {
761761
})
762762
);
763763
tracked!(codegen_backend, Some("abc".to_string()));
764-
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc });
764+
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc, no_mir_spans: true });
765765
tracked!(crate_attr, vec!["abc".to_string()]);
766766
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
767767
tracked!(debug_info_for_profiling, true);

compiler/rustc_middle/src/mir/interpret/allocation.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl AllocBytes for Box<[u8]> {
5252
}
5353

5454
fn zeroed(size: Size, _align: Align) -> Option<Self> {
55-
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes_usize()).ok()?;
55+
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes().try_into().ok()?).ok()?;
5656
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
5757
let bytes = unsafe { bytes.assume_init() };
5858
Some(bytes)
@@ -323,7 +323,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
323323
/// first call this function and then call write_scalar to fill in the right data.
324324
pub fn uninit(size: Size, align: Align) -> Self {
325325
match Self::uninit_inner(size, align, || {
326-
panic!("Allocation::uninit called with panic_on_fail had allocation failure");
326+
panic!(
327+
"interpreter ran out of memory: cannot create allocation of {} bytes",
328+
size.bytes()
329+
);
327330
}) {
328331
Ok(x) => x,
329332
Err(x) => x,

compiler/rustc_mir_transform/src/coverage/mappings.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_index::bit_set::BitSet;
55
use rustc_index::IndexVec;
66
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind};
77
use rustc_middle::mir::{self, BasicBlock, StatementKind};
8+
use rustc_middle::ty::TyCtxt;
89
use rustc_span::Span;
910

1011
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
@@ -63,31 +64,35 @@ pub(super) struct ExtractedMappings {
6364

6465
/// Extracts coverage-relevant spans from MIR, and associates them with
6566
/// their corresponding BCBs.
66-
pub(super) fn extract_all_mapping_info_from_mir(
67-
mir_body: &mir::Body<'_>,
67+
pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
68+
tcx: TyCtxt<'tcx>,
69+
mir_body: &mir::Body<'tcx>,
6870
hir_info: &ExtractedHirInfo,
6971
basic_coverage_blocks: &CoverageGraph,
7072
) -> ExtractedMappings {
71-
if hir_info.is_async_fn {
73+
let mut code_mappings = vec![];
74+
let mut branch_pairs = vec![];
75+
let mut mcdc_bitmap_bytes = 0;
76+
let mut mcdc_branches = vec![];
77+
let mut mcdc_decisions = vec![];
78+
79+
if hir_info.is_async_fn || tcx.sess.coverage_no_mir_spans() {
7280
// An async function desugars into a function that returns a future,
7381
// with the user code wrapped in a closure. Any spans in the desugared
7482
// outer function will be unhelpful, so just keep the signature span
7583
// and ignore all of the spans in the MIR body.
76-
let mut mappings = ExtractedMappings::default();
84+
//
85+
// When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need
86+
// to give the same treatment to _all_ functions, because `llvm-cov`
87+
// seems to ignore functions that don't have any ordinary code spans.
7788
if let Some(span) = hir_info.fn_sig_span_extended {
78-
mappings.code_mappings.push(CodeMapping { span, bcb: START_BCB });
89+
code_mappings.push(CodeMapping { span, bcb: START_BCB });
7990
}
80-
return mappings;
91+
} else {
92+
// Extract coverage spans from MIR statements/terminators as normal.
93+
extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings);
8194
}
8295

83-
let mut code_mappings = vec![];
84-
let mut branch_pairs = vec![];
85-
let mut mcdc_bitmap_bytes = 0;
86-
let mut mcdc_branches = vec![];
87-
let mut mcdc_decisions = vec![];
88-
89-
extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings);
90-
9196
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
9297

9398
extract_mcdc_mappings(

compiler/rustc_mir_transform/src/coverage/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,12 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
7171

7272
////////////////////////////////////////////////////
7373
// Extract coverage spans and other mapping info from MIR.
74-
let extracted_mappings =
75-
mappings::extract_all_mapping_info_from_mir(mir_body, &hir_info, &basic_coverage_blocks);
74+
let extracted_mappings = mappings::extract_all_mapping_info_from_mir(
75+
tcx,
76+
mir_body,
77+
&hir_info,
78+
&basic_coverage_blocks,
79+
);
7680

7781
////////////////////////////////////////////////////
7882
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure

compiler/rustc_session/src/config.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,14 @@ pub enum InstrumentCoverage {
149149
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
150150
pub struct CoverageOptions {
151151
pub level: CoverageLevel,
152-
// Other boolean or enum-valued options might be added here.
152+
153+
/// `-Z coverage-options=no-mir-spans`: Don't extract block coverage spans
154+
/// from MIR statements/terminators, making it easier to inspect/debug
155+
/// branch and MC/DC coverage mappings.
156+
///
157+
/// For internal debugging only. If other code changes would make it hard
158+
/// to keep supporting this flag, remove it.
159+
pub no_mir_spans: bool,
153160
}
154161

155162
/// Controls whether branch coverage or MC/DC coverage is enabled.

compiler/rustc_session/src/options.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ mod desc {
395395
pub const parse_optimization_fuel: &str = "crate=integer";
396396
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
397397
pub const parse_instrument_coverage: &str = parse_bool;
398-
pub const parse_coverage_options: &str = "`block` | `branch` | `condition` | `mcdc`";
398+
pub const parse_coverage_options: &str =
399+
"`block` | `branch` | `condition` | `mcdc` | `no-mir-spans`";
399400
pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
400401
pub const parse_unpretty: &str = "`string` or `string=string`";
401402
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
@@ -963,6 +964,7 @@ mod parse {
963964
"branch" => slot.level = CoverageLevel::Branch,
964965
"condition" => slot.level = CoverageLevel::Condition,
965966
"mcdc" => slot.level = CoverageLevel::Mcdc,
967+
"no-mir-spans" => slot.no_mir_spans = true,
966968
_ => return false,
967969
}
968970
}

compiler/rustc_session/src/session.rs

+5
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ impl Session {
363363
&& self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc
364364
}
365365

366+
/// True if `-Zcoverage-options=no-mir-spans` was passed.
367+
pub fn coverage_no_mir_spans(&self) -> bool {
368+
self.opts.unstable_opts.coverage_options.no_mir_spans
369+
}
370+
366371
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
367372
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
368373
}

src/tools/tidy/src/allowed_run_make_makefiles.txt

-6
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ run-make/emit-shared-files/Makefile
3535
run-make/emit-stack-sizes/Makefile
3636
run-make/emit-to-stdout/Makefile
3737
run-make/env-dep-info/Makefile
38-
run-make/error-found-staticlib-instead-crate/Makefile
3938
run-make/error-writing-dependencies/Makefile
4039
run-make/export-executable-symbols/Makefile
4140
run-make/extern-diff-internal-name/Makefile
@@ -130,17 +129,13 @@ run-make/missing-crate-dependency/Makefile
130129
run-make/mixing-libs/Makefile
131130
run-make/msvc-opt-minsize/Makefile
132131
run-make/native-link-modifier-bundle/Makefile
133-
run-make/native-link-modifier-verbatim-linker/Makefile
134-
run-make/native-link-modifier-verbatim-rustc/Makefile
135132
run-make/native-link-modifier-whole-archive/Makefile
136133
run-make/no-alloc-shim/Makefile
137134
run-make/no-builtins-attribute/Makefile
138135
run-make/no-duplicate-libs/Makefile
139136
run-make/obey-crate-type-flag/Makefile
140137
run-make/optimization-remarks-dir-pgo/Makefile
141138
run-make/optimization-remarks-dir/Makefile
142-
run-make/output-filename-conflicts-with-directory/Makefile
143-
run-make/output-filename-overwrites-input/Makefile
144139
run-make/output-type-permutations/Makefile
145140
run-make/override-aliased-flags/Makefile
146141
run-make/overwrite-input/Makefile
@@ -225,7 +220,6 @@ run-make/unknown-mod-stdin/Makefile
225220
run-make/unstable-flag-required/Makefile
226221
run-make/use-suggestions-rust-2018/Makefile
227222
run-make/used-cdylib-macos/Makefile
228-
run-make/used/Makefile
229223
run-make/volatile-intrinsics/Makefile
230224
run-make/wasm-exceptions-nostd/Makefile
231225
run-make/wasm-override-linker/Makefile

tests/coverage/attr/nested.cov-map

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
Function name: <<<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method::MyInner as nested::MyTrait>::trait_method (unused)
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 39, 15, 02, 16]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 57, 21) to (start + 2, 22)
8+
9+
Function name: <<<nested::MyOuter>::outer_method::MyMiddle>::middle_method::MyInner>::inner_method (unused)
10+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 23, 15, 02, 16]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 0
14+
Number of file 0 mappings: 1
15+
- Code(Zero) at (prev + 35, 21) to (start + 2, 22)
16+
17+
Function name: <<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method (unused)
18+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 36, 0d, 08, 0e]
19+
Number of files: 1
20+
- file 0 => global file 1
21+
Number of expressions: 0
22+
Number of file 0 mappings: 1
23+
- Code(Zero) at (prev + 54, 13) to (start + 8, 14)
24+
25+
Function name: <<nested::MyOuter>::outer_method::MyMiddle>::middle_method (unused)
26+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 20, 0d, 08, 0e]
27+
Number of files: 1
28+
- file 0 => global file 1
29+
Number of expressions: 0
30+
Number of file 0 mappings: 1
31+
- Code(Zero) at (prev + 32, 13) to (start + 8, 14)
32+
33+
Function name: nested::closure_expr
34+
Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02]
35+
Number of files: 1
36+
- file 0 => global file 1
37+
Number of expressions: 0
38+
Number of file 0 mappings: 2
39+
- Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15)
40+
- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
41+
42+
Function name: nested::closure_expr::{closure#0}::{closure#0} (unused)
43+
Raw bytes (14): 0x[01, 01, 00, 02, 00, 47, 1a, 01, 17, 00, 04, 0d, 01, 0a]
44+
Number of files: 1
45+
- file 0 => global file 1
46+
Number of expressions: 0
47+
Number of file 0 mappings: 2
48+
- Code(Zero) at (prev + 71, 26) to (start + 1, 23)
49+
- Code(Zero) at (prev + 4, 13) to (start + 1, 10)
50+
51+
Function name: nested::closure_expr::{closure#0}::{closure#0}::{closure#0} (unused)
52+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 48, 1d, 02, 0e]
53+
Number of files: 1
54+
- file 0 => global file 1
55+
Number of expressions: 0
56+
Number of file 0 mappings: 1
57+
- Code(Zero) at (prev + 72, 29) to (start + 2, 14)
58+
59+
Function name: nested::closure_tail
60+
Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02]
61+
Number of files: 1
62+
- file 0 => global file 1
63+
Number of expressions: 0
64+
Number of file 0 mappings: 2
65+
- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15)
66+
- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
67+
68+
Function name: nested::closure_tail::{closure#0}::{closure#0} (unused)
69+
Raw bytes (14): 0x[01, 01, 00, 02, 00, 58, 14, 01, 1f, 00, 06, 15, 01, 12]
70+
Number of files: 1
71+
- file 0 => global file 1
72+
Number of expressions: 0
73+
Number of file 0 mappings: 2
74+
- Code(Zero) at (prev + 88, 20) to (start + 1, 31)
75+
- Code(Zero) at (prev + 6, 21) to (start + 1, 18)
76+
77+
Function name: nested::closure_tail::{closure#0}::{closure#0}::{closure#0} (unused)
78+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 5a, 1c, 02, 1a]
79+
Number of files: 1
80+
- file 0 => global file 1
81+
Number of expressions: 0
82+
Number of file 0 mappings: 1
83+
- Code(Zero) at (prev + 90, 28) to (start + 2, 26)
84+
85+
Function name: nested::outer_fn::middle_fn (unused)
86+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 05, 05, 06]
87+
Number of files: 1
88+
- file 0 => global file 1
89+
Number of expressions: 0
90+
Number of file 0 mappings: 1
91+
- Code(Zero) at (prev + 17, 5) to (start + 5, 6)
92+
93+
Function name: nested::outer_fn::middle_fn::inner_fn (unused)
94+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
95+
Number of files: 1
96+
- file 0 => global file 1
97+
Number of expressions: 0
98+
Number of file 0 mappings: 1
99+
- Code(Zero) at (prev + 18, 9) to (start + 2, 10)
100+

tests/coverage/attr/nested.coverage

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
LL| |#![feature(coverage_attribute, stmt_expr_attributes)]
2+
LL| |//@ edition: 2021
3+
LL| |
4+
LL| |// Demonstrates the interaction between #[coverage(off)] and various kinds of
5+
LL| |// nested function.
6+
LL| |
7+
LL| |// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
8+
LL| |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
9+
LL| |// its lines can still be marked with misleading execution counts from its enclosing
10+
LL| |// function.
11+
LL| |
12+
LL| |#[coverage(off)]
13+
LL| |fn do_stuff() {}
14+
LL| |
15+
LL| |#[coverage(off)]
16+
LL| |fn outer_fn() {
17+
LL| 0| fn middle_fn() {
18+
LL| 0| fn inner_fn() {
19+
LL| 0| do_stuff();
20+
LL| 0| }
21+
LL| 0| do_stuff();
22+
LL| 0| }
23+
LL| | do_stuff();
24+
LL| |}
25+
LL| |
26+
LL| |struct MyOuter;
27+
LL| |impl MyOuter {
28+
LL| | #[coverage(off)]
29+
LL| | fn outer_method(&self) {
30+
LL| | struct MyMiddle;
31+
LL| | impl MyMiddle {
32+
LL| 0| fn middle_method(&self) {
33+
LL| 0| struct MyInner;
34+
LL| 0| impl MyInner {
35+
LL| 0| fn inner_method(&self) {
36+
LL| 0| do_stuff();
37+
LL| 0| }
38+
LL| 0| }
39+
LL| 0| do_stuff();
40+
LL| 0| }
41+
LL| | }
42+
LL| | do_stuff();
43+
LL| | }
44+
LL| |}
45+
LL| |
46+
LL| |trait MyTrait {
47+
LL| | fn trait_method(&self);
48+
LL| |}
49+
LL| |impl MyTrait for MyOuter {
50+
LL| | #[coverage(off)]
51+
LL| | fn trait_method(&self) {
52+
LL| | struct MyMiddle;
53+
LL| | impl MyTrait for MyMiddle {
54+
LL| 0| fn trait_method(&self) {
55+
LL| 0| struct MyInner;
56+
LL| 0| impl MyTrait for MyInner {
57+
LL| 0| fn trait_method(&self) {
58+
LL| 0| do_stuff();
59+
LL| 0| }
60+
LL| 0| }
61+
LL| 0| do_stuff();
62+
LL| 0| }
63+
LL| | }
64+
LL| | do_stuff();
65+
LL| | }
66+
LL| |}
67+
LL| |
68+
LL| 1|fn closure_expr() {
69+
LL| 1| let _outer = #[coverage(off)]
70+
LL| | || {
71+
LL| 0| let _middle = || {
72+
LL| 0| let _inner = || {
73+
LL| 0| do_stuff();
74+
LL| 0| };
75+
LL| 0| do_stuff();
76+
LL| 0| };
77+
LL| | do_stuff();
78+
LL| | };
79+
LL| 1| do_stuff();
80+
LL| 1|}
81+
LL| |
82+
LL| |// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
83+
LL| 1|fn closure_tail() {
84+
LL| 1| let _outer = {
85+
LL| | #[coverage(off)]
86+
LL| | || {
87+
LL| | let _middle = {
88+
LL| 0| || {
89+
LL| 0| let _inner = {
90+
LL| 0| || {
91+
LL| 0| do_stuff();
92+
LL| 0| }
93+
LL| | };
94+
LL| 0| do_stuff();
95+
LL| 0| }
96+
LL| | };
97+
LL| | do_stuff();
98+
LL| | }
99+
LL| | };
100+
LL| 1| do_stuff();
101+
LL| 1|}
102+
LL| |
103+
LL| |#[coverage(off)]
104+
LL| |fn main() {
105+
LL| | outer_fn();
106+
LL| | MyOuter.outer_method();
107+
LL| | MyOuter.trait_method();
108+
LL| | closure_expr();
109+
LL| | closure_tail();
110+
LL| |}
111+

0 commit comments

Comments
 (0)