1
Fork 0

coverage: Add -Zcoverage-options for fine control of coverage

This new nightly-only flag can be used to toggle fine-grained flags that
control the details of coverage instrumentation.

Currently the only supported flag value is `branch` (or `no-branch`), which is
a placeholder for upcoming support for branch coverage. Other flag values can
be added in the future, to prototype proposed new behaviour, or to enable
special non-default behaviour.
This commit is contained in:
Zalathar 2024-03-08 18:07:04 +11:00
parent 1f544ce305
commit 3407fcc12e
8 changed files with 84 additions and 11 deletions

View file

@ -143,6 +143,19 @@ pub enum InstrumentCoverage {
Yes,
}
/// Individual flag values controlled by `-Z coverage-options`.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct CoverageOptions {
/// Add branch coverage instrumentation (placeholder flag; not yet implemented).
pub branch: bool,
}
impl Default for CoverageOptions {
fn default() -> Self {
Self { branch: false }
}
}
/// Settings for `-Z instrument-xray` flag.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct InstrumentXRay {
@ -3168,12 +3181,12 @@ pub enum WasiExecModel {
/// how the hash should be calculated when adding a new command-line argument.
pub(crate) mod dep_tracking {
use super::{
BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CrateType, DebugInfo,
DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold,
InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli,
NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius,
RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use crate::lint;
use crate::utils::NativeLib;
@ -3243,6 +3256,7 @@ pub(crate) mod dep_tracking {
CodeModel,
TlsModel,
InstrumentCoverage,
CoverageOptions,
InstrumentXRay,
CrateType,
MergeFunctions,

View file

@ -396,6 +396,7 @@ 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 = "`branch` or `no-branch`";
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";
@ -938,6 +939,24 @@ mod parse {
true
}
pub(crate) fn parse_coverage_options(slot: &mut CoverageOptions, v: Option<&str>) -> bool {
let Some(v) = v else { return true };
for option in v.split(',') {
let (option, enabled) = match option.strip_prefix("no-") {
Some(without_no) => (without_no, false),
None => (option, true),
};
let slot = match option {
"branch" => &mut slot.branch,
_ => return false,
};
*slot = enabled;
}
true
}
pub(crate) fn parse_instrument_xray(
slot: &mut Option<InstrumentXRay>,
v: Option<&str>,
@ -1564,6 +1583,8 @@ options! {
"set option to collapse debuginfo for macros"),
combine_cgu: bool = (false, parse_bool, [TRACKED],
"combine CGUs into a single one"),
coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED],
"control details of coverage instrumentation"),
crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
"inject the given attribute in the crate"),
cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED],

View file

@ -352,6 +352,10 @@ impl Session {
self.opts.cg.instrument_coverage() != InstrumentCoverage::No
}
pub fn instrument_coverage_branch(&self) -> bool {
self.instrument_coverage() && self.opts.unstable_opts.coverage_options.branch
}
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}