Skip to content

Commit 994d950

Browse files
committed
Add --mcdc flag, and handle MC/DC fields correctly in LLVM JSON
This adds a new unstable `--mcdc` flag, similar to `--branch`. Apart from that, the LLVM JSON parser also needed changes to recognize the mcdc-related fields, as it would otherwise silently drop those.
1 parent 7d4bb5e commit 994d950

40 files changed

+400
-2
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,11 @@ jobs:
117117
pushd tests/fixtures/crates/cargo_config >/dev/null
118118
# TODO: --fail-under-branches?
119119
cargo llvm-cov test --branch --text --fail-under-lines 80
120+
cargo llvm-cov test --mcdc --text --fail-under-lines 80
120121
popd >/dev/null
121122
pushd easytime >/dev/null
122123
cargo llvm-cov test --branch --doctests --text --fail-under-lines 30
124+
cargo llvm-cov test --mcdc --doctests --text --fail-under-lines 30
123125
popd >/dev/null
124126
125127
# Test minimum runnable Cargo version.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ OPTIONS:
184184
--branch
185185
Enable branch coverage. (unstable)
186186

187+
--mcdc
188+
Enable mcdc coverage. (unstable)
189+
187190
--doctests
188191
Including doc tests (unstable)
189192

docs/cargo-llvm-cov-run.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ OPTIONS:
138138
--branch
139139
Enable branch coverage. (unstable)
140140

141+
--mcdc
142+
Enable mcdc coverage. (unstable)
143+
141144
--ignore-run-fail
142145
Run all tests regardless of failure and generate report
143146

docs/cargo-llvm-cov-test.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ OPTIONS:
143143
--branch
144144
Enable branch coverage. (unstable)
145145

146+
--mcdc
147+
Enable mcdc coverage. (unstable)
148+
146149
--doctests
147150
Including doc tests (unstable)
148151

docs/cargo-llvm-cov.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ OPTIONS:
138138
--branch
139139
Enable branch coverage. (unstable)
140140

141+
--mcdc
142+
Enable mcdc coverage. (unstable)
143+
141144
--doctests
142145
Including doc tests (unstable)
143146

src/cargo.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ pub(crate) struct Workspace {
3636
}
3737

3838
impl Workspace {
39+
#[allow(clippy::fn_params_excessive_bools)]
3940
pub(crate) fn new(
4041
options: &ManifestOptions,
4142
target: Option<&str>,
4243
doctests: bool,
4344
branch: bool,
45+
mcdc: bool,
4446
show_env: bool,
4547
) -> Result<Self> {
4648
// Metadata and config
@@ -64,6 +66,11 @@ impl Workspace {
6466
if branch && !rustc_version.nightly {
6567
bail!("--branch flag requires nightly toolchain; consider using `cargo +nightly llvm-cov`")
6668
}
69+
if mcdc && !rustc_version.nightly {
70+
bail!(
71+
"--mcdc flag requires nightly toolchain; consider using `cargo +nightly llvm-cov`"
72+
)
73+
}
6774
let stable_coverage =
6875
rustc.clone().args(["-C", "help"]).read()?.contains("instrument-coverage");
6976
if !stable_coverage && !rustc_version.nightly {

src/clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
};
2222

2323
pub(crate) fn run(args: &mut Args) -> Result<()> {
24-
let ws = Workspace::new(&args.manifest, None, false, false, false)?;
24+
let ws = Workspace::new(&args.manifest, None, false, false, false, false)?;
2525
cli::merge_config_to_args(&ws, &mut None, &mut args.verbose, &mut args.color);
2626
term::set_coloring(&mut args.color);
2727

src/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ pub(crate) struct LlvmCovOptions {
357357
pub(crate) skip_functions: bool,
358358
/// Enable branch coverage. (unstable)
359359
pub(crate) branch: bool,
360+
/// Enable mcdc coverage. (unstable)
361+
pub(crate) mcdc: bool,
360362
}
361363

362364
impl LlvmCovOptions {
@@ -511,6 +513,7 @@ impl Args {
511513
let mut dep_coverage = None;
512514
let mut skip_functions = false;
513515
let mut branch = false;
516+
let mut mcdc = false;
514517

515518
// build options
516519
let mut release = false;
@@ -670,6 +673,7 @@ impl Args {
670673
Long("summary-only") => parse_flag!(summary_only),
671674
Long("skip-functions") => parse_flag!(skip_functions),
672675
Long("branch") => parse_flag!(branch),
676+
Long("mcdc") => parse_flag!(mcdc),
673677
Long("output-path") => parse_opt!(output_path),
674678
Long("output-dir") => parse_opt!(output_dir),
675679
Long("failure-mode") => parse_opt!(failure_mode),
@@ -1190,6 +1194,7 @@ impl Args {
11901194
dep_coverage,
11911195
skip_functions,
11921196
branch,
1197+
mcdc,
11931198
},
11941199
show_env: ShowEnvOptions { export_prefix },
11951200
doctests,

src/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl Context {
5151
args.target.as_deref(),
5252
args.doctests,
5353
args.cov.branch,
54+
args.cov.mcdc,
5455
show_env,
5556
)?;
5657
cli::merge_config_to_args(&ws, &mut args.target, &mut args.verbose, &mut args.color);
@@ -74,6 +75,9 @@ impl Context {
7475
if args.cov.branch {
7576
warn!("--branch option is unstable");
7677
}
78+
if args.cov.mcdc {
79+
warn!("--mcdc option is unstable");
80+
}
7781
if args.doc {
7882
warn!("--doc option is unstable");
7983
} else if args.doctests {

src/json.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ pub struct File {
340340
/// This is None if report is summary-only.
341341
#[serde(skip_serializing_if = "Option::is_none")]
342342
branches: Option<Vec<serde_json::Value>>,
343+
/// List of MC/DC records contained in the file
344+
///
345+
/// This is None if report is summary-only.
346+
#[serde(skip_serializing_if = "Option::is_none")]
347+
mcdc_records: Option<Vec<serde_json::Value>>,
343348
/// List of expansion records
344349
///
345350
/// This is None if report is summary-only.
@@ -406,6 +411,8 @@ impl fmt::Debug for Segment {
406411
#[cfg_attr(test, serde(deny_unknown_fields))]
407412
struct Function {
408413
branches: Vec<serde_json::Value>,
414+
#[serde(skip_serializing_if = "Option::is_none")]
415+
mcdc_records: Option<Vec<serde_json::Value>>,
409416
count: u64,
410417
/// List of filenames that the function relates to
411418
filenames: Vec<String>,
@@ -500,6 +507,9 @@ impl RegionLocation {
500507
struct Summary {
501508
/// Object summarizing branch coverage
502509
branches: CoverageCounts,
510+
/// Object summarizing mcdc coverage
511+
#[serde(skip_serializing_if = "Option::is_none")]
512+
mcdc: Option<CoverageCounts>,
503513
/// Object summarizing function coverage
504514
functions: CoverageCounts,
505515
instantiations: CoverageCounts,

src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,11 @@ fn set_env(cx: &Context, env: &mut dyn EnvTarget, IsNextest(is_nextest): IsNexte
196196
flags.push("codegen-units=1");
197197
}
198198
}
199-
if cx.args.cov.branch {
199+
if cx.args.cov.mcdc {
200+
// Tracking issue: https://github.com/rust-lang/rust/issues/124144
201+
flags.push("-Z");
202+
flags.push("coverage-options=mcdc");
203+
} else if cx.args.cov.branch {
200204
// Tracking issue: https://github.com/rust-lang/rust/issues/79649
201205
flags.push("-Z");
202206
flags.push("coverage-options=branch");

tests/fixtures/coverage-reports/bin_crate/bin_crate.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,

tests/fixtures/coverage-reports/bin_crate/run.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,

tests/fixtures/coverage-reports/cargo_config/cargo_config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 2,
1622
"covered": 2,

tests/fixtures/coverage-reports/cargo_config_toml/cargo_config_toml.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 2,
1622
"covered": 2,

tests/fixtures/coverage-reports/coverage_helper/coverage_helper.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,

tests/fixtures/coverage-reports/instantiations/instantiations.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 2,
1622
"covered": 2,

tests/fixtures/coverage-reports/merge/clean_ws.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 2,
1622
"covered": 2,

tests/fixtures/coverage-reports/no_coverage/no_cfg_coverage.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 4,
1622
"covered": 4,

tests/fixtures/coverage-reports/no_coverage/no_coverage.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 2,
1622
"covered": 2,

tests/fixtures/coverage-reports/no_test/link_dead_code.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,
@@ -43,6 +49,12 @@
4349
"notcovered": 0,
4450
"percent": 0.0
4551
},
52+
"mcdc": {
53+
"count": 0,
54+
"covered": 0,
55+
"notcovered": 0,
56+
"percent": 0.0
57+
},
4658
"functions": {
4759
"count": 1,
4860
"covered": 0,

tests/fixtures/coverage-reports/no_test/no_test.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,
@@ -43,6 +49,12 @@
4349
"notcovered": 0,
4450
"percent": 0.0
4551
},
52+
"mcdc": {
53+
"count": 0,
54+
"covered": 0,
55+
"notcovered": 0,
56+
"percent": 0.0
57+
},
4658
"functions": {
4759
"count": 1,
4860
"covered": 0,

tests/fixtures/coverage-reports/real1/all.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"notcovered": 0,
1212
"percent": 0.0
1313
},
14+
"mcdc": {
15+
"count": 0,
16+
"covered": 0,
17+
"notcovered": 0,
18+
"percent": 0.0
19+
},
1420
"functions": {
1521
"count": 1,
1622
"covered": 1,
@@ -43,6 +49,12 @@
4349
"notcovered": 0,
4450
"percent": 0.0
4551
},
52+
"mcdc": {
53+
"count": 0,
54+
"covered": 0,
55+
"notcovered": 0,
56+
"percent": 0.0
57+
},
4658
"functions": {
4759
"count": 1,
4860
"covered": 1,
@@ -75,6 +87,12 @@
7587
"notcovered": 0,
7688
"percent": 0.0
7789
},
90+
"mcdc": {
91+
"count": 0,
92+
"covered": 0,
93+
"notcovered": 0,
94+
"percent": 0.0
95+
},
7896
"functions": {
7997
"count": 2,
8098
"covered": 2,

0 commit comments

Comments
 (0)