Skip to content

Commit

Permalink
Auto merge of #126630 - GuillaumeGomez:rollup-hlwbpa2, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #125988 (Migrate `run-make/used` to `rmake.rs`)
 - #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)
 - #126583 (interpret: better error when we ran out of memory)
 - #126587 (coverage: Add debugging flag `-Zcoverage-options=no-mir-spans`)
 - #126621 (More thorough status-quo tests for `#[coverage(..)]`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 18, 2024
2 parents af3d100 + 9f455d3 commit 8814b92
Show file tree
Hide file tree
Showing 34 changed files with 992 additions and 88 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ fn test_unstable_options_tracking_hash() {
})
);
tracked!(codegen_backend, Some("abc".to_string()));
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc });
tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc, no_mir_spans: true });
tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true);
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl AllocBytes for Box<[u8]> {
}

fn zeroed(size: Size, _align: Align) -> Option<Self> {
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes_usize()).ok()?;
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes().try_into().ok()?).ok()?;
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
let bytes = unsafe { bytes.assume_init() };
Some(bytes)
Expand Down Expand Up @@ -323,7 +323,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
/// first call this function and then call write_scalar to fill in the right data.
pub fn uninit(size: Size, align: Align) -> Self {
match Self::uninit_inner(size, align, || {
panic!("Allocation::uninit called with panic_on_fail had allocation failure");
panic!(
"interpreter ran out of memory: cannot create allocation of {} bytes",
size.bytes()
);
}) {
Ok(x) => x,
Err(x) => x,
Expand Down
33 changes: 19 additions & 14 deletions compiler/rustc_mir_transform/src/coverage/mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind};
use rustc_middle::mir::{self, BasicBlock, StatementKind};
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;

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

/// Extracts coverage-relevant spans from MIR, and associates them with
/// their corresponding BCBs.
pub(super) fn extract_all_mapping_info_from_mir(
mir_body: &mir::Body<'_>,
pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
hir_info: &ExtractedHirInfo,
basic_coverage_blocks: &CoverageGraph,
) -> ExtractedMappings {
if hir_info.is_async_fn {
let mut code_mappings = vec![];
let mut branch_pairs = vec![];
let mut mcdc_bitmap_bytes = 0;
let mut mcdc_branches = vec![];
let mut mcdc_decisions = vec![];

if hir_info.is_async_fn || tcx.sess.coverage_no_mir_spans() {
// An async function desugars into a function that returns a future,
// with the user code wrapped in a closure. Any spans in the desugared
// outer function will be unhelpful, so just keep the signature span
// and ignore all of the spans in the MIR body.
let mut mappings = ExtractedMappings::default();
//
// When debugging flag `-Zcoverage-options=no-mir-spans` is set, we need
// to give the same treatment to _all_ functions, because `llvm-cov`
// seems to ignore functions that don't have any ordinary code spans.
if let Some(span) = hir_info.fn_sig_span_extended {
mappings.code_mappings.push(CodeMapping { span, bcb: START_BCB });
code_mappings.push(CodeMapping { span, bcb: START_BCB });
}
return mappings;
} else {
// Extract coverage spans from MIR statements/terminators as normal.
extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings);
}

let mut code_mappings = vec![];
let mut branch_pairs = vec![];
let mut mcdc_bitmap_bytes = 0;
let mut mcdc_branches = vec![];
let mut mcdc_decisions = vec![];

extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings);

branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));

extract_mcdc_mappings(
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:

////////////////////////////////////////////////////
// Extract coverage spans and other mapping info from MIR.
let extracted_mappings =
mappings::extract_all_mapping_info_from_mir(mir_body, &hir_info, &basic_coverage_blocks);
let extracted_mappings = mappings::extract_all_mapping_info_from_mir(
tcx,
mir_body,
&hir_info,
&basic_coverage_blocks,
);

////////////////////////////////////////////////////
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,14 @@ pub enum InstrumentCoverage {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct CoverageOptions {
pub level: CoverageLevel,
// Other boolean or enum-valued options might be added here.

/// `-Z coverage-options=no-mir-spans`: Don't extract block coverage spans
/// from MIR statements/terminators, making it easier to inspect/debug
/// branch and MC/DC coverage mappings.
///
/// For internal debugging only. If other code changes would make it hard
/// to keep supporting this flag, remove it.
pub no_mir_spans: bool,
}

/// Controls whether branch coverage or MC/DC coverage is enabled.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,8 @@ mod desc {
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
pub const parse_instrument_coverage: &str = parse_bool;
pub const parse_coverage_options: &str = "`block` | `branch` | `condition` | `mcdc`";
pub const parse_coverage_options: &str =
"`block` | `branch` | `condition` | `mcdc` | `no-mir-spans`";
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`";
pub const parse_unpretty: &str = "`string` or `string=string`";
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
Expand Down Expand Up @@ -963,6 +964,7 @@ mod parse {
"branch" => slot.level = CoverageLevel::Branch,
"condition" => slot.level = CoverageLevel::Condition,
"mcdc" => slot.level = CoverageLevel::Mcdc,
"no-mir-spans" => slot.no_mir_spans = true,
_ => return false,
}
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ impl Session {
&& self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc
}

/// True if `-Zcoverage-options=no-mir-spans` was passed.
pub fn coverage_no_mir_spans(&self) -> bool {
self.opts.unstable_opts.coverage_options.no_mir_spans
}

pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}
Expand Down
6 changes: 0 additions & 6 deletions src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ run-make/emit-shared-files/Makefile
run-make/emit-stack-sizes/Makefile
run-make/emit-to-stdout/Makefile
run-make/env-dep-info/Makefile
run-make/error-found-staticlib-instead-crate/Makefile
run-make/error-writing-dependencies/Makefile
run-make/export-executable-symbols/Makefile
run-make/extern-diff-internal-name/Makefile
Expand Down Expand Up @@ -130,17 +129,13 @@ run-make/missing-crate-dependency/Makefile
run-make/mixing-libs/Makefile
run-make/msvc-opt-minsize/Makefile
run-make/native-link-modifier-bundle/Makefile
run-make/native-link-modifier-verbatim-linker/Makefile
run-make/native-link-modifier-verbatim-rustc/Makefile
run-make/native-link-modifier-whole-archive/Makefile
run-make/no-alloc-shim/Makefile
run-make/no-builtins-attribute/Makefile
run-make/no-duplicate-libs/Makefile
run-make/obey-crate-type-flag/Makefile
run-make/optimization-remarks-dir-pgo/Makefile
run-make/optimization-remarks-dir/Makefile
run-make/output-filename-conflicts-with-directory/Makefile
run-make/output-filename-overwrites-input/Makefile
run-make/output-type-permutations/Makefile
run-make/override-aliased-flags/Makefile
run-make/overwrite-input/Makefile
Expand Down Expand Up @@ -225,7 +220,6 @@ run-make/unknown-mod-stdin/Makefile
run-make/unstable-flag-required/Makefile
run-make/use-suggestions-rust-2018/Makefile
run-make/used-cdylib-macos/Makefile
run-make/used/Makefile
run-make/volatile-intrinsics/Makefile
run-make/wasm-exceptions-nostd/Makefile
run-make/wasm-override-linker/Makefile
Expand Down
100 changes: 100 additions & 0 deletions tests/coverage/attr/nested.cov-map
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
Function name: <<<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method::MyInner as nested::MyTrait>::trait_method (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 39, 15, 02, 16]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 57, 21) to (start + 2, 22)

Function name: <<<nested::MyOuter>::outer_method::MyMiddle>::middle_method::MyInner>::inner_method (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 23, 15, 02, 16]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 35, 21) to (start + 2, 22)

Function name: <<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 36, 0d, 08, 0e]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 54, 13) to (start + 8, 14)

Function name: <<nested::MyOuter>::outer_method::MyMiddle>::middle_method (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 20, 0d, 08, 0e]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 32, 13) to (start + 8, 14)

Function name: nested::closure_expr
Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15)
- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)

Function name: nested::closure_expr::{closure#0}::{closure#0} (unused)
Raw bytes (14): 0x[01, 01, 00, 02, 00, 47, 1a, 01, 17, 00, 04, 0d, 01, 0a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Zero) at (prev + 71, 26) to (start + 1, 23)
- Code(Zero) at (prev + 4, 13) to (start + 1, 10)

Function name: nested::closure_expr::{closure#0}::{closure#0}::{closure#0} (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 48, 1d, 02, 0e]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 72, 29) to (start + 2, 14)

Function name: nested::closure_tail
Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15)
- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)

Function name: nested::closure_tail::{closure#0}::{closure#0} (unused)
Raw bytes (14): 0x[01, 01, 00, 02, 00, 58, 14, 01, 1f, 00, 06, 15, 01, 12]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Zero) at (prev + 88, 20) to (start + 1, 31)
- Code(Zero) at (prev + 6, 21) to (start + 1, 18)

Function name: nested::closure_tail::{closure#0}::{closure#0}::{closure#0} (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 5a, 1c, 02, 1a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 90, 28) to (start + 2, 26)

Function name: nested::outer_fn::middle_fn (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 05, 05, 06]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 17, 5) to (start + 5, 6)

Function name: nested::outer_fn::middle_fn::inner_fn (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 18, 9) to (start + 2, 10)

111 changes: 111 additions & 0 deletions tests/coverage/attr/nested.coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
LL| |#![feature(coverage_attribute, stmt_expr_attributes)]
LL| |//@ edition: 2021
LL| |
LL| |// Demonstrates the interaction between #[coverage(off)] and various kinds of
LL| |// nested function.
LL| |
LL| |// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
LL| |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
LL| |// its lines can still be marked with misleading execution counts from its enclosing
LL| |// function.
LL| |
LL| |#[coverage(off)]
LL| |fn do_stuff() {}
LL| |
LL| |#[coverage(off)]
LL| |fn outer_fn() {
LL| 0| fn middle_fn() {
LL| 0| fn inner_fn() {
LL| 0| do_stuff();
LL| 0| }
LL| 0| do_stuff();
LL| 0| }
LL| | do_stuff();
LL| |}
LL| |
LL| |struct MyOuter;
LL| |impl MyOuter {
LL| | #[coverage(off)]
LL| | fn outer_method(&self) {
LL| | struct MyMiddle;
LL| | impl MyMiddle {
LL| 0| fn middle_method(&self) {
LL| 0| struct MyInner;
LL| 0| impl MyInner {
LL| 0| fn inner_method(&self) {
LL| 0| do_stuff();
LL| 0| }
LL| 0| }
LL| 0| do_stuff();
LL| 0| }
LL| | }
LL| | do_stuff();
LL| | }
LL| |}
LL| |
LL| |trait MyTrait {
LL| | fn trait_method(&self);
LL| |}
LL| |impl MyTrait for MyOuter {
LL| | #[coverage(off)]
LL| | fn trait_method(&self) {
LL| | struct MyMiddle;
LL| | impl MyTrait for MyMiddle {
LL| 0| fn trait_method(&self) {
LL| 0| struct MyInner;
LL| 0| impl MyTrait for MyInner {
LL| 0| fn trait_method(&self) {
LL| 0| do_stuff();
LL| 0| }
LL| 0| }
LL| 0| do_stuff();
LL| 0| }
LL| | }
LL| | do_stuff();
LL| | }
LL| |}
LL| |
LL| 1|fn closure_expr() {
LL| 1| let _outer = #[coverage(off)]
LL| | || {
LL| 0| let _middle = || {
LL| 0| let _inner = || {
LL| 0| do_stuff();
LL| 0| };
LL| 0| do_stuff();
LL| 0| };
LL| | do_stuff();
LL| | };
LL| 1| do_stuff();
LL| 1|}
LL| |
LL| |// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
LL| 1|fn closure_tail() {
LL| 1| let _outer = {
LL| | #[coverage(off)]
LL| | || {
LL| | let _middle = {
LL| 0| || {
LL| 0| let _inner = {
LL| 0| || {
LL| 0| do_stuff();
LL| 0| }
LL| | };
LL| 0| do_stuff();
LL| 0| }
LL| | };
LL| | do_stuff();
LL| | }
LL| | };
LL| 1| do_stuff();
LL| 1|}
LL| |
LL| |#[coverage(off)]
LL| |fn main() {
LL| | outer_fn();
LL| | MyOuter.outer_method();
LL| | MyOuter.trait_method();
LL| | closure_expr();
LL| | closure_tail();
LL| |}

Loading

0 comments on commit 8814b92

Please sign in to comment.