Skip to content

Commit aded003

Browse files
committed
coverage: Branch coverage test for match arms
1 parent 9ff21b4 commit aded003

File tree

3 files changed

+285
-0
lines changed

3 files changed

+285
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
Function name: match_arms::guards
2+
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, 31, 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]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 8
6+
- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5)
7+
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
8+
- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3)
9+
- expression 3 operands: lhs = Zero, rhs = Counter(2)
10+
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(9)
11+
- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(8)
12+
- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(7)
13+
- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(6)
14+
Number of file 0 mappings: 12
15+
- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16)
16+
- Code(Counter(10)) at (prev + 3, 11) to (start + 0, 16)
17+
- Code(Counter(6)) at (prev + 1, 17) to (start + 0, 41)
18+
- Branch { true: Counter(6), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27)
19+
true = c6
20+
false = c2
21+
- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41)
22+
- Branch { true: Counter(7), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27)
23+
true = c7
24+
false = c3
25+
- Code(Counter(8)) at (prev + 1, 17) to (start + 0, 41)
26+
- Branch { true: Counter(8), false: Counter(4) } at (prev + 0, 23) to (start + 0, 27)
27+
true = c8
28+
false = c4
29+
- Code(Counter(9)) at (prev + 1, 17) to (start + 0, 41)
30+
- Branch { true: Counter(9), false: Counter(5) } at (prev + 0, 23) to (start + 0, 27)
31+
true = c9
32+
false = c5
33+
- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 24)
34+
= ((((Zero + c2) + c3) + c4) + c5)
35+
- Code(Expression(4, Add)) at (prev + 3, 5) to (start + 1, 2)
36+
= ((((((((Zero + c2) + c3) + c4) + c5) + c6) + c7) + c8) + c9)
37+
38+
Function name: match_arms::match_arms
39+
Raw bytes (51): 0x[01, 01, 06, 05, 07, 0b, 11, 09, 0d, 13, 02, 17, 09, 11, 0d, 07, 01, 19, 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]
40+
Number of files: 1
41+
- file 0 => global file 1
42+
Number of expressions: 6
43+
- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
44+
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
45+
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
46+
- expression 3 operands: lhs = Expression(4, Add), rhs = Expression(0, Sub)
47+
- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(2)
48+
- expression 5 operands: lhs = Counter(4), rhs = Counter(3)
49+
Number of file 0 mappings: 7
50+
- Code(Counter(0)) at (prev + 25, 1) to (start + 1, 16)
51+
- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
52+
- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 33)
53+
- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
54+
- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
55+
- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 33)
56+
= (c1 - ((c2 + c3) + c4))
57+
- Code(Expression(3, Add)) at (prev + 3, 5) to (start + 1, 2)
58+
= (((c4 + c3) + c2) + (c1 - ((c2 + c3) + c4)))
59+
60+
Function name: match_arms::or_patterns
61+
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, 26, 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]
62+
Number of files: 1
63+
- file 0 => global file 1
64+
Number of expressions: 13
65+
- expression 0 operands: lhs = Counter(4), rhs = Counter(3)
66+
- expression 1 operands: lhs = Counter(1), rhs = Expression(11, Add)
67+
- expression 2 operands: lhs = Expression(12, Add), rhs = Counter(4)
68+
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
69+
- expression 4 operands: lhs = Counter(2), rhs = Expression(10, Sub)
70+
- expression 5 operands: lhs = Counter(1), rhs = Expression(11, Add)
71+
- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(4)
72+
- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
73+
- expression 8 operands: lhs = Expression(0, Add), rhs = Expression(9, Add)
74+
- expression 9 operands: lhs = Counter(2), rhs = Expression(10, Sub)
75+
- expression 10 operands: lhs = Counter(1), rhs = Expression(11, Add)
76+
- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(4)
77+
- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
78+
Number of file 0 mappings: 9
79+
- Code(Counter(0)) at (prev + 38, 1) to (start + 1, 16)
80+
- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
81+
- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
82+
- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
83+
- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46)
84+
= (c4 + c3)
85+
- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
86+
- Code(Expression(10, Sub)) at (prev + 0, 30) to (start + 0, 31)
87+
= (c1 - ((c2 + c3) + c4))
88+
- Code(Expression(9, Add)) at (prev + 0, 36) to (start + 0, 46)
89+
= (c2 + (c1 - ((c2 + c3) + c4)))
90+
- Code(Expression(8, Add)) at (prev + 3, 5) to (start + 1, 2)
91+
= ((c4 + c3) + (c2 + (c1 - ((c2 + c3) + c4))))
92+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
LL| |#![feature(coverage_attribute)]
2+
LL| |//@ edition: 2021
3+
LL| |//@ compile-flags: -Zcoverage-options=branch
4+
LL| |//@ llvm-cov-flags: --show-branches=count
5+
LL| |
6+
LL| |// Tests for branch coverage of the lazy boolean operators `&&` and `||`,
7+
LL| |// as ordinary expressions that aren't part of an `if` condition or similar.
8+
LL| |
9+
LL| |// Helper macro to prevent start-of-function spans from being merged into
10+
LL| |// spans on the lines we care about.
11+
LL| |macro_rules! no_merge {
12+
LL| | () => {
13+
LL| | for _ in 0..1 {}
14+
LL| | };
15+
LL| |}
16+
LL| |
17+
LL| |#[derive(Clone, Copy, Debug)]
18+
LL| |enum Enum {
19+
LL| | A(u32),
20+
LL| | B(u32),
21+
LL| | C(u32),
22+
LL| | D(u32),
23+
LL| |}
24+
LL| |
25+
LL| 15|fn match_arms(value: Enum) {
26+
LL| 15| no_merge!();
27+
LL| |
28+
LL| 15| match value {
29+
LL| 8| Enum::D(d) => consume(d),
30+
LL| 4| Enum::C(c) => consume(c),
31+
LL| 2| Enum::B(b) => consume(b),
32+
LL| 1| Enum::A(a) => consume(a),
33+
LL| | }
34+
LL| |
35+
LL| 15| consume(0);
36+
LL| 15|}
37+
LL| |
38+
LL| 15|fn or_patterns(value: Enum) {
39+
LL| 15| no_merge!();
40+
LL| |
41+
LL| 15| match value {
42+
LL| 12| Enum::D(x) | Enum::C(x) => consume(x),
43+
^8 ^4
44+
LL| 3| Enum::B(y) | Enum::A(y) => consume(y),
45+
^2 ^1
46+
LL| | }
47+
LL| |
48+
LL| 15| consume(0);
49+
LL| 15|}
50+
LL| |
51+
LL| 45|fn guards(value: Enum, cond: bool) {
52+
LL| 45| no_merge!();
53+
LL| |
54+
LL| 3| match value {
55+
LL| 8| Enum::D(d) if cond => consume(d),
56+
------------------
57+
| Branch (LL:23): [True: 8, False: 16]
58+
------------------
59+
LL| 4| Enum::C(c) if cond => consume(c),
60+
------------------
61+
| Branch (LL:23): [True: 4, False: 8]
62+
------------------
63+
LL| 2| Enum::B(b) if cond => consume(b),
64+
------------------
65+
| Branch (LL:23): [True: 2, False: 4]
66+
------------------
67+
LL| 1| Enum::A(a) if cond => consume(a),
68+
------------------
69+
| Branch (LL:23): [True: 1, False: 2]
70+
------------------
71+
LL| 30| _ => consume(0),
72+
LL| | }
73+
LL| |
74+
LL| 45| consume(0);
75+
LL| 45|}
76+
LL| |
77+
LL| |#[coverage(off)]
78+
LL| |fn consume<T>(x: T) {
79+
LL| | core::hint::black_box(x);
80+
LL| |}
81+
LL| |
82+
LL| |#[coverage(off)]
83+
LL| |fn main() {
84+
LL| | #[coverage(off)]
85+
LL| | fn call_everything(e: Enum) {
86+
LL| | match_arms(e);
87+
LL| | or_patterns(e);
88+
LL| | for cond in [false, false, true] {
89+
LL| | guards(e, cond);
90+
LL| | }
91+
LL| | }
92+
LL| |
93+
LL| | call_everything(Enum::A(0));
94+
LL| | for b in 0..2 {
95+
LL| | call_everything(Enum::B(b));
96+
LL| | }
97+
LL| | for c in 0..4 {
98+
LL| | call_everything(Enum::C(c));
99+
LL| | }
100+
LL| | for d in 0..8 {
101+
LL| | call_everything(Enum::D(d));
102+
LL| | }
103+
LL| |}
104+

tests/coverage/branch/match-arms.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#![feature(coverage_attribute)]
2+
//@ edition: 2021
3+
//@ compile-flags: -Zcoverage-options=branch
4+
//@ llvm-cov-flags: --show-branches=count
5+
6+
// Tests for branch coverage of the lazy boolean operators `&&` and `||`,
7+
// as ordinary expressions that aren't part of an `if` condition or similar.
8+
9+
// Helper macro to prevent start-of-function spans from being merged into
10+
// spans on the lines we care about.
11+
macro_rules! no_merge {
12+
() => {
13+
for _ in 0..1 {}
14+
};
15+
}
16+
17+
#[derive(Clone, Copy, Debug)]
18+
enum Enum {
19+
A(u32),
20+
B(u32),
21+
C(u32),
22+
D(u32),
23+
}
24+
25+
fn match_arms(value: Enum) {
26+
no_merge!();
27+
28+
match value {
29+
Enum::D(d) => consume(d),
30+
Enum::C(c) => consume(c),
31+
Enum::B(b) => consume(b),
32+
Enum::A(a) => consume(a),
33+
}
34+
35+
consume(0);
36+
}
37+
38+
fn or_patterns(value: Enum) {
39+
no_merge!();
40+
41+
match value {
42+
Enum::D(x) | Enum::C(x) => consume(x),
43+
Enum::B(y) | Enum::A(y) => consume(y),
44+
}
45+
46+
consume(0);
47+
}
48+
49+
fn guards(value: Enum, cond: bool) {
50+
no_merge!();
51+
52+
match value {
53+
Enum::D(d) if cond => consume(d),
54+
Enum::C(c) if cond => consume(c),
55+
Enum::B(b) if cond => consume(b),
56+
Enum::A(a) if cond => consume(a),
57+
_ => consume(0),
58+
}
59+
60+
consume(0);
61+
}
62+
63+
#[coverage(off)]
64+
fn consume<T>(x: T) {
65+
core::hint::black_box(x);
66+
}
67+
68+
#[coverage(off)]
69+
fn main() {
70+
#[coverage(off)]
71+
fn call_everything(e: Enum) {
72+
match_arms(e);
73+
or_patterns(e);
74+
for cond in [false, false, true] {
75+
guards(e, cond);
76+
}
77+
}
78+
79+
call_everything(Enum::A(0));
80+
for b in 0..2 {
81+
call_everything(Enum::B(b));
82+
}
83+
for c in 0..4 {
84+
call_everything(Enum::C(c));
85+
}
86+
for d in 0..8 {
87+
call_everything(Enum::D(d));
88+
}
89+
}

0 commit comments

Comments
 (0)