mirror of
https://github.com/rust-lang/rust
synced 2024-09-05 00:24:52 +00:00
coverage: Branch coverage tests for match arms
This commit is contained in:
parent
7f432dfb23
commit
3de87feba2
92
tests/coverage/branch/match-arms.cov-map
Normal file
92
tests/coverage/branch/match-arms.cov-map
Normal 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))))
|
||||
|
105
tests/coverage/branch/match-arms.coverage
Normal file
105
tests/coverage/branch/match-arms.coverage
Normal 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.
|
||||
|
90
tests/coverage/branch/match-arms.rs
Normal file
90
tests/coverage/branch/match-arms.rs
Normal 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.
|
17
tests/coverage/branch/match-trivial.cov-map
Normal file
17
tests/coverage/branch/match-trivial.cov-map
Normal 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)
|
||||
|
49
tests/coverage/branch/match-trivial.coverage
Normal file
49
tests/coverage/branch/match-trivial.coverage
Normal 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| |}
|
||||
|
48
tests/coverage/branch/match-trivial.rs
Normal file
48
tests/coverage/branch/match-trivial.rs
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue