coverage: Branch coverage tests for match arms

This commit is contained in:
Zalathar 2024-04-17 12:32:11 +10:00
parent 7f432dfb23
commit 3de87feba2
6 changed files with 401 additions and 0 deletions

View file

@ -0,0 +1,92 @@
Function name: match_arms::guards
Raw bytes (88): 0x[01, 01, 08, 07, 15, 0b, 11, 0f, 0d, 00, 09, 17, 25, 1b, 21, 1f, 1d, 03, 19, 0c, 01, 30, 01, 01, 10, 29, 03, 0b, 00, 10, 19, 01, 11, 00, 29, 20, 19, 09, 00, 17, 00, 1b, 1d, 01, 11, 00, 29, 20, 1d, 0d, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 11, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 15, 00, 17, 00, 1b, 03, 01, 0e, 00, 18, 13, 03, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 8
- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5)
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3)
- expression 3 operands: lhs = Zero, rhs = Counter(2)
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(9)
- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(8)
- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(7)
- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(6)
Number of file 0 mappings: 12
- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16)
- Code(Counter(10)) at (prev + 3, 11) to (start + 0, 16)
- Code(Counter(6)) at (prev + 1, 17) to (start + 0, 41)
- Branch { true: Counter(6), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27)
true = c6
false = c2
- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41)
- Branch { true: Counter(7), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27)
true = c7
false = c3
- Code(Counter(8)) at (prev + 1, 17) to (start + 0, 41)
- Branch { true: Counter(8), false: Counter(4) } at (prev + 0, 23) to (start + 0, 27)
true = c8
false = c4
- Code(Counter(9)) at (prev + 1, 17) to (start + 0, 41)
- Branch { true: Counter(9), false: Counter(5) } at (prev + 0, 23) to (start + 0, 27)
true = c9
false = c5
- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 24)
= ((((Zero + c2) + c3) + c4) + c5)
- Code(Expression(4, Add)) at (prev + 3, 5) to (start + 1, 2)
= ((((((((Zero + c2) + c3) + c4) + c5) + c6) + c7) + c8) + c9)
Function name: match_arms::match_arms
Raw bytes (51): 0x[01, 01, 06, 05, 07, 0b, 11, 09, 0d, 13, 02, 17, 09, 11, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 09, 01, 11, 00, 21, 02, 01, 11, 00, 21, 0f, 03, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 6
- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
- expression 3 operands: lhs = Expression(4, Add), rhs = Expression(0, Sub)
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(2)
- expression 5 operands: lhs = Counter(4), rhs = Counter(3)
Number of file 0 mappings: 7
- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 16)
- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 33)
- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 33)
= (c1 - ((c2 + c3) + c4))
- Code(Expression(3, Add)) at (prev + 3, 5) to (start + 1, 2)
= (((c4 + c3) + c2) + (c1 - ((c2 + c3) + c4)))
Function name: match_arms::or_patterns
Raw bytes (75): 0x[01, 01, 0d, 11, 0d, 05, 2f, 33, 11, 09, 0d, 09, 2a, 05, 2f, 33, 11, 09, 0d, 03, 27, 09, 2a, 05, 2f, 33, 11, 09, 0d, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 09, 01, 11, 00, 12, 2a, 00, 1e, 00, 1f, 27, 00, 24, 00, 2e, 23, 03, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 13
- expression 0 operands: lhs = Counter(4), rhs = Counter(3)
- expression 1 operands: lhs = Counter(1), rhs = Expression(11, Add)
- expression 2 operands: lhs = Expression(12, Add), rhs = Counter(4)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
- expression 4 operands: lhs = Counter(2), rhs = Expression(10, Sub)
- expression 5 operands: lhs = Counter(1), rhs = Expression(11, Add)
- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(4)
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
- expression 8 operands: lhs = Expression(0, Add), rhs = Expression(9, Add)
- expression 9 operands: lhs = Counter(2), rhs = Expression(10, Sub)
- expression 10 operands: lhs = Counter(1), rhs = Expression(11, Add)
- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(4)
- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
Number of file 0 mappings: 9
- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 16)
- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46)
= (c4 + c3)
- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
- Code(Expression(10, Sub)) at (prev + 0, 30) to (start + 0, 31)
= (c1 - ((c2 + c3) + c4))
- Code(Expression(9, Add)) at (prev + 0, 36) to (start + 0, 46)
= (c2 + (c1 - ((c2 + c3) + c4)))
- Code(Expression(8, Add)) at (prev + 3, 5) to (start + 1, 2)
= ((c4 + c3) + (c2 + (c1 - ((c2 + c3) + c4))))

View file

@ -0,0 +1,105 @@
LL| |#![feature(coverage_attribute)]
LL| |//@ edition: 2021
LL| |//@ compile-flags: -Zcoverage-options=branch
LL| |//@ llvm-cov-flags: --show-branches=count
LL| |
LL| |// Tests for branch coverage of various kinds of match arms.
LL| |
LL| |// Helper macro to prevent start-of-function spans from being merged into
LL| |// spans on the lines we care about.
LL| |macro_rules! no_merge {
LL| | () => {
LL| | for _ in 0..1 {}
LL| | };
LL| |}
LL| |
LL| |#[derive(Clone, Copy, Debug)]
LL| |enum Enum {
LL| | A(u32),
LL| | B(u32),
LL| | C(u32),
LL| | D(u32),
LL| |}
LL| |
LL| 15|fn match_arms(value: Enum) {
LL| 15| no_merge!();
LL| |
LL| 15| match value {
LL| 8| Enum::D(d) => consume(d),
LL| 4| Enum::C(c) => consume(c),
LL| 2| Enum::B(b) => consume(b),
LL| 1| Enum::A(a) => consume(a),
LL| | }
LL| |
LL| 15| consume(0);
LL| 15|}
LL| |
LL| 15|fn or_patterns(value: Enum) {
LL| 15| no_merge!();
LL| |
LL| 15| match value {
LL| 12| Enum::D(x) | Enum::C(x) => consume(x),
^8 ^4
LL| 3| Enum::B(y) | Enum::A(y) => consume(y),
^2 ^1
LL| | }
LL| |
LL| 15| consume(0);
LL| 15|}
LL| |
LL| 45|fn guards(value: Enum, cond: bool) {
LL| 45| no_merge!();
LL| |
LL| 3| match value {
LL| 8| Enum::D(d) if cond => consume(d),
------------------
| Branch (LL:23): [True: 8, False: 16]
------------------
LL| 4| Enum::C(c) if cond => consume(c),
------------------
| Branch (LL:23): [True: 4, False: 8]
------------------
LL| 2| Enum::B(b) if cond => consume(b),
------------------
| Branch (LL:23): [True: 2, False: 4]
------------------
LL| 1| Enum::A(a) if cond => consume(a),
------------------
| Branch (LL:23): [True: 1, False: 2]
------------------
LL| 30| _ => consume(0),
LL| | }
LL| |
LL| 45| consume(0);
LL| 45|}
LL| |
LL| |#[coverage(off)]
LL| |fn consume<T>(x: T) {
LL| | core::hint::black_box(x);
LL| |}
LL| |
LL| |#[coverage(off)]
LL| |fn main() {
LL| | #[coverage(off)]
LL| | fn call_everything(e: Enum) {
LL| | match_arms(e);
LL| | or_patterns(e);
LL| | for cond in [false, false, true] {
LL| | guards(e, cond);
LL| | }
LL| | }
LL| |
LL| | call_everything(Enum::A(0));
LL| | for b in 0..2 {
LL| | call_everything(Enum::B(b));
LL| | }
LL| | for c in 0..4 {
LL| | call_everything(Enum::C(c));
LL| | }
LL| | for d in 0..8 {
LL| | call_everything(Enum::D(d));
LL| | }
LL| |}
LL| |
LL| |// FIXME(#124118) Actually instrument match arms for branch coverage.

View file

@ -0,0 +1,90 @@
#![feature(coverage_attribute)]
//@ edition: 2021
//@ compile-flags: -Zcoverage-options=branch
//@ llvm-cov-flags: --show-branches=count
// Tests for branch coverage of various kinds of match arms.
// Helper macro to prevent start-of-function spans from being merged into
// spans on the lines we care about.
macro_rules! no_merge {
() => {
for _ in 0..1 {}
};
}
#[derive(Clone, Copy, Debug)]
enum Enum {
A(u32),
B(u32),
C(u32),
D(u32),
}
fn match_arms(value: Enum) {
no_merge!();
match value {
Enum::D(d) => consume(d),
Enum::C(c) => consume(c),
Enum::B(b) => consume(b),
Enum::A(a) => consume(a),
}
consume(0);
}
fn or_patterns(value: Enum) {
no_merge!();
match value {
Enum::D(x) | Enum::C(x) => consume(x),
Enum::B(y) | Enum::A(y) => consume(y),
}
consume(0);
}
fn guards(value: Enum, cond: bool) {
no_merge!();
match value {
Enum::D(d) if cond => consume(d),
Enum::C(c) if cond => consume(c),
Enum::B(b) if cond => consume(b),
Enum::A(a) if cond => consume(a),
_ => consume(0),
}
consume(0);
}
#[coverage(off)]
fn consume<T>(x: T) {
core::hint::black_box(x);
}
#[coverage(off)]
fn main() {
#[coverage(off)]
fn call_everything(e: Enum) {
match_arms(e);
or_patterns(e);
for cond in [false, false, true] {
guards(e, cond);
}
}
call_everything(Enum::A(0));
for b in 0..2 {
call_everything(Enum::B(b));
}
for c in 0..4 {
call_everything(Enum::C(c));
}
for d in 0..8 {
call_everything(Enum::D(d));
}
}
// FIXME(#124118) Actually instrument match arms for branch coverage.

View file

@ -0,0 +1,17 @@
Function name: match_trivial::_uninhabited (unused)
Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 10]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 1
- Code(Zero) at (prev + 22, 1) to (start + 1, 16)
Function name: match_trivial::trivial
Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 05, 03, 0b, 05, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
- Code(Counter(1)) at (prev + 3, 11) to (start + 5, 2)

View file

@ -0,0 +1,49 @@
LL| |#![feature(coverage_attribute)]
LL| |//@ edition: 2021
LL| |//@ compile-flags: -Zcoverage-options=branch
LL| |//@ llvm-cov-flags: --show-branches=count
LL| |
LL| |// When instrumenting match expressions for branch coverage, make sure we don't
LL| |// cause an ICE or produce weird coverage output for matches with <2 arms.
LL| |
LL| |// Helper macro to prevent start-of-function spans from being merged into
LL| |// spans on the lines we care about.
LL| |macro_rules! no_merge {
LL| | () => {
LL| | for _ in 0..1 {}
LL| | };
LL| |}
LL| |
LL| |enum Uninhabited {}
LL| |enum Trivial {
LL| | Value,
LL| |}
LL| |
LL| 0|fn _uninhabited(x: Uninhabited) {
LL| 0| no_merge!();
LL| |
LL| | match x {}
LL| |
LL| | consume("done");
LL| |}
LL| |
LL| 1|fn trivial(x: Trivial) {
LL| 1| no_merge!();
LL| |
LL| 1| match x {
LL| 1| Trivial::Value => consume("trivial"),
LL| 1| }
LL| 1|
LL| 1| consume("done");
LL| 1|}
LL| |
LL| |#[coverage(off)]
LL| |fn consume<T>(x: T) {
LL| | core::hint::black_box(x);
LL| |}
LL| |
LL| |#[coverage(off)]
LL| |fn main() {
LL| | trivial(Trivial::Value);
LL| |}

View file

@ -0,0 +1,48 @@
#![feature(coverage_attribute)]
//@ edition: 2021
//@ compile-flags: -Zcoverage-options=branch
//@ llvm-cov-flags: --show-branches=count
// When instrumenting match expressions for branch coverage, make sure we don't
// cause an ICE or produce weird coverage output for matches with <2 arms.
// Helper macro to prevent start-of-function spans from being merged into
// spans on the lines we care about.
macro_rules! no_merge {
() => {
for _ in 0..1 {}
};
}
enum Uninhabited {}
enum Trivial {
Value,
}
fn _uninhabited(x: Uninhabited) {
no_merge!();
match x {}
consume("done");
}
fn trivial(x: Trivial) {
no_merge!();
match x {
Trivial::Value => consume("trivial"),
}
consume("done");
}
#[coverage(off)]
fn consume<T>(x: T) {
core::hint::black_box(x);
}
#[coverage(off)]
fn main() {
trivial(Trivial::Value);
}