coverage: Copy all remaining run-coverage tests into coverage-map

These multi-file tests were not copied over in #114843 because they weren't
working, but it turns out that they just need the correct crate-type.
This commit is contained in:
Zalathar 2023-10-28 21:29:37 +11:00
parent 4b76b97bc8
commit 211d4cee8e
13 changed files with 392 additions and 1 deletions

View File

@ -2193,7 +2193,7 @@ impl<'test> TestCx<'test> {
|| self.is_vxworks_pure_static()
|| self.config.target.contains("bpf")
|| !self.config.target_cfg().dynamic_linking
|| self.config.mode == RunCoverage
|| matches!(self.config.mode, CoverageMap | RunCoverage)
{
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible

View File

@ -0,0 +1,22 @@
// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
#![allow(dead_code)]
mod foo {
#[inline(always)]
pub fn called() {}
fn uncalled() {}
}
pub mod bar {
pub fn call_me() {
super::foo::called();
}
}
pub mod baz {
pub fn call_me() {
super::foo::called();
}
}

View File

@ -0,0 +1,4 @@
#[allow(dead_code)]
pub fn never_called_function() {
println!("I am never called");
}

View File

@ -0,0 +1,103 @@
#![allow(unused_assignments, unused_variables)]
// Verify that coverage works with optimizations:
// compile-flags: -C opt-level=3
use std::fmt::Debug;
pub fn used_function() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
// dependent conditions.
let is_true = std::env::args().len() == 1;
let mut countdown = 0;
if is_true {
countdown = 10;
}
use_this_lib_crate();
}
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
}
// Expect for above function: `Unexecuted instantiation` (see below)
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
}
pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
pub fn unused_generic_function<T: Debug>(arg: T) {
println!("unused_generic_function with {:?}", arg);
}
pub fn unused_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
#[allow(dead_code)]
fn unused_private_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
fn use_this_lib_crate() {
used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
"used from library used_crate.rs",
);
let some_vec = vec![5, 6, 7, 8];
used_only_from_this_lib_crate_generic_function(some_vec);
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
}
// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
// for example:
//
// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
//
// These notices appear when `llvm-cov` shows instantiations. This may be a
// default option, but it can be suppressed with:
//
// ```shell
// $ `llvm-cov show --show-instantiations=0 ...`
// ```
//
// The notice is triggered because the function is unused by the library itself,
// and when the library is compiled, a synthetic function is generated, so
// unused function coverage can be reported. Coverage can be skipped for unused
// generic functions with:
//
// ```shell
// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
// ```
//
// Even though this function is used by `uses_crate.rs` (and
// counted), with substitutions for `T`, those instantiations are only generated
// when the generic function is actually used (from the binary, not from this
// library crate). So the test result shows coverage for all instantiated
// versions and their generic type substitutions, plus the `Unexecuted
// instantiation` message for the non-substituted version. This is valid, but
// unfortunately a little confusing.
//
// The library crate has its own coverage map, and the only way to show unused
// coverage of a generic function is to include the generic function in the
// coverage map, marked as an "unused function". If the library were used by
// another binary that never used this generic function, then it would be valid
// to show the unused generic, with unknown substitution (`_`).
//
// The alternative is to exclude all generics from being included in the "unused
// functions" list, which would then omit coverage results for
// `unused_generic_function<T>()`, below.

View File

@ -0,0 +1,85 @@
#![allow(unused_assignments, unused_variables)]
// Verify that coverage works with optimizations:
// compile-flags: -C opt-level=3
use std::fmt::Debug;
pub fn used_function() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
// dependent conditions.
let is_true = std::env::args().len() == 1;
let mut countdown = 0;
if is_true {
countdown = 10;
}
use_this_lib_crate();
}
#[inline(always)]
pub fn used_inline_function() {
// Initialize test constants in a way that cannot be determined at compile time, to ensure
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
// dependent conditions.
let is_true = std::env::args().len() == 1;
let mut countdown = 0;
if is_true {
countdown = 10;
}
use_this_lib_crate();
}
#[inline(always)]
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
}
// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
#[inline(always)]
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn unused_generic_function<T: Debug>(arg: T) {
println!("unused_generic_function with {:?}", arg);
}
#[inline(always)]
pub fn unused_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
#[inline(always)]
#[allow(dead_code)]
fn unused_private_function() {
let is_true = std::env::args().len() == 1;
let mut countdown = 2;
if !is_true {
countdown = 20;
}
}
fn use_this_lib_crate() {
used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
"used from library used_crate.rs",
);
let some_vec = vec![5, 6, 7, 8];
used_only_from_this_lib_crate_generic_function(some_vec);
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
}

View File

@ -0,0 +1,8 @@
Function name: issue_85461::main
Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)

View File

@ -0,0 +1,11 @@
// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
// aux-build:inline_always_with_dead_code.rs
extern crate inline_always_with_dead_code;
use inline_always_with_dead_code::{bar, baz};
fn main() {
bar::call_me();
baz::call_me();
}

View File

@ -0,0 +1,16 @@
Function name: unused_mod::main
Raw bytes (9): 0x[01, 02, 00, 01, 01, 04, 01, 02, 02]
Number of files: 1
- file 0 => global file 2
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2)
Function name: unused_mod::unused_module::never_called_function (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 02, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 2, 1) to (start + 2, 2)

View File

@ -0,0 +1,6 @@
#[path = "auxiliary/unused_mod_helper.rs"]
mod unused_module;
fn main() {
println!("hello world!");
}

View File

@ -0,0 +1,40 @@
Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2)
Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
Function name: used_crate::used_only_from_bin_crate_generic_function::<&str>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2)
Function name: uses_crate::main
Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02]
Number of files: 1
- file 0 => global file 2
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2)

View File

@ -0,0 +1,19 @@
// This test was failing on Linux for a while due to #110393 somehow making
// the unused functions not instrumented, but it seems to be fine now.
// Validates coverage now works with optimizations
// compile-flags: -C opt-level=3
#![allow(unused_assignments, unused_variables)]
// aux-build:used_crate.rs
extern crate used_crate;
fn main() {
used_crate::used_function();
let some_vec = vec![1, 2, 3, 4];
used_crate::used_only_from_bin_crate_generic_function(&some_vec);
used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
}

View File

@ -0,0 +1,55 @@
Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2)
Function name: used_inline_crate::used_inline_function
Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 06, 00, 07, 07, 01, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 2
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 20, 1) to (start + 6, 15)
- Code(Counter(1)) at (prev + 6, 16) to (start + 2, 6)
- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
= (c0 - c1)
- Code(Expression(1, Add)) at (prev + 1, 5) to (start + 1, 2)
= (c1 + (c0 - c1))
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2)
Function name: uses_inline_crate::main
Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02]
Number of files: 1
- file 0 => global file 2
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2)

View File

@ -0,0 +1,22 @@
// This test was failing on Linux for a while due to #110393 somehow making
// the unused functions not instrumented, but it seems to be fine now.
// Validates coverage now works with optimizations
// compile-flags: -C opt-level=3
#![allow(unused_assignments, unused_variables)]
// aux-build:used_inline_crate.rs
extern crate used_inline_crate;
fn main() {
used_inline_crate::used_function();
used_inline_crate::used_inline_function();
let some_vec = vec![1, 2, 3, 4];
used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
"interesting?",
);
}