Skip to content

Commit

Permalink
coverage: Regression test for functions with unreachable bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalathar committed Oct 1, 2023
1 parent b11431e commit 3de0824
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
24 changes: 24 additions & 0 deletions tests/coverage-map/unreachable.cov-map
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0}
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 27, 00, 49]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Counter(0)) at (prev + 15, 39) to (start + 0, 73)

Function name: unreachable::unreachable_function
Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 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 + 17, 1) to (start + 2, 2)

Function name: unreachable::unreachable_intrinsic
Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 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 + 22, 1) to (start + 2, 2)

37 changes: 37 additions & 0 deletions tests/coverage-map/unreachable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#![feature(core_intrinsics)]
#![feature(coverage_attribute)]
// compile-flags: --edition=2021

// <https://github.com/rust-lang/rust/issues/116171>
// If we instrument a function for coverage, but all of its counter-increment
// statements are removed by MIR optimizations, LLVM will think it isn't
// instrumented and it will disappear from coverage maps and coverage reports.
// Most MIR opts won't cause this because they tend not to remove statements
// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends
// with `TerminatorKind::Unreachable`.

use std::hint::{black_box, unreachable_unchecked};

static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() };

fn unreachable_function() {
unsafe { unreachable_unchecked() }
}

// Use an intrinsic to more reliably trigger unreachable-propagation.
fn unreachable_intrinsic() {
unsafe { std::intrinsics::unreachable() }
}

#[coverage(off)]
fn main() {
if black_box(false) {
UNREACHABLE_CLOSURE();
}
if black_box(false) {
unreachable_function();
}
if black_box(false) {
unreachable_intrinsic();
}
}
38 changes: 38 additions & 0 deletions tests/run-coverage/unreachable.coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
LL| |#![feature(core_intrinsics)]
LL| |#![feature(coverage_attribute)]
LL| |// compile-flags: --edition=2021
LL| |
LL| |// <https://github.com/rust-lang/rust/issues/116171>
LL| |// If we instrument a function for coverage, but all of its counter-increment
LL| |// statements are removed by MIR optimizations, LLVM will think it isn't
LL| |// instrumented and it will disappear from coverage maps and coverage reports.
LL| |// Most MIR opts won't cause this because they tend not to remove statements
LL| |// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends
LL| |// with `TerminatorKind::Unreachable`.
LL| |
LL| |use std::hint::{black_box, unreachable_unchecked};
LL| |
LL| 0|static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() };
LL| |
LL| 0|fn unreachable_function() {
LL| 0| unsafe { unreachable_unchecked() }
LL| 0|}
LL| |
LL| |// Use an intrinsic to more reliably trigger unreachable-propagation.
LL| 0|fn unreachable_intrinsic() {
LL| 0| unsafe { std::intrinsics::unreachable() }
LL| 0|}
LL| |
LL| |#[coverage(off)]
LL| |fn main() {
LL| | if black_box(false) {
LL| | UNREACHABLE_CLOSURE();
LL| | }
LL| | if black_box(false) {
LL| | unreachable_function();
LL| | }
LL| | if black_box(false) {
LL| | unreachable_intrinsic();
LL| | }
LL| |}

37 changes: 37 additions & 0 deletions tests/run-coverage/unreachable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#![feature(core_intrinsics)]
#![feature(coverage_attribute)]
// compile-flags: --edition=2021

// <https://github.com/rust-lang/rust/issues/116171>
// If we instrument a function for coverage, but all of its counter-increment
// statements are removed by MIR optimizations, LLVM will think it isn't
// instrumented and it will disappear from coverage maps and coverage reports.
// Most MIR opts won't cause this because they tend not to remove statements
// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends
// with `TerminatorKind::Unreachable`.

use std::hint::{black_box, unreachable_unchecked};

static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() };

fn unreachable_function() {
unsafe { unreachable_unchecked() }
}

// Use an intrinsic to more reliably trigger unreachable-propagation.
fn unreachable_intrinsic() {
unsafe { std::intrinsics::unreachable() }
}

#[coverage(off)]
fn main() {
if black_box(false) {
UNREACHABLE_CLOSURE();
}
if black_box(false) {
unreachable_function();
}
if black_box(false) {
unreachable_intrinsic();
}
}

0 comments on commit 3de0824

Please sign in to comment.