From 34106f89353575bd341e27b95e4e759866cd7939 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 21 Oct 2021 16:04:22 +0200 Subject: [PATCH] Stabilize -Z instrument-coverage as -C instrument-coverage Continue supporting -Z instrument-coverage for compatibility for now, but show a deprecation warning for it. Update uses and documentation to use the -C option. Move the documentation from the unstable book to stable rustc documentation. --- .../src/coverageinfo/mapgen.rs | 4 +- .../src/traits/coverageinfo.rs | 8 +-- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/query.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- .../rustc_mir_transform/src/coverage/debug.rs | 2 +- compiler/rustc_mir_transform/src/simplify.rs | 2 +- compiler/rustc_session/src/config.rs | 45 ++++++++++----- compiler/rustc_session/src/options.rs | 15 +++-- config.toml.example | 4 +- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/codegen-options/index.md | 6 ++ .../src}/instrument-coverage.md | 56 +++++++++---------- .../source-based-code-coverage.md | 5 -- src/librustdoc/doctest.rs | 4 +- src/test/mir-opt/coverage_graphviz.rs | 4 +- src/test/mir-opt/instrument_coverage.rs | 4 +- .../coverage-llvmir/Makefile | 2 +- .../coverage-llvmir/filecheck.testprog.txt | 2 +- .../coverage-reports/Makefile | 6 +- .../expected_show_coverage.uses_crate.txt | 2 +- .../coverage/lib/used_crate.rs | 2 +- 23 files changed, 102 insertions(+), 79 deletions(-) rename src/doc/{unstable-book/src/compiler-flags => rustc/src}/instrument-coverage.md (89%) delete mode 100644 src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index e0af5653753..dc48eac7156 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -37,7 +37,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { // LLVM 12. let version = coverageinfo::mapping_version(); if version < 4 { - tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 12 or higher."); + tcx.sess.fatal("rustc option `-C instrument-coverage` requires LLVM 12 or higher."); } debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name()); @@ -264,7 +264,7 @@ fn save_function_record( /// (functions referenced by other "used" or public items). Any other functions considered unused, /// or "Unreachable", were still parsed and processed through the MIR stage, but were not /// codegenned. (Note that `-Clink-dead-code` can force some unused code to be codegenned, but -/// that flag is known to cause other errors, when combined with `-Z instrument-coverage`; and +/// that flag is known to cause other errors, when combined with `-C instrument-coverage`; and /// `-Clink-dead-code` will not generate code for unused generic functions.) /// /// We can find the unused functions (including generic functions) by the set difference of all MIR diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index cbf570dba4c..e77201cf0c8 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -22,7 +22,7 @@ pub trait CoverageInfoMethods<'tcx>: BackendTypes { pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { /// Returns true if the function source hash was added to the coverage map (even if it had - /// already been added, for this instance). Returns false *only* if `-Z instrument-coverage` is + /// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is /// not enabled (a coverage map is not being generated). fn set_function_source_hash( &mut self, @@ -30,7 +30,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { function_source_hash: u64, ) -> bool; - /// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage` + /// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage` /// is not enabled (a coverage map is not being generated). fn add_coverage_counter( &mut self, @@ -40,7 +40,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { ) -> bool; /// Returns true if the expression was added to the coverage map; false if - /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). + /// `-C instrument-coverage` is not enabled (a coverage map is not being generated). fn add_coverage_counter_expression( &mut self, instance: Instance<'tcx>, @@ -51,7 +51,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { region: Option, ) -> bool; - /// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage` + /// Returns true if the region was added to the coverage map; false if `-C instrument-coverage` /// is not enabled (a coverage map is not being generated). fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool; } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 816e770f012..508af06610a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -575,6 +575,7 @@ fn test_codegen_options_tracking_hash() { tracked!(force_frame_pointers, Some(false)); tracked!(force_unwind_tables, Some(true)); tracked!(inline_threshold, Some(0xf007ba11)); + tracked!(instrument_coverage, Some(InstrumentCoverage::All)); tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto); tracked!(link_dead_code, Some(true)); tracked!(llvm_args, vec![String::from("1"), String::from("2")]); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c7c306e7d06..1ea3ba439b5 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1590,7 +1590,7 @@ pub enum StatementKind<'tcx> { /// - `Bivariant` -- no effect AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance), - /// Marks the start of a "coverage region", injected with '-Zinstrument-coverage'. A + /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage /// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates /// executable code, to increment a counter variable at runtime, each time the code region is diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index cb3f3850958..4b8eb3fbd96 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -390,7 +390,7 @@ pub struct DestructuredConst<'tcx> { } /// Coverage information summarized from a MIR if instrumented for source code coverage (see -/// compiler option `-Zinstrument-coverage`). This information is generated by the +/// compiler option `-Cinstrument-coverage`). This information is generated by the /// `InstrumentCoverage` MIR pass and can be retrieved via the `coverageinfo` query. #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable)] pub struct CoverageInfo { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 027c0c64924..0ae34e264a9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -380,7 +380,7 @@ rustc_queries! { } /// Returns coverage summary info for a function, after executing the `InstrumentCoverage` - /// MIR pass (assuming the -Zinstrument-coverage option is enabled). + /// MIR pass (assuming the -Cinstrument-coverage option is enabled). query coverageinfo(key: ty::InstanceDef<'tcx>) -> mir::CoverageInfo { desc { |tcx| "retrieving coverage info from MIR for `{}`", tcx.def_path_str(key.def_id()) } storage(ArenaCacheSelector<'tcx>) diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs index c61ee6f7e6c..c64165163ad 100644 --- a/compiler/rustc_mir_transform/src/coverage/debug.rs +++ b/compiler/rustc_mir_transform/src/coverage/debug.rs @@ -3,7 +3,7 @@ //! //! To enable coverage, include the rustc command line option: //! -//! * `-Z instrument-coverage` +//! * `-C instrument-coverage` //! //! MIR Dump Files, with additional `CoverageGraph` graphviz and `CoverageSpan` spanview //! ------------------------------------------------------------------------------------ diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 7992124bacd..1c7f73d542e 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -303,7 +303,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// evaluation: `if false { ... }`. /// /// Those statements are bypassed by redirecting paths in the CFG around the -/// `dead blocks`; but with `-Z instrument-coverage`, the dead blocks usually +/// `dead blocks`; but with `-C instrument-coverage`, the dead blocks usually /// include `Coverage` statements representing the Rust source code regions to /// be counted at runtime. Without these `Coverage` statements, the regions are /// lost, and the Rust source code will show no coverage information. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f2c7959ddb6..fa14a95bb0c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -127,15 +127,15 @@ pub enum MirSpanview { Block, } -/// The different settings that the `-Z instrument-coverage` flag can have. +/// The different settings that the `-C instrument-coverage` flag can have. /// -/// Coverage instrumentation now supports combining `-Z instrument-coverage` +/// Coverage instrumentation now supports combining `-C instrument-coverage` /// with compiler and linker optimization (enabled with `-O` or `-C opt-level=1` /// and higher). Nevertheless, there are many variables, depending on options /// selected, code structure, and enabled attributes. If errors are encountered, /// either while compiling or when generating `llvm-cov show` reports, consider /// lowering the optimization level, including or excluding `-C link-dead-code`, -/// or using `-Z instrument-coverage=except-unused-functions` or `-Z +/// or using `-C instrument-coverage=except-unused-functions` or `-C /// instrument-coverage=except-unused-generics`. /// /// Note that `ExceptUnusedFunctions` means: When `mapgen.rs` generates the @@ -148,13 +148,13 @@ pub enum MirSpanview { /// unless the function has type parameters. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum InstrumentCoverage { - /// Default `-Z instrument-coverage` or `-Z instrument-coverage=statement` + /// Default `-C instrument-coverage` or `-C instrument-coverage=statement` All, - /// `-Z instrument-coverage=except-unused-generics` + /// `-C instrument-coverage=except-unused-generics` ExceptUnusedGenerics, - /// `-Z instrument-coverage=except-unused-functions` + /// `-C instrument-coverage=except-unused-functions` ExceptUnusedFunctions, - /// `-Z instrument-coverage=off` (or `no`, etc.) + /// `-C instrument-coverage=off` (or `no`, etc.) Off, } @@ -2144,18 +2144,37 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { _ => {} } - if debugging_opts.instrument_coverage.is_some() - && debugging_opts.instrument_coverage != Some(InstrumentCoverage::Off) - { + // Handle both `-Z instrument-coverage` and `-C instrument-coverage`; the latter takes + // precedence. + match (cg.instrument_coverage, debugging_opts.instrument_coverage) { + (Some(ic_c), Some(ic_z)) if ic_c != ic_z => { + early_error( + error_format, + "incompatible values passed for `-C instrument-coverage` \ + and `-Z instrument-coverage`", + ); + } + (None, None) => {} + (None, ic) => { + early_warn( + error_format, + "`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`", + ); + cg.instrument_coverage = ic; + } + _ => {} + } + + if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) { if cg.profile_generate.enabled() || cg.profile_use.is_some() { early_error( error_format, - "option `-Z instrument-coverage` is not compatible with either `-C profile-use` \ + "option `-C instrument-coverage` is not compatible with either `-C profile-use` \ or `-C profile-generate`", ); } - // `-Z instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent + // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over // multiple runs, including some changes to source code; so mangled names must be consistent // across compilations. @@ -2164,7 +2183,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { Some(SymbolManglingVersion::Legacy) => { early_warn( error_format, - "-Z instrument-coverage requires symbol mangling version `v0`, \ + "-C instrument-coverage requires symbol mangling version `v0`, \ but `-C symbol-mangling-version=legacy` was specified", ); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c8adc9f00a1..2b39d97d55b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -109,17 +109,16 @@ impl Options { } pub fn instrument_coverage(&self) -> bool { - self.debugging_opts.instrument_coverage.unwrap_or(InstrumentCoverage::Off) - != InstrumentCoverage::Off + self.cg.instrument_coverage.unwrap_or(InstrumentCoverage::Off) != InstrumentCoverage::Off } pub fn instrument_coverage_except_unused_generics(&self) -> bool { - self.debugging_opts.instrument_coverage.unwrap_or(InstrumentCoverage::Off) + self.cg.instrument_coverage.unwrap_or(InstrumentCoverage::Off) == InstrumentCoverage::ExceptUnusedGenerics } pub fn instrument_coverage_except_unused_functions(&self) -> bool { - self.debugging_opts.instrument_coverage.unwrap_or(InstrumentCoverage::Off) + self.cg.instrument_coverage.unwrap_or(InstrumentCoverage::Off) == InstrumentCoverage::ExceptUnusedFunctions } } @@ -1021,6 +1020,14 @@ options! { "enable incremental compilation"), inline_threshold: Option = (None, parse_opt_number, [TRACKED], "set the threshold for inlining a function"), + instrument_coverage: Option = (None, parse_instrument_coverage, [TRACKED], + "instrument the generated code to support LLVM source-based code coverage \ + reports (note, the compiler build config must include `profiler = true`); \ + implies `-C symbol-mangling-version=v0`. Optional values are: + `=all` (implicit value) + `=except-unused-generics` + `=except-unused-functions` + `=off` (default)"), link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED], "a single extra argument to append to the linker invocation (can be used several times)"), link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], diff --git a/config.toml.example b/config.toml.example index f24f8e81a79..98688ca65b7 100644 --- a/config.toml.example +++ b/config.toml.example @@ -289,7 +289,7 @@ changelog-seen = 2 #sanitizers = false # Build the profiler runtime (required when compiling with options that depend -# on this runtime, such as `-C profile-generate` or `-Z instrument-coverage`). +# on this runtime, such as `-C profile-generate` or `-C instrument-coverage`). #profiler = false # Indicates whether the native libraries linked into Cargo will be statically @@ -671,7 +671,7 @@ changelog-seen = 2 #sanitizers = build.sanitizers (bool) # Build the profiler runtime for this target(required when compiling with options that depend -# on this runtime, such as `-C profile-generate` or `-Z instrument-coverage`). +# on this runtime, such as `-C profile-generate` or `-C instrument-coverage`). # This option will override the same option under [build] section. #profiler = build.profiler (bool) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 69a0304d41d..1142bf59a39 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -23,6 +23,7 @@ - [Custom Targets](targets/custom.md) - [Known Issues](targets/known-issues.md) - [Profile-guided Optimization](profile-guided-optimization.md) +- [Instrumentation-based Code Coverage](instrument-coverage.md) - [Linker-plugin based LTO](linker-plugin-lto.md) - [Exploit Mitigations](exploit-mitigations.md) - [Contributing to `rustc`](contributing.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 0201b88417a..d50c2317a0c 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -177,6 +177,11 @@ The default depends on the [opt-level](#opt-level): | s | 75 | | z | 25 | +## instrument-coverage + +This option enables instrumentation-based code coverage support. See the +chapter on [instrumentation-based code coverage] for more information. + ## link-arg This flag lets you append a single extra argument to the linker invocation. @@ -597,5 +602,6 @@ effective only for x86 targets. [option-emit]: ../command-line-arguments.md#option-emit [option-o-optimize]: ../command-line-arguments.md#option-o-optimize +[instrumentation-based code coverage]: ../instrument-coverage.md [profile-guided optimization]: ../profile-guided-optimization.md [option-g-debug]: ../command-line-arguments.md#option-g-debug diff --git a/src/doc/unstable-book/src/compiler-flags/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md similarity index 89% rename from src/doc/unstable-book/src/compiler-flags/instrument-coverage.md rename to src/doc/rustc/src/instrument-coverage.md index 39eb407269c..f0b71db1201 100644 --- a/src/doc/unstable-book/src/compiler-flags/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -1,23 +1,17 @@ # `instrument-coverage` -The tracking issue for this feature is: [#79121]. - -[#79121]: https://github.com/rust-lang/rust/issues/79121 - ---- - ## Introduction The Rust compiler includes two code coverage implementations: - A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo. -- A source-based code coverage implementation, enabled with `-Z instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data. +- A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data. -This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-Z instrument-coverage` compiler flag. +This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag. ## How it works -When `-Z instrument-coverage` is enabled, the Rust compiler enhances rust-based libraries and binaries by: +When `-C instrument-coverage` is enabled, the Rust compiler enhances rust-based libraries and binaries by: - Automatically injecting calls to an LLVM intrinsic ([`llvm.instrprof.increment`]), at functions and branches in compiled code, to increment counters when conditional sections of code are executed. - Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format] _Version 5_, if compiling with LLVM 12, or _Version 6_, if compiling with LLVM 13 or higher), to define the code regions (start and end positions in the source code) being counted. @@ -27,13 +21,13 @@ When running a coverage-instrumented program, the counter values are written to [`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic [llvm code coverage mapping format]: https://llvm.org/docs/CoverageMappingFormat.html -> **Note**: `-Z instrument-coverage` also automatically enables `-C symbol-mangling-version=v0` (tracking issue [#60705]). The `v0` symbol mangler is strongly recommended, but be aware that this demangler is also experimental. The `v0` demangler can be overridden by explicitly adding `-Z unstable-options -C symbol-mangling-version=legacy`. +> **Note**: `-C instrument-coverage` also automatically enables `-C symbol-mangling-version=v0` (tracking issue [#60705]). The `v0` symbol mangler is strongly recommended. The `v0` demangler can be overridden by explicitly adding `-Z unstable-options -C symbol-mangling-version=legacy`. [#60705]: https://github.com/rust-lang/rust/issues/60705 ## Enable coverage profiling in the Rust compiler -Rust's source-based code coverage requires the Rust "profiler runtime". Without it, compiling with `-Z instrument-coverage` generates an error that the profiler runtime is missing. +Rust's source-based code coverage requires the Rust "profiler runtime". Without it, compiling with `-C instrument-coverage` generates an error that the profiler runtime is missing. The Rust `nightly` distribution channel includes the profiler runtime, by default. @@ -41,7 +35,7 @@ The Rust `nightly` distribution channel includes the profiler runtime, by defaul > > ```toml > # Build the profiler runtime (required when compiling with options that depend -> # on this runtime, such as `-C profile-generate` or `-Z instrument-coverage`). +> # on this runtime, such as `-C profile-generate` or `-C instrument-coverage`). > profiler = true > ``` @@ -65,9 +59,9 @@ $ ./x.py build rust-demangler ## Compiling with coverage enabled -Set the `-Z instrument-coverage` compiler flag in order to enable LLVM source-based code coverage profiling. +Set the `-C instrument-coverage` compiler flag in order to enable LLVM source-based code coverage profiling. -The default option generates coverage for all functions, including unused (never called) functions and generics. The compiler flag supports an optional value to tailor this behavior. (See [`-Z instrument-coverage=`](#-z-instrument-coverageoptions), below.) +The default option generates coverage for all functions, including unused (never called) functions and generics. The compiler flag supports an optional value to tailor this behavior. (See [`-C instrument-coverage=`](#-c-instrument-coverageoptions), below.) With `cargo`, you can instrument your program binary _and_ dependencies at the same time. @@ -76,18 +70,18 @@ For example (if your project's Cargo.toml builds a binary by default): ```shell $ cd your-project $ cargo clean -$ RUSTFLAGS="-Z instrument-coverage" cargo build +$ RUSTFLAGS="-C instrument-coverage" cargo build ``` If `cargo` is not configured to use your `profiler`-enabled version of `rustc`, set the path explicitly via the `RUSTC` environment variable. Here is another example, using a `stage1` build of `rustc` to compile an `example` binary (from the [`json5format`] crate): ```shell $ RUSTC=$HOME/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc \ - RUSTFLAGS="-Z instrument-coverage" \ + RUSTFLAGS="-C instrument-coverage" \ cargo build --example formatjson5 ``` -> **Note**: that some compiler options, combined with `-Z instrument-coverage`, can produce LLVM IR and/or linked binaries that are incompatible with LLVM coverage maps. For example, coverage requires references to actual functions in LLVM IR. If any covered function is optimized out, the coverage tools may not be able to process the coverage results. If you need to pass additional options, with coverage enabled, test them early, to confirm you will get the coverage results you expect. +> **Note**: that some compiler options, combined with `-C instrument-coverage`, can produce LLVM IR and/or linked binaries that are incompatible with LLVM coverage maps. For example, coverage requires references to actual functions in LLVM IR. If any covered function is optimized out, the coverage tools may not be able to process the coverage results. If you need to pass additional options, with coverage enabled, test them early, to confirm you will get the coverage results you expect. ## Running the instrumented binary to generate raw coverage profiling data @@ -176,7 +170,7 @@ Some of the more notable options in this example include: > **Note**: Coverage can also be disabled on an individual function by annotating the function with the [`no_coverage` attribute] (which requires the feature flag `#![feature(no_coverage)]`). -[`no_coverage` attribute]: ../language-features/no-coverage.md +[`no_coverage` attribute]: ../unstable-book/language-features/no-coverage.html ## Interpreting reports @@ -195,10 +189,10 @@ A typical use case for coverage analysis is test coverage. Rust's source-based c The following example (using the [`json5format`] crate, for demonstration purposes) show how to generate and analyze coverage results for all tests in a crate. -Since `cargo test` both builds and runs the tests, we set both the additional `RUSTFLAGS`, to add the `-Z instrument-coverage` flag, and `LLVM_PROFILE_FILE`, to set a custom filename for the raw profiling data generated during the test runs. Since there may be more than one test binary, apply `%m` in the filename pattern. This generates unique names for each test binary. (Otherwise, each executed test binary would overwrite the coverage results from the previous binary.) +Since `cargo test` both builds and runs the tests, we set both the additional `RUSTFLAGS`, to add the `-C instrument-coverage` flag, and `LLVM_PROFILE_FILE`, to set a custom filename for the raw profiling data generated during the test runs. Since there may be more than one test binary, apply `%m` in the filename pattern. This generates unique names for each test binary. (Otherwise, each executed test binary would overwrite the coverage results from the previous binary.) ```shell -$ RUSTFLAGS="-Z instrument-coverage" \ +$ RUSTFLAGS="-C instrument-coverage" \ LLVM_PROFILE_FILE="json5format-%m.profraw" \ cargo test --tests ``` @@ -256,7 +250,7 @@ $ cargo cov -- report \ $( \ for file in \ $( \ - RUSTFLAGS="-Z instrument-coverage" \ + RUSTFLAGS="-C instrument-coverage" \ cargo test --tests --no-run --message-format=json \ | jq -r "select(.profile.test == true) | .filenames[]" \ | grep -v dSYM - \ @@ -280,12 +274,12 @@ for each listed test binary. The previous examples run `cargo test` with `--tests`, which excludes doc tests.[^79417] To include doc tests in the coverage results, drop the `--tests` flag, and apply the -`-Z instrument-coverage` flag, and some doc-test-specific options in the +`-C instrument-coverage` flag, and some doc-test-specific options in the `RUSTDOCFLAGS` environment variable. (The `cargo profdata` command does not change.) ```bash -$ RUSTFLAGS="-Z instrument-coverage" \ - RUSTDOCFLAGS="-Z instrument-coverage -Z unstable-options --persist-doctests target/debug/doctestbins" \ +$ RUSTFLAGS="-C instrument-coverage" \ + RUSTDOCFLAGS="-C instrument-coverage -Z unstable-options --persist-doctests target/debug/doctestbins" \ LLVM_PROFILE_FILE="json5format-%m.profraw" \ cargo test $ cargo profdata -- merge \ @@ -300,8 +294,8 @@ $ cargo cov -- report \ $( \ for file in \ $( \ - RUSTFLAGS="-Z instrument-coverage" \ - RUSTDOCFLAGS="-Z instrument-coverage -Z unstable-options --persist-doctests target/debug/doctestbins" \ + RUSTFLAGS="-C instrument-coverage" \ + RUSTDOCFLAGS="-C instrument-coverage -Z unstable-options --persist-doctests target/debug/doctestbins" \ cargo test --no-run --message-format=json \ | jq -r "select(.profile.test == true) | .filenames[]" \ | grep -v dSYM - \ @@ -331,12 +325,12 @@ $ cargo cov -- report \ [(#79417)](https://github.com/rust-lang/rust/issues/79417) that doc test coverage generates incorrect source line numbers in `llvm-cov show` results. -## `-Z instrument-coverage=` +## `-C instrument-coverage=` -- `-Z instrument-coverage=all`: Instrument all functions, including unused functions and unused generics. (This is the same as `-Z instrument-coverage`, with no value.) -- `-Z instrument-coverage=except-unused-generics`: Instrument all functions except unused generics. -- `-Z instrument-coverage=except-unused-functions`: Instrument only used (called) functions and instantiated generic functions. -- `-Z instrument-coverage=off`: Do not instrument any functions. (This is the same as simply not including the `-Z instrument-coverage` option.) +- `-C instrument-coverage=all`: Instrument all functions, including unused functions and unused generics. (This is the same as `-C instrument-coverage`, with no value.) +- `-C instrument-coverage=except-unused-generics`: Instrument all functions except unused generics. +- `-C instrument-coverage=except-unused-functions`: Instrument only used (called) functions and instantiated generic functions. +- `-C instrument-coverage=off`: Do not instrument any functions. (This is the same as simply not including the `-C instrument-coverage` option.) ## Other references diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md deleted file mode 100644 index cb65978e0a0..00000000000 --- a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md +++ /dev/null @@ -1,5 +0,0 @@ -# `source-based-code-coverage` - -See compiler flag [`-Z instrument-coverage`]. - -[`-z instrument-coverage`]: ./instrument-coverage.html diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index ac24543929b..227553287a8 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -658,7 +658,7 @@ crate fn make_test( } else { let returns_result = everything_else.trim_end().ends_with("(())"); // Give each doctest main function a unique name. - // This is for example needed for the tooling around `-Z instrument-coverage`. + // This is for example needed for the tooling around `-C instrument-coverage`. let inner_fn_name = if let Some(test_id) = test_id { format!("_doctest_main_{}", test_id) } else { @@ -683,7 +683,7 @@ crate fn make_test( }; // Note on newlines: We insert a line/newline *before*, and *after* // the doctest and adjust the `line_offset` accordingly. - // In the case of `-Z instrument-coverage`, this means that the generated + // In the case of `-C instrument-coverage`, this means that the generated // inner `main` function spans from the doctest opening codeblock to the // closing one. For example // /// ``` <- start of the inner main diff --git a/src/test/mir-opt/coverage_graphviz.rs b/src/test/mir-opt/coverage_graphviz.rs index b3c90c52837..09403bb3a79 100644 --- a/src/test/mir-opt/coverage_graphviz.rs +++ b/src/test/mir-opt/coverage_graphviz.rs @@ -1,9 +1,9 @@ -// Test that `-Z instrument-coverage` with `-Z dump-mir-graphviz` generates a graphviz (.dot file) +// Test that `-C instrument-coverage` with `-Z dump-mir-graphviz` generates a graphviz (.dot file) // rendering of the `BasicCoverageBlock` coverage control flow graph, with counters and // expressions. // needs-profiler-support -// compile-flags: -Z instrument-coverage -Z dump-mir-graphviz +// compile-flags: -C instrument-coverage -Z dump-mir-graphviz // EMIT_MIR coverage_graphviz.main.InstrumentCoverage.0.dot // EMIT_MIR coverage_graphviz.bar.InstrumentCoverage.0.dot fn main() { diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs index 18863edac97..a748f2c5ccc 100644 --- a/src/test/mir-opt/instrument_coverage.rs +++ b/src/test/mir-opt/instrument_coverage.rs @@ -1,9 +1,9 @@ -// Test that `-Z instrument-coverage` injects Coverage statements. The Coverage Counter statements +// Test that `-C instrument-coverage` injects Coverage statements. The Coverage Counter statements // are later converted into LLVM instrprof.increment intrinsics, during codegen. // needs-profiler-support // ignore-windows -// compile-flags: -Z instrument-coverage --remap-path-prefix={{src-base}}=/the/src +// compile-flags: -C instrument-coverage --remap-path-prefix={{src-base}}=/the/src // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff diff --git a/src/test/run-make-fulldeps/coverage-llvmir/Makefile b/src/test/run-make-fulldeps/coverage-llvmir/Makefile index 3c4df3533e1..fbe0a5cb1bb 100644 --- a/src/test/run-make-fulldeps/coverage-llvmir/Makefile +++ b/src/test/run-make-fulldeps/coverage-llvmir/Makefile @@ -57,7 +57,7 @@ all: test_llvm_ir test_llvm_ir: # Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR $(RUSTC) $(BASEDIR)/testprog.rs \ - -Zinstrument-coverage \ + -Cinstrument-coverage \ --emit=llvm-ir cat "$(TMPDIR)"/testprog.ll | \ diff --git a/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt b/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt index 8e5f2104687..1e2ecc2fbb1 100644 --- a/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt +++ b/src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt @@ -1,5 +1,5 @@ # Check for metadata, variables, declarations, and function definitions injected -# into LLVM IR when compiling with -Zinstrument-coverage. +# into LLVM IR when compiling with -Cinstrument-coverage. WINDOWS: $__llvm_profile_runtime_user = comdat any diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile index 9122e0406c2..53e75ae337b 100644 --- a/src/test/run-make-fulldeps/coverage-reports/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports/Makefile @@ -81,13 +81,13 @@ endif # Compile the test library with coverage instrumentation $(RUSTC) $(SOURCEDIR)/lib/$@.rs \ $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \ - --crate-type rlib -Zinstrument-coverage + --crate-type rlib -Cinstrument-coverage %: $(SOURCEDIR)/%.rs # Compile the test program with coverage instrumentation $(RUSTC) $(SOURCEDIR)/$@.rs \ $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \ - -L "$(TMPDIR)" -Zinstrument-coverage + -L "$(TMPDIR)" -Cinstrument-coverage # Run it in order to generate some profiling data, # with `LLVM_PROFILE_FILE=` environment variable set to @@ -109,7 +109,7 @@ endif LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p-%m.profraw \ $(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \ $$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \ - -L "$(TMPDIR)" -Zinstrument-coverage \ + -L "$(TMPDIR)" -Cinstrument-coverage \ -Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@ # Postprocess the profiling data so it can be used by the llvm-cov tool diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt index 768dcb2f608..8d6a9eb902c 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt @@ -125,7 +125,7 @@ 78| |// generic functions with: 79| |// 80| |// ```shell - 81| |// $ `rustc -Z instrument-coverage=except-unused-generics ...` + 81| |// $ `rustc -C instrument-coverage=except-unused-generics ...` 82| |// ``` 83| |// 84| |// Even though this function is used by `uses_crate.rs` (and diff --git a/src/test/run-make-fulldeps/coverage/lib/used_crate.rs b/src/test/run-make-fulldeps/coverage/lib/used_crate.rs index eaa93115ae8..9c3b147ac59 100644 --- a/src/test/run-make-fulldeps/coverage/lib/used_crate.rs +++ b/src/test/run-make-fulldeps/coverage/lib/used_crate.rs @@ -78,7 +78,7 @@ fn use_this_lib_crate() { // generic functions with: // // ```shell -// $ `rustc -Z instrument-coverage=except-unused-generics ...` +// $ `rustc -C instrument-coverage=except-unused-generics ...` // ``` // // Even though this function is used by `uses_crate.rs` (and