coverage. Add coverage-options=mcdc as gate for MC/DC instrument

This commit is contained in:
zhuyunxing 2024-04-19 10:43:53 +08:00
parent e3181b091e
commit 68f86381ee
10 changed files with 40 additions and 15 deletions

View File

@ -758,7 +758,7 @@ macro_rules! tracked {
); );
tracked!(codegen_backend, Some("abc".to_string())); tracked!(codegen_backend, Some("abc".to_string()));
tracked!(collapse_macro_debuginfo, CollapseMacroDebuginfo::Yes); tracked!(collapse_macro_debuginfo, CollapseMacroDebuginfo::Yes);
tracked!(coverage_options, CoverageOptions { branch: true }); tracked!(coverage_options, CoverageOptions { branch: true, mcdc: true });
tracked!(crate_attr, vec!["abc".to_string()]); tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true); tracked!(debug_info_for_profiling, true);

View File

@ -97,6 +97,8 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
.label = dereference of raw pointer .label = dereference of raw pointer
mir_build_exceeds_mcdc_condition_num_limit = Conditions number of the decision ({$conditions_num}) exceeds limit ({$max_conditions_num}). MCDC analysis will not count this expression.
mir_build_extern_static_requires_unsafe = mir_build_extern_static_requires_unsafe =
use of extern static is unsafe and requires unsafe block use of extern static is unsafe and requires unsafe block
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior

View File

@ -818,6 +818,15 @@ pub struct NontrivialStructuralMatch<'tcx> {
pub non_sm_ty: Ty<'tcx>, pub non_sm_ty: Ty<'tcx>,
} }
#[derive(Diagnostic)]
#[diag(mir_build_exceeds_mcdc_condition_num_limit)]
pub(crate) struct MCDCExceedsConditionNumLimit {
#[primary_span]
pub span: Span,
pub conditions_num: usize,
pub max_conditions_num: usize,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_pattern_not_covered, code = E0005)] #[diag(mir_build_pattern_not_covered, code = E0005)]
pub(crate) struct PatternNotCovered<'s, 'tcx> { pub(crate) struct PatternNotCovered<'s, 'tcx> {

View File

@ -148,6 +148,8 @@ pub enum InstrumentCoverage {
pub struct CoverageOptions { pub struct CoverageOptions {
/// Add branch coverage instrumentation. /// Add branch coverage instrumentation.
pub branch: bool, pub branch: bool,
/// Add mcdc coverage instrumentation.
pub mcdc: bool,
} }
/// Settings for `-Z instrument-xray` flag. /// Settings for `-Z instrument-xray` flag.

View File

@ -396,7 +396,7 @@ mod desc {
pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
pub const parse_instrument_coverage: &str = parse_bool; pub const parse_instrument_coverage: &str = parse_bool;
pub const parse_coverage_options: &str = "`branch` or `no-branch`"; pub const parse_coverage_options: &str = "either `no-branch`, `branch` or `mcdc`";
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_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_unpretty: &str = "`string` or `string=string`";
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
@ -946,17 +946,19 @@ pub(crate) fn parse_coverage_options(slot: &mut CoverageOptions, v: Option<&str>
let Some(v) = v else { return true }; let Some(v) = v else { return true };
for option in v.split(',') { for option in v.split(',') {
let (option, enabled) = match option.strip_prefix("no-") { match option {
Some(without_no) => (without_no, false), "no-branch" => {
None => (option, true), slot.branch = false;
}; slot.mcdc = false;
let slot = match option { }
"branch" => &mut slot.branch, "branch" => slot.branch = true,
"mcdc" => {
slot.branch = true;
slot.mcdc = true;
}
_ => return false, _ => return false,
}; }
*slot = enabled;
} }
true true
} }

View File

@ -352,6 +352,10 @@ pub fn instrument_coverage_branch(&self) -> bool {
self.instrument_coverage() && self.opts.unstable_opts.coverage_options.branch self.instrument_coverage() && self.opts.unstable_opts.coverage_options.branch
} }
pub fn instrument_coverage_mcdc(&self) -> bool {
self.instrument_coverage() && self.opts.unstable_opts.coverage_options.mcdc
}
pub fn is_sanitizer_cfi_enabled(&self) -> bool { pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI) self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
} }

View File

@ -351,8 +351,8 @@ $ llvm-cov report \
This unstable option provides finer control over some aspects of coverage This unstable option provides finer control over some aspects of coverage
instrumentation. Pass one or more of the following values, separated by commas. instrumentation. Pass one or more of the following values, separated by commas.
- `branch` or `no-branch` - Either `no-branch`, `branch` or `mcdc`
- Enables or disables branch coverage instrumentation. - `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation, which is same as do not pass `branch` or `mcdc`.
## Other references ## Other references

View File

@ -5,4 +5,4 @@ This option controls details of the coverage instrumentation performed by
Multiple options can be passed, separated by commas. Valid options are: Multiple options can be passed, separated by commas. Valid options are:
- `branch` or `no-branch`: Enables or disables branch coverage instrumentation. - `no-branch`, `branch` or `mcdc`: `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation as well as mcdc instrumentation, which is same as do not pass `branch` or `mcdc`.

View File

@ -1,2 +1,2 @@
error: incorrect value `bad` for unstable option `coverage-options` - `branch` or `no-branch` was expected error: incorrect value `bad` for unstable option `coverage-options` - either `no-branch`, `branch` or `mcdc` was expected

View File

@ -8,7 +8,13 @@
//@ [no-branch] check-pass //@ [no-branch] check-pass
//@ [no-branch] compile-flags: -Zcoverage-options=no-branch //@ [no-branch] compile-flags: -Zcoverage-options=no-branch
//@ [mcdc] check-pass
//@ [mcdc] compile-flags: -Zcoverage-options=mcdc
//@ [bad] check-fail //@ [bad] check-fail
//@ [bad] compile-flags: -Zcoverage-options=bad //@ [bad] compile-flags: -Zcoverage-options=bad
//@ [conflict] check-fail
//@ [conflict] compile-flags: -Zcoverage-options=no-branch,mcdc
fn main() {} fn main() {}