Skip to content

Commit 34a1828

Browse files
committed
coverage: Add tests for the MC/DC condition limit
1 parent 7845c6e commit 34a1828

File tree

5 files changed

+310
-0
lines changed

5 files changed

+310
-0
lines changed
+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
Function name: condition_limit::bad
2+
Raw bytes (204): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 11, 01, 14, 01, 03, 09, 20, 05, 02, 03, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 7a, 1d, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 20, 76, 19, 00, 12, 00, 13, 76, 00, 17, 00, 18, 20, 72, 15, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 20, 6e, 11, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 20, 6a, 0d, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 20, 21, 09, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 06, 00, 07, 97, 01, 01, 01, 00, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 44
6+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
7+
- expression 1 operands: lhs = Counter(1), rhs = Counter(7)
8+
- expression 2 operands: lhs = Counter(1), rhs = Counter(7)
9+
- expression 3 operands: lhs = Expression(30, Sub), rhs = Counter(6)
10+
- expression 4 operands: lhs = Counter(1), rhs = Counter(7)
11+
- expression 5 operands: lhs = Expression(30, Sub), rhs = Counter(6)
12+
- expression 6 operands: lhs = Counter(1), rhs = Counter(7)
13+
- expression 7 operands: lhs = Expression(29, Sub), rhs = Counter(5)
14+
- expression 8 operands: lhs = Expression(30, Sub), rhs = Counter(6)
15+
- expression 9 operands: lhs = Counter(1), rhs = Counter(7)
16+
- expression 10 operands: lhs = Expression(29, Sub), rhs = Counter(5)
17+
- expression 11 operands: lhs = Expression(30, Sub), rhs = Counter(6)
18+
- expression 12 operands: lhs = Counter(1), rhs = Counter(7)
19+
- expression 13 operands: lhs = Expression(28, Sub), rhs = Counter(4)
20+
- expression 14 operands: lhs = Expression(29, Sub), rhs = Counter(5)
21+
- expression 15 operands: lhs = Expression(30, Sub), rhs = Counter(6)
22+
- expression 16 operands: lhs = Counter(1), rhs = Counter(7)
23+
- expression 17 operands: lhs = Expression(28, Sub), rhs = Counter(4)
24+
- expression 18 operands: lhs = Expression(29, Sub), rhs = Counter(5)
25+
- expression 19 operands: lhs = Expression(30, Sub), rhs = Counter(6)
26+
- expression 20 operands: lhs = Counter(1), rhs = Counter(7)
27+
- expression 21 operands: lhs = Expression(27, Sub), rhs = Counter(3)
28+
- expression 22 operands: lhs = Expression(28, Sub), rhs = Counter(4)
29+
- expression 23 operands: lhs = Expression(29, Sub), rhs = Counter(5)
30+
- expression 24 operands: lhs = Expression(30, Sub), rhs = Counter(6)
31+
- expression 25 operands: lhs = Counter(1), rhs = Counter(7)
32+
- expression 26 operands: lhs = Expression(27, Sub), rhs = Counter(3)
33+
- expression 27 operands: lhs = Expression(28, Sub), rhs = Counter(4)
34+
- expression 28 operands: lhs = Expression(29, Sub), rhs = Counter(5)
35+
- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(6)
36+
- expression 30 operands: lhs = Counter(1), rhs = Counter(7)
37+
- expression 31 operands: lhs = Expression(39, Add), rhs = Expression(0, Sub)
38+
- expression 32 operands: lhs = Expression(40, Add), rhs = Counter(7)
39+
- expression 33 operands: lhs = Expression(41, Add), rhs = Counter(6)
40+
- expression 34 operands: lhs = Expression(42, Add), rhs = Counter(5)
41+
- expression 35 operands: lhs = Expression(43, Add), rhs = Counter(4)
42+
- expression 36 operands: lhs = Counter(2), rhs = Counter(3)
43+
- expression 37 operands: lhs = Counter(8), rhs = Expression(38, Add)
44+
- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(0, Sub)
45+
- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(7)
46+
- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(6)
47+
- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(5)
48+
- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4)
49+
- expression 43 operands: lhs = Counter(2), rhs = Counter(3)
50+
Number of file 0 mappings: 17
51+
- Code(Counter(0)) at (prev + 20, 1) to (start + 3, 9)
52+
- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 3, 8) to (start + 0, 9)
53+
true = c1
54+
false = (c0 - c1)
55+
- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
56+
- Branch { true: Expression(30, Sub), false: Counter(7) } at (prev + 0, 13) to (start + 0, 14)
57+
true = (c1 - c7)
58+
false = c7
59+
- Code(Expression(30, Sub)) at (prev + 0, 18) to (start + 0, 19)
60+
= (c1 - c7)
61+
- Branch { true: Expression(29, Sub), false: Counter(6) } at (prev + 0, 18) to (start + 0, 19)
62+
true = ((c1 - c7) - c6)
63+
false = c6
64+
- Code(Expression(29, Sub)) at (prev + 0, 23) to (start + 0, 24)
65+
= ((c1 - c7) - c6)
66+
- Branch { true: Expression(28, Sub), false: Counter(5) } at (prev + 0, 23) to (start + 0, 24)
67+
true = (((c1 - c7) - c6) - c5)
68+
false = c5
69+
- Code(Expression(28, Sub)) at (prev + 0, 28) to (start + 0, 29)
70+
= (((c1 - c7) - c6) - c5)
71+
- Branch { true: Expression(27, Sub), false: Counter(4) } at (prev + 0, 28) to (start + 0, 29)
72+
true = ((((c1 - c7) - c6) - c5) - c4)
73+
false = c4
74+
- Code(Expression(27, Sub)) at (prev + 0, 33) to (start + 0, 34)
75+
= ((((c1 - c7) - c6) - c5) - c4)
76+
- Branch { true: Expression(26, Sub), false: Counter(3) } at (prev + 0, 33) to (start + 0, 34)
77+
true = (((((c1 - c7) - c6) - c5) - c4) - c3)
78+
false = c3
79+
- Code(Expression(26, Sub)) at (prev + 0, 38) to (start + 0, 39)
80+
= (((((c1 - c7) - c6) - c5) - c4) - c3)
81+
- Branch { true: Counter(8), false: Counter(2) } at (prev + 0, 38) to (start + 0, 39)
82+
true = c8
83+
false = c2
84+
- Code(Counter(8)) at (prev + 0, 40) to (start + 2, 6)
85+
- Code(Expression(38, Add)) at (prev + 2, 6) to (start + 0, 7)
86+
= ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1))
87+
- Code(Expression(37, Add)) at (prev + 1, 1) to (start + 0, 2)
88+
= (c8 + ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1)))
89+
90+
Function name: condition_limit::good
91+
Raw bytes (180): 0x[01, 01, 20, 01, 05, 05, 19, 05, 19, 52, 15, 05, 19, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 1d, 6f, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 10, 01, 0c, 01, 03, 09, 28, 00, 06, 03, 08, 00, 22, 30, 05, 02, 01, 06, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 52, 19, 06, 05, 00, 00, 0d, 00, 0e, 52, 00, 12, 00, 13, 30, 4e, 15, 05, 04, 00, 00, 12, 00, 13, 4e, 00, 17, 00, 18, 30, 4a, 11, 04, 03, 00, 00, 17, 00, 18, 4a, 00, 1c, 00, 1d, 30, 46, 0d, 03, 02, 00, 00, 1c, 00, 1d, 46, 00, 21, 00, 22, 30, 1d, 09, 02, 00, 00, 00, 21, 00, 22, 1d, 00, 23, 02, 06, 6f, 02, 06, 00, 07, 6b, 01, 01, 00, 02]
92+
Number of files: 1
93+
- file 0 => global file 1
94+
Number of expressions: 32
95+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
96+
- expression 1 operands: lhs = Counter(1), rhs = Counter(6)
97+
- expression 2 operands: lhs = Counter(1), rhs = Counter(6)
98+
- expression 3 operands: lhs = Expression(20, Sub), rhs = Counter(5)
99+
- expression 4 operands: lhs = Counter(1), rhs = Counter(6)
100+
- expression 5 operands: lhs = Expression(20, Sub), rhs = Counter(5)
101+
- expression 6 operands: lhs = Counter(1), rhs = Counter(6)
102+
- expression 7 operands: lhs = Expression(19, Sub), rhs = Counter(4)
103+
- expression 8 operands: lhs = Expression(20, Sub), rhs = Counter(5)
104+
- expression 9 operands: lhs = Counter(1), rhs = Counter(6)
105+
- expression 10 operands: lhs = Expression(19, Sub), rhs = Counter(4)
106+
- expression 11 operands: lhs = Expression(20, Sub), rhs = Counter(5)
107+
- expression 12 operands: lhs = Counter(1), rhs = Counter(6)
108+
- expression 13 operands: lhs = Expression(18, Sub), rhs = Counter(3)
109+
- expression 14 operands: lhs = Expression(19, Sub), rhs = Counter(4)
110+
- expression 15 operands: lhs = Expression(20, Sub), rhs = Counter(5)
111+
- expression 16 operands: lhs = Counter(1), rhs = Counter(6)
112+
- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(3)
113+
- expression 18 operands: lhs = Expression(19, Sub), rhs = Counter(4)
114+
- expression 19 operands: lhs = Expression(20, Sub), rhs = Counter(5)
115+
- expression 20 operands: lhs = Counter(1), rhs = Counter(6)
116+
- expression 21 operands: lhs = Expression(28, Add), rhs = Expression(0, Sub)
117+
- expression 22 operands: lhs = Expression(29, Add), rhs = Counter(6)
118+
- expression 23 operands: lhs = Expression(30, Add), rhs = Counter(5)
119+
- expression 24 operands: lhs = Expression(31, Add), rhs = Counter(4)
120+
- expression 25 operands: lhs = Counter(2), rhs = Counter(3)
121+
- expression 26 operands: lhs = Counter(7), rhs = Expression(27, Add)
122+
- expression 27 operands: lhs = Expression(28, Add), rhs = Expression(0, Sub)
123+
- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(6)
124+
- expression 29 operands: lhs = Expression(30, Add), rhs = Counter(5)
125+
- expression 30 operands: lhs = Expression(31, Add), rhs = Counter(4)
126+
- expression 31 operands: lhs = Counter(2), rhs = Counter(3)
127+
Number of file 0 mappings: 16
128+
- Code(Counter(0)) at (prev + 12, 1) to (start + 3, 9)
129+
- MCDCDecision { bitmap_idx: 0, conditions_num: 6 } at (prev + 3, 8) to (start + 0, 34)
130+
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 6, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
131+
true = c1
132+
false = (c0 - c1)
133+
- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
134+
- MCDCBranch { true: Expression(20, Sub), false: Counter(6), condition_id: 6, true_next_id: 5, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
135+
true = (c1 - c6)
136+
false = c6
137+
- Code(Expression(20, Sub)) at (prev + 0, 18) to (start + 0, 19)
138+
= (c1 - c6)
139+
- MCDCBranch { true: Expression(19, Sub), false: Counter(5), condition_id: 5, true_next_id: 4, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
140+
true = ((c1 - c6) - c5)
141+
false = c5
142+
- Code(Expression(19, Sub)) at (prev + 0, 23) to (start + 0, 24)
143+
= ((c1 - c6) - c5)
144+
- MCDCBranch { true: Expression(18, Sub), false: Counter(4), condition_id: 4, true_next_id: 3, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
145+
true = (((c1 - c6) - c5) - c4)
146+
false = c4
147+
- Code(Expression(18, Sub)) at (prev + 0, 28) to (start + 0, 29)
148+
= (((c1 - c6) - c5) - c4)
149+
- MCDCBranch { true: Expression(17, Sub), false: Counter(3), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29)
150+
true = ((((c1 - c6) - c5) - c4) - c3)
151+
false = c3
152+
- Code(Expression(17, Sub)) at (prev + 0, 33) to (start + 0, 34)
153+
= ((((c1 - c6) - c5) - c4) - c3)
154+
- MCDCBranch { true: Counter(7), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34)
155+
true = c7
156+
false = c2
157+
- Code(Counter(7)) at (prev + 0, 35) to (start + 2, 6)
158+
- Code(Expression(27, Add)) at (prev + 2, 6) to (start + 0, 7)
159+
= (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1))
160+
- Code(Expression(26, Add)) at (prev + 1, 1) to (start + 0, 2)
161+
= (c7 + (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1)))
162+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
LL| |#![feature(coverage_attribute)]
2+
LL| |//@ edition: 2021
3+
LL| |//@ min-llvm-version: 18
4+
LL| |//@ compile-flags: -Zcoverage-options=mcdc
5+
LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc
6+
LL| |
7+
LL| |// Check that MC/DC instrumentation can gracefully handle conditions that
8+
LL| |// exceed LLVM's limit of 6 conditions per decision.
9+
LL| |//
10+
LL| |// (The limit is enforced in `compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs`.)
11+
LL| |
12+
LL| 1|fn good() {
13+
LL| 1| // With only 6 conditions, perform full MC/DC instrumentation.
14+
LL| 1| let [a, b, c, d, e, f] = <[bool; 6]>::default();
15+
LL| 1| if a && b && c && d && e && f {
16+
^0 ^0 ^0 ^0 ^0
17+
------------------
18+
| Branch (LL:8): [True: 0, False: 1]
19+
| Branch (LL:13): [True: 0, False: 0]
20+
| Branch (LL:18): [True: 0, False: 0]
21+
| Branch (LL:23): [True: 0, False: 0]
22+
| Branch (LL:28): [True: 0, False: 0]
23+
| Branch (LL:33): [True: 0, False: 0]
24+
------------------
25+
|---> MC/DC Decision Region (LL:8) to (LL:34)
26+
|
27+
| Number of Conditions: 6
28+
| Condition C1 --> (LL:8)
29+
| Condition C2 --> (LL:13)
30+
| Condition C3 --> (LL:18)
31+
| Condition C4 --> (LL:23)
32+
| Condition C5 --> (LL:28)
33+
| Condition C6 --> (LL:33)
34+
|
35+
| Executed MC/DC Test Vectors:
36+
|
37+
| C1, C2, C3, C4, C5, C6 Result
38+
| 1 { F, -, -, -, -, - = F }
39+
|
40+
| C1-Pair: not covered
41+
| C2-Pair: not covered
42+
| C3-Pair: not covered
43+
| C4-Pair: not covered
44+
| C5-Pair: not covered
45+
| C6-Pair: not covered
46+
| MC/DC Coverage for Decision: 0.00%
47+
|
48+
------------------
49+
LL| 0| core::hint::black_box("hello");
50+
LL| 1| }
51+
LL| 1|}
52+
LL| |
53+
LL| 1|fn bad() {
54+
LL| 1| // With 7 conditions, fall back to branch instrumentation only.
55+
LL| 1| let [a, b, c, d, e, f, g] = <[bool; 7]>::default();
56+
LL| 1| if a && b && c && d && e && f && g {
57+
^0 ^0 ^0 ^0 ^0 ^0
58+
------------------
59+
| Branch (LL:8): [True: 0, False: 1]
60+
| Branch (LL:13): [True: 0, False: 0]
61+
| Branch (LL:18): [True: 0, False: 0]
62+
| Branch (LL:23): [True: 0, False: 0]
63+
| Branch (LL:28): [True: 0, False: 0]
64+
| Branch (LL:33): [True: 0, False: 0]
65+
| Branch (LL:38): [True: 0, False: 0]
66+
------------------
67+
LL| 0| core::hint::black_box("hello");
68+
LL| 1| }
69+
LL| 1|}
70+
LL| |
71+
LL| |#[coverage(off)]
72+
LL| |fn main() {
73+
LL| | good();
74+
LL| | bad();
75+
LL| |}
76+
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#![feature(coverage_attribute)]
2+
//@ edition: 2021
3+
//@ min-llvm-version: 18
4+
//@ compile-flags: -Zcoverage-options=mcdc
5+
//@ llvm-cov-flags: --show-branches=count --show-mcdc
6+
7+
// Check that MC/DC instrumentation can gracefully handle conditions that
8+
// exceed LLVM's limit of 6 conditions per decision.
9+
//
10+
// (The limit is enforced in `compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs`.)
11+
12+
fn good() {
13+
// With only 6 conditions, perform full MC/DC instrumentation.
14+
let [a, b, c, d, e, f] = <[bool; 6]>::default();
15+
if a && b && c && d && e && f {
16+
core::hint::black_box("hello");
17+
}
18+
}
19+
20+
fn bad() {
21+
// With 7 conditions, fall back to branch instrumentation only.
22+
let [a, b, c, d, e, f, g] = <[bool; 7]>::default();
23+
if a && b && c && d && e && f && g {
24+
core::hint::black_box("hello");
25+
}
26+
}
27+
28+
#[coverage(off)]
29+
fn main() {
30+
good();
31+
bad();
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: Conditions number of the decision (7) exceeds limit (6). MCDC analysis will not count this expression.
2+
--> $DIR/mcdc-condition-limit.rs:29:8
3+
|
4+
LL | if a && b && c && d && e && f && g {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
warning: 1 warning emitted
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ edition: 2021
2+
//@ min-llvm-version: 18
3+
//@ revisions: good bad
4+
//@ check-pass
5+
//@ compile-flags: -Cinstrument-coverage -Zcoverage-options=mcdc -Zno-profiler-runtime
6+
7+
// Check that we emit some kind of diagnostic when MC/DC instrumentation sees
8+
// code that exceeds the limit of 6 conditions per decision, and falls back
9+
// to only instrumenting that code for branch coverage.
10+
//
11+
// See also `tests/coverage/mcdc/condition-limit.rs`, which tests the actual
12+
// effect on instrumentation.
13+
//
14+
// (The limit is enforced in `compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs`.)
15+
16+
#[cfg(good)]
17+
fn main() {
18+
// 6 conditions is OK, so no diagnostic.
19+
let [a, b, c, d, e, f] = <[bool; 6]>::default();
20+
if a && b && c && d && e && f {
21+
core::hint::black_box("hello");
22+
}
23+
}
24+
25+
#[cfg(bad)]
26+
fn main() {
27+
// 7 conditions is too many, so issue a diagnostic.
28+
let [a, b, c, d, e, f, g] = <[bool; 7]>::default();
29+
if a && b && c && d && e && f && g { //[bad]~ WARNING Conditions number of the decision
30+
core::hint::black_box("hello");
31+
}
32+
}

0 commit comments

Comments
 (0)