summaryrefslogtreecommitdiffstats
path: root/tests/coverage/unreachable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/coverage/unreachable.rs')
-rw-r--r--tests/coverage/unreachable.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/coverage/unreachable.rs b/tests/coverage/unreachable.rs
new file mode 100644
index 000000000..6385bfa16
--- /dev/null
+++ b/tests/coverage/unreachable.rs
@@ -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();
+ }
+}