Skip to content

Commit 2856753

Browse files
committed
coverage: Copy all remaining run-coverage tests into coverage-map
These multi-file tests were not copied over in rust-lang#114843 because they weren't working, but it turns out that they just need the correct crate-type.
1 parent a043f34 commit 2856753

13 files changed

+392
-1
lines changed

src/tools/compiletest/src/runtest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2193,7 +2193,7 @@ impl<'test> TestCx<'test> {
21932193
|| self.is_vxworks_pure_static()
21942194
|| self.config.target.contains("bpf")
21952195
|| !self.config.target_cfg().dynamic_linking
2196-
|| self.config.mode == RunCoverage
2196+
|| matches!(self.config.mode, CoverageMap | RunCoverage)
21972197
{
21982198
// We primarily compile all auxiliary libraries as dynamic libraries
21992199
// to avoid code size bloat and large binaries as much as possible
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
2+
3+
#![allow(dead_code)]
4+
5+
mod foo {
6+
#[inline(always)]
7+
pub fn called() {}
8+
9+
fn uncalled() {}
10+
}
11+
12+
pub mod bar {
13+
pub fn call_me() {
14+
super::foo::called();
15+
}
16+
}
17+
18+
pub mod baz {
19+
pub fn call_me() {
20+
super::foo::called();
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[allow(dead_code)]
2+
pub fn never_called_function() {
3+
println!("I am never called");
4+
}
+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#![allow(unused_assignments, unused_variables)]
2+
// Verify that coverage works with optimizations:
3+
// compile-flags: -C opt-level=3
4+
5+
use std::fmt::Debug;
6+
7+
pub fn used_function() {
8+
// Initialize test constants in a way that cannot be determined at compile time, to ensure
9+
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
10+
// dependent conditions.
11+
let is_true = std::env::args().len() == 1;
12+
let mut countdown = 0;
13+
if is_true {
14+
countdown = 10;
15+
}
16+
use_this_lib_crate();
17+
}
18+
19+
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
20+
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
21+
}
22+
// Expect for above function: `Unexecuted instantiation` (see below)
23+
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
24+
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
25+
}
26+
27+
pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
28+
println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
29+
}
30+
31+
pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
32+
println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
33+
}
34+
35+
pub fn unused_generic_function<T: Debug>(arg: T) {
36+
println!("unused_generic_function with {:?}", arg);
37+
}
38+
39+
pub fn unused_function() {
40+
let is_true = std::env::args().len() == 1;
41+
let mut countdown = 2;
42+
if !is_true {
43+
countdown = 20;
44+
}
45+
}
46+
47+
#[allow(dead_code)]
48+
fn unused_private_function() {
49+
let is_true = std::env::args().len() == 1;
50+
let mut countdown = 2;
51+
if !is_true {
52+
countdown = 20;
53+
}
54+
}
55+
56+
fn use_this_lib_crate() {
57+
used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
58+
used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
59+
"used from library used_crate.rs",
60+
);
61+
let some_vec = vec![5, 6, 7, 8];
62+
used_only_from_this_lib_crate_generic_function(some_vec);
63+
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
64+
}
65+
66+
// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
67+
// for example:
68+
//
69+
// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
70+
//
71+
// These notices appear when `llvm-cov` shows instantiations. This may be a
72+
// default option, but it can be suppressed with:
73+
//
74+
// ```shell
75+
// $ `llvm-cov show --show-instantiations=0 ...`
76+
// ```
77+
//
78+
// The notice is triggered because the function is unused by the library itself,
79+
// and when the library is compiled, a synthetic function is generated, so
80+
// unused function coverage can be reported. Coverage can be skipped for unused
81+
// generic functions with:
82+
//
83+
// ```shell
84+
// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
85+
// ```
86+
//
87+
// Even though this function is used by `uses_crate.rs` (and
88+
// counted), with substitutions for `T`, those instantiations are only generated
89+
// when the generic function is actually used (from the binary, not from this
90+
// library crate). So the test result shows coverage for all instantiated
91+
// versions and their generic type substitutions, plus the `Unexecuted
92+
// instantiation` message for the non-substituted version. This is valid, but
93+
// unfortunately a little confusing.
94+
//
95+
// The library crate has its own coverage map, and the only way to show unused
96+
// coverage of a generic function is to include the generic function in the
97+
// coverage map, marked as an "unused function". If the library were used by
98+
// another binary that never used this generic function, then it would be valid
99+
// to show the unused generic, with unknown substitution (`_`).
100+
//
101+
// The alternative is to exclude all generics from being included in the "unused
102+
// functions" list, which would then omit coverage results for
103+
// `unused_generic_function<T>()`, below.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#![allow(unused_assignments, unused_variables)]
2+
// Verify that coverage works with optimizations:
3+
// compile-flags: -C opt-level=3
4+
5+
use std::fmt::Debug;
6+
7+
pub fn used_function() {
8+
// Initialize test constants in a way that cannot be determined at compile time, to ensure
9+
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
10+
// dependent conditions.
11+
let is_true = std::env::args().len() == 1;
12+
let mut countdown = 0;
13+
if is_true {
14+
countdown = 10;
15+
}
16+
use_this_lib_crate();
17+
}
18+
19+
#[inline(always)]
20+
pub fn used_inline_function() {
21+
// Initialize test constants in a way that cannot be determined at compile time, to ensure
22+
// rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
23+
// dependent conditions.
24+
let is_true = std::env::args().len() == 1;
25+
let mut countdown = 0;
26+
if is_true {
27+
countdown = 10;
28+
}
29+
use_this_lib_crate();
30+
}
31+
32+
#[inline(always)]
33+
pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
34+
println!("used_only_from_bin_crate_generic_function with {:?}", arg);
35+
}
36+
// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
37+
38+
#[inline(always)]
39+
pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
40+
println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
41+
}
42+
43+
#[inline(always)]
44+
pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
45+
println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
46+
}
47+
48+
#[inline(always)]
49+
pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
50+
println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
51+
}
52+
53+
#[inline(always)]
54+
pub fn unused_generic_function<T: Debug>(arg: T) {
55+
println!("unused_generic_function with {:?}", arg);
56+
}
57+
58+
#[inline(always)]
59+
pub fn unused_function() {
60+
let is_true = std::env::args().len() == 1;
61+
let mut countdown = 2;
62+
if !is_true {
63+
countdown = 20;
64+
}
65+
}
66+
67+
#[inline(always)]
68+
#[allow(dead_code)]
69+
fn unused_private_function() {
70+
let is_true = std::env::args().len() == 1;
71+
let mut countdown = 2;
72+
if !is_true {
73+
countdown = 20;
74+
}
75+
}
76+
77+
fn use_this_lib_crate() {
78+
used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
79+
used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
80+
"used from library used_crate.rs",
81+
);
82+
let some_vec = vec![5, 6, 7, 8];
83+
used_only_from_this_lib_crate_generic_function(some_vec);
84+
used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
85+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Function name: issue_85461::main
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 03, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 2)
8+

tests/coverage-map/issue-85461.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
2+
3+
// aux-build:inline_always_with_dead_code.rs
4+
extern crate inline_always_with_dead_code;
5+
6+
use inline_always_with_dead_code::{bar, baz};
7+
8+
fn main() {
9+
bar::call_me();
10+
baz::call_me();
11+
}

tests/coverage-map/unused_mod.cov-map

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Function name: unused_mod::main
2+
Raw bytes (9): 0x[01, 02, 00, 01, 01, 04, 01, 02, 02]
3+
Number of files: 1
4+
- file 0 => global file 2
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 2)
8+
9+
Function name: unused_mod::unused_module::never_called_function (unused)
10+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 02, 01, 02, 02]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 0
14+
Number of file 0 mappings: 1
15+
- Code(Zero) at (prev + 2, 1) to (start + 2, 2)
16+

tests/coverage-map/unused_mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[path = "auxiliary/unused_mod_helper.rs"]
2+
mod unused_module;
3+
4+
fn main() {
5+
println!("hello world!");
6+
}

tests/coverage-map/uses_crate.cov-map

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Function name: used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 01, 02, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 27, 1) to (start + 2, 2)
8+
9+
Function name: used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
10+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 0
14+
Number of file 0 mappings: 1
15+
- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
16+
17+
Function name: used_crate::used_only_from_bin_crate_generic_function::<&str>
18+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 02, 02]
19+
Number of files: 1
20+
- file 0 => global file 1
21+
Number of expressions: 0
22+
Number of file 0 mappings: 1
23+
- Code(Counter(0)) at (prev + 19, 1) to (start + 2, 2)
24+
25+
Function name: used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
26+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 02, 02]
27+
Number of files: 1
28+
- file 0 => global file 1
29+
Number of expressions: 0
30+
Number of file 0 mappings: 1
31+
- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 2)
32+
33+
Function name: uses_crate::main
34+
Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 07, 02]
35+
Number of files: 1
36+
- file 0 => global file 2
37+
Number of expressions: 0
38+
Number of file 0 mappings: 1
39+
- Code(Counter(0)) at (prev + 12, 1) to (start + 7, 2)
40+

tests/coverage-map/uses_crate.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// This test was failing on Linux for a while due to #110393 somehow making
2+
// the unused functions not instrumented, but it seems to be fine now.
3+
4+
// Validates coverage now works with optimizations
5+
// compile-flags: -C opt-level=3
6+
7+
#![allow(unused_assignments, unused_variables)]
8+
9+
// aux-build:used_crate.rs
10+
extern crate used_crate;
11+
12+
fn main() {
13+
used_crate::used_function();
14+
let some_vec = vec![1, 2, 3, 4];
15+
used_crate::used_only_from_bin_crate_generic_function(&some_vec);
16+
used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
17+
used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
18+
used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Function name: used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 01, 02, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 44, 1) to (start + 2, 2)
8+
9+
Function name: used_inline_crate::used_inline_function
10+
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]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 2
14+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
15+
- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
16+
Number of file 0 mappings: 4
17+
- Code(Counter(0)) at (prev + 20, 1) to (start + 6, 15)
18+
- Code(Counter(1)) at (prev + 6, 16) to (start + 2, 6)
19+
- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
20+
= (c0 - c1)
21+
- Code(Expression(1, Add)) at (prev + 1, 5) to (start + 1, 2)
22+
= (c1 + (c0 - c1))
23+
24+
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>
25+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
26+
Number of files: 1
27+
- file 0 => global file 1
28+
Number of expressions: 0
29+
Number of file 0 mappings: 1
30+
- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
31+
32+
Function name: used_inline_crate::used_only_from_bin_crate_generic_function::<&str>
33+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 02, 02]
34+
Number of files: 1
35+
- file 0 => global file 1
36+
Number of expressions: 0
37+
Number of file 0 mappings: 1
38+
- Code(Counter(0)) at (prev + 33, 1) to (start + 2, 2)
39+
40+
Function name: used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>
41+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 01, 02, 02]
42+
Number of files: 1
43+
- file 0 => global file 1
44+
Number of expressions: 0
45+
Number of file 0 mappings: 1
46+
- Code(Counter(0)) at (prev + 49, 1) to (start + 2, 2)
47+
48+
Function name: uses_inline_crate::main
49+
Raw bytes (9): 0x[01, 02, 00, 01, 01, 0c, 01, 0a, 02]
50+
Number of files: 1
51+
- file 0 => global file 2
52+
Number of expressions: 0
53+
Number of file 0 mappings: 1
54+
- Code(Counter(0)) at (prev + 12, 1) to (start + 10, 2)
55+

0 commit comments

Comments
 (0)