aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJørgen Kvalsvik <j@lambda.is>2023-12-06 09:08:46 +0100
committerJørgen Kvalsvik <j@lambda.is>2024-04-04 20:29:12 +0200
commitdc8a25189dd6e10a50751793f08d6c5857bd6131 (patch)
tree912678d08ec2fd66a59988101a6803456228e6d8
parent08a52331803f66a4aaeaedd278436ca8eac57b50 (diff)
downloadgcc-dc8a25189dd6e10a50751793f08d6c5857bd6131.zip
gcc-dc8a25189dd6e10a50751793f08d6c5857bd6131.tar.gz
gcc-dc8a25189dd6e10a50751793f08d6c5857bd6131.tar.bz2
Add gcov MC/DC tests for GDC
This is a mostly straight port from the gcov-19.c tests from the C test suite. The only notable differences from C to D are that D flips the true/false outcomes for loop headers, and the D front end ties loop and ternary conditions to slightly different locus. The test for >64 conditions warning is disabled as it either needs support from the testing framework or a something similar to #pragma GCC diagnostic push to not cause a test failure from detecting a warning. gcc/testsuite/ChangeLog: * gdc.dg/gcov.exp: New test. * gdc.dg/gcov1.d: New test.
-rw-r--r--gcc/testsuite/gdc.dg/gcov.exp44
-rw-r--r--gcc/testsuite/gdc.dg/gcov1.d1712
2 files changed, 1756 insertions, 0 deletions
diff --git a/gcc/testsuite/gdc.dg/gcov.exp b/gcc/testsuite/gdc.dg/gcov.exp
new file mode 100644
index 0000000..4218771b
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gcov.exp
@@ -0,0 +1,44 @@
+# Copyright (C) 1997-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Gcov test driver.
+
+# Load support procs.
+load_lib gdc-dg.exp
+load_lib gcov.exp
+
+global GDC_UNDER_TEST
+
+# For now find gcov in the same directory as $GDC_UNDER_TEST.
+if { ![is_remote host] && [string match "*/*" [lindex $GDC_UNDER_TEST 0]] } {
+ set GCOV [file dirname [lindex $GDC_UNDER_TEST 0]]/[gcc-transform-out-of-tree gcov]
+} else {
+ set GCOV [gcc-transform-out-of-tree gcov]
+}
+
+# Initialize harness.
+dg-init
+
+# Delete old .gcda files.
+set files [glob -nocomplain gcov*.gcda]
+if { $files != "" } {
+ eval "remote_file build delete $files"
+}
+
+# Main loop.
+gdc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/gcov*.d]] "" ""
+
+dg-finish
diff --git a/gcc/testsuite/gdc.dg/gcov1.d b/gcc/testsuite/gdc.dg/gcov1.d
new file mode 100644
index 0000000..10ffa4a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/gcov1.d
@@ -0,0 +1,1712 @@
+/* { dg-options "-fcondition-coverage -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+/* Some side effect to stop branches from being pruned. */
+int x = 0;
+
+int id (int x) { return x; }
+int inv (int x) { return !x; }
+
+/* || works. */
+void
+mcdc001a (int a, int b)
+{
+ if (a || b) /* conditions(1/4) true(0) false(0 1) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc001b (int a, int b)
+{
+ if (a || b) /* conditions(3/4) true(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc001c (int a, int b)
+{
+ if (a || b) /* conditions(4/4) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc001d (int a, int b, int c)
+{
+ if (a || b || c) /* conditions(2/6) false(0 1 2) true(2) */
+ /* conditions(end) */
+ x = 1;
+}
+
+/* && works */
+void
+mcdc002a (int a, int b)
+{
+ if (a && b) /* conditions(1/4) true(0 1) false(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc002b (int a, int b)
+{
+ if (a && b) /* conditions(3/4) false(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc002c (int a, int b)
+{
+ if (a && b) /* conditions(4/4) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc002d (int a, int b, int c)
+{
+ if (a && b && c) /* conditions(4/6) false(0 2) */
+ /* conditions(end) */
+ x = 1;
+}
+
+/* Negation works. */
+void
+mcdc003a (int a, int b)
+{
+ if (!a || !b) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+/* Single conditionals with and without else. */
+void
+mcdc004a (int a)
+{
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc004b (int a)
+{
+ if (a) /* conditions(2/2) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc004c (int a)
+{
+ if (a) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ x = 1;
+}
+
+void
+mcdc004d (int a, int b, int c)
+{
+ if (a) /* conditions(2/2) */
+ {
+ if (b || c) /* conditions(1/4) true(1) false(0 1) */
+ x = a + b + c;
+ }
+}
+
+void
+mcdc004e (int a, int b, int c)
+{
+ if (a) /* conditions(2/2) */
+ {
+ if (b || c) /* conditions(1/4) true(1) false(0 1) */
+ /* conditions(end) */
+ x = a + b + c;
+ }
+ else
+ {
+ x = c;
+ }
+}
+
+void
+mcdc004f (int a, int b, int c)
+{
+ if (a) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ {
+ x = 1;
+ }
+ else if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ x = 2;
+ if (c) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ x = 3;
+ }
+}
+
+/* Mixing && and || works. */
+void
+mcdc005a (int a, int b, int c)
+{
+ if ((a && b) || c) /* conditions(1/6) true(0 1) false(0 1 2) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc005b (int a, int b, int c, int d)
+{
+ /* This is where masking MC/DC gets unintuitive:
+
+ 1 1 0 0 => covers 1 (d = 0) as && 0 masks everything to the left
+ 1 0 0 0 => covers 2 (b = 0, c = 0) as (a && 0) masks a and d is never
+ evaluated. */
+ if ((a && (b || c)) && d) /* conditions(3/8) true(0 1 2 3) false(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc005c (int a, int b, int c, int d)
+{
+ if (a || (b && c) || d) /* conditions(2/8) true(0 3) false(0 1 2 3) */
+ /* conditions(end) */
+ x = a + b + c + d;
+}
+
+void
+mcdc005d (int a, int b, int c, int d)
+{
+ /* This test is quite significant - it has a single input
+ (1, 0, 0, 0) and tests specifically for when a multi-term left operand
+ is masked. d = 0 should mask a || b and for the input there are no other
+ sources for masking a (since b = 0). */
+ if ((a || b) && (c || d)) /* conditions(2/8) true(0 1 2 3) false(0 1) */
+ /* conditions(end) */
+ x = a + b;
+ else
+ x = c + d;
+}
+
+/* Mixing in constants kills the decision removes the term outright. */
+void
+mcdc005e (int a, int b)
+{
+ x += 0 && a;
+ x += a && 1;
+ x += 0 && a && b;
+ x += a && 1 && b; /* conditions(4/4) */
+ x += a && b && 0;
+ x += 0 && 1;
+ x += 1 && a;
+ x += a && 0;
+ x += 1 || a;
+ x += a || 0;
+ x += 1 || a || b;
+ x += a || 0 || b; /* conditions(4/4) */
+ x += a || b || 1;
+ x += 1 || 0;
+ x += 0 || a;
+ x += a || 1;
+}
+
+/* Nested conditionals. */
+void
+mcdc006a (int a, int b, int c, int d, int e)
+{
+ if (a) /* conditions(2/2) */
+ {
+ if (b && c) /* conditions(3/4) false(1) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+ }
+ else
+ {
+ if (c || d) /* conditions(2/4) true(0 1) */
+ /* conditions(end) */
+ x = 3;
+ else
+ x = 4;
+ }
+}
+
+void
+mcdc006b (int a, int b, int c)
+{
+ if (a) /* conditions(2/2) */
+ if (b) /* conditions(2/2) */
+ if (c) /* conditions(2/2) */
+ x = a + b + c;
+}
+
+void
+mcdc006c (int a, int b, int c)
+{
+ if (a) /* conditions(2/2) */
+ {
+ if (b) /*conditions(2/2) */
+ {
+ if (c) /* conditions(2/2) */
+ {
+ x = a + b + c;
+ }
+ }
+ else
+ {
+ x = b;
+ }
+ }
+ else
+ {
+ x = a;
+ }
+}
+
+void
+mcdc006d (int a, int b, int c)
+{
+ if (a) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x = a + b;
+ if (c) /* conditions(2/2) */
+ /* conditions(end) */
+ x = a + b;
+ }
+}
+
+void
+mcdc006e (int a, int b, int c, int d)
+{
+ if ((a || b || c) && id (d)) /* conditions(4/8) true(0 1 2 3) false() */
+ /* conditions(end) */
+ x = 1;
+}
+
+/* else/if. */
+void
+mcdc007a (int a, int b, int c, int d)
+{
+ if (a) /* conditions(2/2) */
+ {
+ if (b) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+ }
+ else if (c) /* conditions(2/2) */
+ {
+ if (d) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x = 3;
+ else
+ x = 4;
+ }
+}
+
+void
+mcdc007b (int a, int b, int c)
+{
+ goto begin;
+then:
+ x = 1;
+ return;
+begin:
+ if (a) /* conditions(2/2) */
+ goto then;
+ else if (b) /* conditions(2/2) */
+ goto then;
+ else if (c) /* conditions(1/2) true(0) */
+ goto then;
+}
+
+void
+mcdc007c (int a, int b, int c)
+{
+ goto begin;
+then1:
+ x = 1;
+ return;
+then2:
+ x = 1;
+ return;
+then3:
+ x = 1;
+ return;
+begin:
+ if (a) /* conditions(2/2) */
+ goto then1;
+ else if (b) /* conditions(2/2) */
+ goto then2;
+ else if (c) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ goto then3;
+}
+
+void
+noop () {}
+
+int
+mcdc007d (int a, int b, int c, int d, int e)
+{
+ noop ();
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b || c) /* conditions(0/4) true(0 1) false(0 1) */
+ /* conditions(end) */
+ x = 2;
+ if (d) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 1;
+ }
+ if (e) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ return 0;
+
+ return 2;
+}
+
+/* while loop. */
+void
+mcdc008a (int a)
+{
+ while (a < 10) /* conditions(2/2) */
+ x = a++;
+}
+
+void
+mcdc008b (int a)
+{
+ /* gdc inverts this check. */
+ while (a > 10) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ x = a--;
+}
+
+void
+mcdc008c (int a)
+{
+ // should work, even with no body
+ while (a) /* conditions(2/2) */
+ break;
+}
+
+void
+mcdc008d (int a, int b, int c, int d)
+{
+ /* Multi-term loop conditional. */
+ while ((a && (b || c)) && d) /* conditions(8/8) */
+ a = b = c = d = 0;
+}
+
+void
+mcdc009a (int a, int b)
+{
+ while (a > 0 && b > 0) /* conditions(3/4) true(1) */
+ /* conditions(end) */
+ x = a--;
+}
+
+void
+mcdc009b (int a, int b)
+{
+ while (a-- > 0 && b) {} /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+}
+
+/* for loop. */
+void
+mcdc010a (int a, int b)
+{
+ for (int i = 0; i < b; i++) /* conditions(2/2) */
+ {
+ if (a < b) /* conditions(2/2) */
+ x = 1;
+ else
+ x = a += 2;
+ }
+}
+
+void
+mcdc010b ()
+{
+ for (int a = 0; a <= 1; ++a) /* conditions(2/2) */
+ {
+ x = a;
+ }
+}
+
+int
+mcdc010c (int a, int b, int c)
+{
+ for (;a || b || c;) /* conditions(4/6) false(0 2) */
+ /* conditions(end) */
+ return 1;
+ return 0;
+}
+
+
+int always (int x) { return 1; }
+
+/* No-condition infinite loops. */
+void
+mcdc010d (int a)
+{
+ for (;;)
+ {
+ if (always(a)) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ {
+ x = a;
+ break;
+ }
+ x += a + 1;
+ }
+}
+
+/* conditionals without control flow constructs work */
+void
+mcdc011a (int a, int b, int c)
+{
+ x = (a && b) || c; /* conditions(5/6) false(1) */
+ /* conditions(end) */
+}
+
+/* Sequential expressions are handled independently. */
+void
+mcdc012a (int a, int b, int c)
+{
+ if (a || b) /* conditions(3/4) true(0) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+
+ if (c) /* conditions(2/2) */
+ x = 1;
+}
+
+/* Cannot ever satisfy (masking) MC/DC, even with all input combinations,
+ because not all variables independently affect the decision. */
+void
+mcdc013a (int a, int b, int c)
+{
+ /* Specification: (a && b) || c
+ The implementation does not match the specification. This has branch
+ coverage, but not MC/DC. */
+ if ((a && !c) || c) /* conditions(5/6) false(1) */
+ /* conditions(end) */
+ x = 1;
+ else
+ x = 2;
+}
+
+void
+mcdc014a ()
+{
+ int[64] conds;
+ /* conditions(64/128) true(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63) */
+ x = conds[ 0] || conds[ 1] || conds[ 2] || conds[ 3] || conds[ 4] ||
+ conds[ 5] || conds[ 6] || conds[ 7] || conds[ 8] || conds[ 9] ||
+ conds[10] || conds[11] || conds[12] || conds[13] || conds[14] ||
+ conds[15] || conds[16] || conds[17] || conds[18] || conds[19] ||
+ conds[20] || conds[21] || conds[22] || conds[23] || conds[24] ||
+ conds[25] || conds[26] || conds[27] || conds[28] || conds[29] ||
+ conds[30] || conds[31] || conds[32] || conds[33] || conds[34] ||
+ conds[35] || conds[36] || conds[37] || conds[38] || conds[39] ||
+ conds[40] || conds[41] || conds[42] || conds[43] || conds[44] ||
+ conds[45] || conds[46] || conds[47] || conds[48] || conds[49] ||
+ conds[50] || conds[51] || conds[52] || conds[53] || conds[54] ||
+ conds[55] || conds[56] || conds[57] || conds[58] || conds[59] ||
+ conds[60] || conds[61] || conds[62] || conds[63]
+ ; /* conditions(end) */
+}
+
+/* Early returns. */
+void
+mcdc015a (int a, int b)
+{
+ if (a) /* conditions(2/2) */
+ return;
+
+ if (b) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x = 1;
+}
+
+void
+mcdc015b (int a, int b)
+{
+ for (int i = 5; i > a; i--) /* conditions(2/2) */
+ {
+ if (i == b) /* conditions(2/2) */
+ return;
+ x = i;
+ }
+}
+
+void
+mcdc015c (int a, int b)
+{
+ for (int i = 5; i > a; i--) /* conditions(2/2) */
+ {
+ if (i == b) /* conditions(2/2) */
+ {
+ x = 0;
+ return;
+ }
+ else
+ {
+ x = 1;
+ return;
+ }
+
+ x = i;
+ }
+}
+
+/* Early returns, gotos. */
+void
+mcdc015d (int a, int b, int c)
+{
+ if (a) return; /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ if (id (b)) return; /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ if (id (c)) return; /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+}
+
+
+/* Check nested loops. */
+void
+mcdc016a (int a, int b)
+{
+ for (int i = 0; i < a; i++) /* conditions(2/2) */
+ for (int k = 0; k < b; k++) /* conditions(2/2) */
+ x = i + k;
+}
+
+void
+mcdc016b (int a, int b)
+{
+ for (int i = 0; i < a; i++) /* conditions(2/2) */
+ {
+ if (a > 5) /* conditions(2/2) */
+ break;
+
+ for (int k = 0; k < b; k++) /* conditions(2/2) */
+ x = i + k;
+ }
+}
+
+void
+mcdc016c (int a, int b)
+{
+ for (int i = 0; i < a; i++) /* conditions(2/2) */
+ {
+ if (a > 5) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ return;
+
+ for (int k = 0; k < b; k++) /* conditions(2/2) */
+ x = i + k;
+ }
+}
+
+void
+mcdc016d (int a, int b)
+{
+ for (int i = 0; i < a; i++) /* conditions(2/2) */
+ {
+ for (int k = 0; k < 5; k++) /* conditions(2/2) */
+ {
+ if (b > 5) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ return;
+ x = i + k;
+ }
+
+ }
+}
+
+/* do-while loops. */
+void
+mcdc017a (int a)
+{
+ do
+ {
+ /* conditions(2/2) */
+ a--;
+ } while (a > 0);
+}
+
+void
+mcdc017b (int a, int b)
+{
+ do /* conditions(2/2) */
+ {
+ /* This call is important; it can add more nodes to the body in the
+ CFG, which changes how close exits and breaks are to the loop
+ conditional. */
+ noop ();
+ a--;
+ if (b) /* conditions(2/2) */
+ break;
+ } while (a > 0);
+}
+
+void
+mcdc017c (int a, int b)
+{
+ int left = 0;
+ int right = 0;
+ int n = a + b;
+ do
+ {
+ if (a) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ {
+ left = a > left ? b : left; /* conditions(2/2) */
+ }
+ if (b) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ {
+ right = b > right ? a : right; /* conditions(2/2) */
+ }
+ } while (n-- > 0); /* conditions(2/2) */
+}
+
+void
+mcdc017d (int a, int b, int c)
+{
+ do
+ {
+ a--; /* conditions(0/6) true(0 1 2) false(0 1 2) */
+ /* conditions(end) */
+ } while (a > 0 && b && c);
+}
+
+/* Collection of odd cases lifted-and-adapted from real-world code. */
+int
+mcdc018a (int a, int b, int c, int d, int e, int f, int g, int len)
+{
+ int n;
+ /* adapted from zlib/gz_read */
+ do
+ {
+ n = -1;
+ if (n > len) /* conditions(2/2) */
+ n = len;
+
+ if (b) /* conditions(2/2) */
+ {
+ if (b < 5) /* conditions(2/2) */
+ x = 1;
+ noop();
+ }
+ else if (c && d) /* conditions(3/4) false(1) */
+ /* conditions(end) */
+ {
+ x = 2;
+ break;
+ }
+ else if (e || f) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ {
+ if (id(g)) /* conditions(2/2) */
+ return 0;
+ continue;
+ }
+ } while (a-- > 0); /* conditions(2/2) */
+
+ return 1;
+}
+
+void
+mcdc018b (int a, int b, int c)
+{
+ int n;
+ while (a) /* conditions(2/2) */
+ {
+ /* else block does not make a difference for the problem, but ensures
+ loop termination. */
+ if (b) /* conditions(2/2) */
+ n = c ? 0 : 0; // does not show up in CFG (embedded in the block)
+ else
+ n = 0;
+ a = n;
+ }
+}
+
+/* Adapted from zlib/compress2. */
+void
+mcdc018c (int a, int b)
+{
+ int err;
+ do
+ {
+ a = inv (a);
+ err = a; /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ } while (err);
+
+ a = id (a);
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ x *= a + 1;
+}
+
+/* Too many conditions, coverage gives up. */
+void
+mcdc019a ()
+{
+ /* This will warn and needs a pragma warning suppression (or similar)
+ mechanism to not cause trigger a test failure from the warning.
+ int[65] conds;
+ x = conds[ 0] || conds[ 1] || conds[ 2] || conds[ 3] || conds[ 4] ||
+ conds[ 5] || conds[ 6] || conds[ 7] || conds[ 8] || conds[ 9] ||
+ conds[10] || conds[11] || conds[12] || conds[13] || conds[14] ||
+ conds[15] || conds[16] || conds[17] || conds[18] || conds[19] ||
+ conds[20] || conds[21] || conds[22] || conds[23] || conds[24] ||
+ conds[25] || conds[26] || conds[27] || conds[28] || conds[29] ||
+ conds[30] || conds[31] || conds[32] || conds[33] || conds[34] ||
+ conds[35] || conds[36] || conds[37] || conds[38] || conds[39] ||
+ conds[40] || conds[41] || conds[42] || conds[43] || conds[44] ||
+ conds[45] || conds[46] || conds[47] || conds[48] || conds[49] ||
+ conds[50] || conds[51] || conds[52] || conds[53] || conds[54] ||
+ conds[55] || conds[56] || conds[57] || conds[58] || conds[59] ||
+ conds[60] || conds[61] || conds[62] || conds[63] || conds[64]
+ ;
+ */
+}
+
+/* Ternary. */
+void
+mcdc020a (int a)
+{
+ /* In C this is reduced to
+ _1 = argc != 0;
+ e = (int) _1;
+ but in D the branches are preserved. */
+ x = a ? 1 : 0; /* conditions(2/2) */
+ x = a ? 2 : 1; /* conditions(2/2) */
+}
+
+void
+mcdc020b (int a, int b)
+{
+ x = (a || b) ? 1 : 0; /* conditions(3/4) true(1) */
+ /* conditions(end) */
+}
+
+void
+mcdc020c (int a, int b)
+{
+ x = a ? 0 /* conditions(2/2) */
+ : b ? 1 /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ : 2;
+}
+
+int
+mcdc020d (int b, int c, int d, int e, int f)
+{
+ return ((b ? c : d) && e && f); /* conditions(7/10) true(2) false(3 4) */
+ /* conditions(end) */
+}
+
+/* Infinite loop (no exit-edge), this should not be called, but it should
+ compile fine. */
+void
+mcdc021a ()
+{
+ while (1) {}
+}
+
+/* If edges are not properly contracted the a && id (b) will be interpreted as
+ two independent expressions. */
+void
+mcdc021d (int a, int b, int c, int d)
+{
+ if (a && id (b)) /* conditions(1/4) true(0 1) false(0) */
+ /* conditions(end) */
+ x = 1;
+ else if (c && id (d)) /* conditions(1/4) true(0 1) false(0) */
+ /* conditions(end) */
+ x = 2;
+ else
+ x = 3;
+}
+
+/* Adapted from linux arch/x86/tools/relocs.c
+ With poor edge contracting this became an infinite loop. */
+void
+mcdc022a (int a, int b)
+{
+ for (int i = 0; i < 5; i++) /* conditions(2/2) */
+ {
+ x = i;
+ for (int j = i; j < 5; j++) /* conditions(2/2) */
+ {
+ if (id (id (a)) || id (b)) /* conditions(3/4) true(0) */
+ /* conditions(end) */
+ continue;
+ b = inv(b);
+ }
+ }
+}
+
+int
+mcdc022b (int a)
+{
+ int devt;
+ if (a) /* conditions(2/2) */
+ {
+ x = a * 2;
+ if (x != a / 10 || x != a % 10) /* conditions(1/4) true(1) false(0 1) */
+ /* conditions(end) */
+ return 0;
+ } else {
+ devt = id (a);
+ if (devt) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ return 0;
+ }
+
+ return devt;
+}
+
+/* Adapted from linux arch/x86/events/intel/ds.c
+
+ It broken sorting so that the entry block was not the first node after
+ sorting. */
+void
+mcdc022c (int a)
+{
+ if (!a) /* conditions(2/2) */
+ return;
+
+ for (int i = 0; i < 5; i++) /* conditions(2/2) */
+ {
+ if (id (a + i) || inv (a - 1)) /* conditions(1/4) false(0 1) true(1) */
+ /* conditions(end) */
+ x = a + i;
+ if (inv (a)) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ break;
+ }
+}
+
+void
+mcdc022d (int a)
+{
+ int i;
+ for (i = 0; i < id (a); i++) /* conditions(1/2) true(0) */
+ {
+ if (!inv (a)) /* conditions(1/2) false(0)*/
+ /* conditions(end) */
+ break;
+ }
+
+ if (i < a) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ x = a + 1;
+}
+
+/* Adapted from openssl-3.0.1/crypto/cmp/cmp_msg.c ossl_cmp_error_new (). */
+void
+mcdc022e (int a, int b, int c, int d)
+{
+ if (a || b) /* conditions(1/4) true(0) false(0 1) */
+ /* conditions(end) */
+ {
+ if (always (c)) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ goto err;
+ d++;
+ }
+
+ if (d) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ goto err;
+ return;
+
+err:
+ noop ();
+}
+
+/* 023 specifically tests that masking works correctly, which gets complicated
+ fast with a mix of operators and deep subexpressions. These tests violates
+ the style guide slightly to emphasize the nesting. They all share the same
+ implementation and only one input is given to each function to obtain clean
+ coverage results. */
+void
+mcdc023a (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ // [a m n] = 0, [b, ...] = 1
+ // a is masked by b and the remaining terms should be short circuited
+ if (/* conditions(1/24) true(0 2 3 4 5 6 7 8 9 10 11) false(0 1 2 3 4 5 6 7 8 9 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023b (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ // [a b d h] = 0, [c, ...] = 1
+ // h = 0 => false but does not mask (a || b) or (c && d). d = 0 masks c.
+ if (/* conditions(4/24) true(0 1 2 3 4 5 6 7 8 9 10 11) false(2 4 5 6 8 9 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023c (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ /* [m n a b] = 0, [...] = 1
+ n,m = 0 should mask all other terms than a, b */
+ if (/* conditions(4/24) true(0 1 2 3 4 5 6 7 8 9 10 11) false(2 3 4 5 6 7 8 9) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023d (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ /* [a b] = 0, [h, ...] = 1
+ n,m = 0 should mask all other terms than a, b */
+ if (/* conditions(4/24) true(0 1 2 3 4 5 6 7 8 9 10 11) false(2 3 4 5 6 7 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023e (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ /* [a b d] = 0, [c h, ...] = 1
+ h = 1 should mask c, d, leave other terms intact.
+ If [k l m n] were false then h itself would be masked.
+ [a b] are masked as collateral by [m n]. */
+ if (/* conditions(5/24) true(0 1 2 3 6 9 11) false(0 1 2 3 4 5 6 7 8 9 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023f (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ /* [a b c f g] = 0, [e, ...] = 1
+ [f g] = 0 should mask e, leave [c d] intact. */
+ if (/* conditions(5/24) true(0 1 2 3 4 5 6 7 8 9 10 11) false(3 4 7 8 9 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+void
+mcdc023g (int a, int b, int c, int d, int e, int f, int g, int h, int i, int k,
+ int l, int m, int n)
+{
+ /* [a b d f g] = 0, [e c, ...] = 1
+ Same as 023f but with [c d] flipped so d masks c rather than c
+ short-circuits. This should not be lost. */
+ if (/* conditions(5/24) true(0 1 2 3 4 5 6 7 8 9 10 11) false(2 4 7 8 9 10 11) */
+ /* conditions(end) */
+ (a || b)
+ || ( ((c && d) || (e && (f || g) && h))
+ && (k || l)
+ && (m || n)))
+ x = a + b;
+ else
+ x = b + c;
+}
+
+/* Gotos, return, labels can make odd graphs. It is important that conditions
+ are assigned to the right expression, and that there are no miscounts. In
+ these tests values may be re-used, as checking things like masking an
+ independence is done in other test cases and not so useful here. */
+void
+mcdc024a (int a, int b)
+{
+ /* This is a reference implementation without the labels, which should not
+ alter behavior. */
+ if (a && b) /* conditions(2/4) true(0 1) */
+ /* conditions(end) */
+ {
+ x = 1;
+ }
+ else
+ {
+ x = 2;
+ }
+
+ if (a || b) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ {
+ x = 1;
+ }
+ else
+ {
+ x = 2;
+ }
+}
+
+void
+mcdc024b (int a, int b)
+{
+ if (a && b) /* conditions(2/4) true(0 1) */
+ /* conditions(end) */
+ {
+label1:
+ x = 1;
+ }
+ else
+ {
+ x = 2;
+ }
+
+ if (a || b) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ {
+label2:
+ x = 1;
+ }
+ else
+ {
+ x = 2;
+ }
+}
+
+void
+mcdc024c (int a, int b)
+{
+
+ if (a && b) /* conditions(2/4) true(0 1) */
+ /* conditions(end) */
+ {
+ x = 1;
+ }
+ else
+ {
+label1:
+ x = 2;
+ }
+
+ if (a || b) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ {
+ x = 1;
+ }
+ else
+ {
+label2:
+ x = 2;
+ }
+}
+
+void
+mcdc024d (int a, int b)
+{
+ if (a && b) /* conditions(2/4) true(0 1) */
+ /* conditions(end) */
+ {
+label1:
+ x = 1;
+ }
+ else
+ {
+label2:
+ x = 2;
+ }
+
+ if (a || b) /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ {
+label3:
+ x = 1;
+ }
+ else
+ {
+label4:
+ x = 2;
+ }
+}
+
+int
+mcdc024e (int a, int b, int c)
+{
+ /* Graphs can get complicated with the innermost returns and else-less if,
+ so we must make sure these conditions are counted correctly. */
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ if (c) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 1;
+ else
+ return 2;
+ }
+
+ if (a) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 3;
+ }
+
+ return 5;
+}
+
+/* Nested else-less ifs with inner returns needs to be counted right, which
+ puts some pressure on the expression isolation. */
+int
+mcdc024f (int a, int b, int c)
+{
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ if (c) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ if (a) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 1;
+ else
+ return 2;
+ }
+
+ if (a) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 3;
+ }
+
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return 4;
+ }
+ return 5;
+}
+
+int
+mcdc024g (int a, int b, int c)
+{
+ if (b) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ return 0;
+
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ b += 2;
+ if (b & 0xFF) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ c++;
+
+ return c;
+ }
+ c += 10;
+ }
+ return 1;
+}
+
+
+int
+mcdc024h (int a, int b, int c)
+{
+ if (b) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ goto inner;
+
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ ++a;
+
+
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+inner:
+ b += 2;
+ if (b & 0xFF) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ c++;
+
+ return c;
+ }
+ c += 10;
+ }
+ return 1;
+}
+
+int
+mcdc024i (int a, int b, int c)
+{
+fst:
+ b++;
+snd:
+ b++;
+
+ if (b > 10) /* conditions(2/2) */
+ /* conditions(end) */
+ goto end;
+
+ if (b < 5) /* conditions(2/2) */
+ /* conditions(end) */
+ goto fst;
+ else
+ goto snd;
+
+end:
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ ++a;
+
+
+ if (a) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ {
+ b += 2;
+ if (b & 0xFF) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ c++;
+
+ return c;
+ }
+ c += 10;
+ }
+ return 1;
+}
+
+/* Adapted from alsa-lib 1.2.8 src/control/control.c. If two expressions share
+ an outcome with bypass nodes they would be marked twice. */
+int
+mcdc025a (int a, int b, int c)
+{
+ int err;
+ if (id (a)) /* conditions(1/2) true(0) */
+ /* conditions(end) */
+ {
+ if (b) /* conditions(0/2) true(0) false(0) */
+ /* conditions(end) */
+ return -1;
+ }
+ else
+ {
+ err = id (c);
+ if (err > 0) /* conditions(1/2) false(0) */
+ /* conditions(end) */
+ return err;
+ }
+ err = id (a);
+ return err;
+}
+
+/* Boolean expressions in function call parameters. These tests are all built
+ with a reference expression which should behave the same as the function
+ call versions. */
+int
+mcdc026a (int a, int b, int c, int d, int e)
+{
+ int cad = c && d; /* conditions(4/4) */
+ /* conditions(end) */
+ int x = a && b && cad && e; /* conditions(5/8) false(0 1 3) */
+ /* conditions(end) */
+ int y = a && b && id (c && d) && e; /* conditions(5/8; 4/4) false(0 1 3;;) */
+ /* conditions(end) */
+ return x + y;
+}
+
+int
+mcdc026b (int a, int b, int c, int d, int e)
+{
+ int dae = d && e; /* conditions(3/4) false(1) */
+ /* conditions(end) */
+ int x = a && b && c && dae; /* conditions(6/8) false(0 1) */
+ int y = a && b && c && id (d && e); /* conditions(6/8; 3/4) false(0 1; 1) */
+ /* conditions(end) */
+ return x + y;
+}
+
+int
+mcdc026c (int a, int b, int c, int d, int e)
+{
+ int cod = c || d; /* conditions(3/4) true(1) */
+ /* conditions(end) */
+ int x = a && b && cod && e; /* conditions(5/8) false(0 1 3) */
+ int y = a && b && id (c || d) && e; /* conditions(5/8; 3/4) true(;1) false(0 1 3;) */
+ /* conditions(end) */
+ return x+y;
+}
+
+int
+mcdc026d (int a, int b, int c, int d, int e)
+{
+ int aab = a && b; /* conditions(2/4) false(0 1) */
+ /* conditions(end) */
+ int cod = c || d; /* conditions(3/4) true(1) */
+ /* conditions(end) */
+ int x = aab && cod && e; /* conditions(4/6) false(0 2) */
+ /* conditions(end) */
+ int y = id (a && b) && id (c || d) && e; /* conditions(2/4;4/6;3/4) true(;;1) false(0 1;0 2;;) */
+ /* conditions(end) */
+ return x + y;
+}
+
+int
+mcdc026e (int a, int b, int c, int d, int e)
+{
+ int cod = c || d; /* conditions(3/4) true(1) */
+ /* conditions(end) */
+ int dae = d && e; /* conditions(3/4) false(1) */
+ /* conditions(end) */
+ int aacod = a && cod; /* conditions(3/4) false(0)*/
+ /* conditions(end) */
+ int x = aacod && dae; /* conditions(4/4) */
+ /* conditions(end) */
+ int y = id (a && id (c || d)) && id (d && e); /* conditions(3/4; 3/4; 4/4; 3/4) true(;1;;) false(0;;;1) */
+ /* conditions(end) */
+ return x + y;
+}
+
+void main ()
+{
+ mcdc001a (0, 1);
+
+ mcdc001b (0, 1);
+ mcdc001b (0, 0);
+
+ mcdc001c (0, 1);
+ mcdc001c (0, 0);
+ mcdc001c (1, 1);
+
+ mcdc001d (1, 1, 1);
+ mcdc001d (0, 1, 0);
+
+ mcdc002a (1, 0);
+
+ mcdc002b (1, 0);
+ mcdc002b (1, 1);
+
+ mcdc002c (0, 0);
+ mcdc002c (1, 1);
+ mcdc002c (1, 0);
+
+ mcdc002d (1, 1, 1);
+ mcdc002d (1, 0, 0);
+
+ mcdc003a (0, 0);
+ mcdc003a (1, 0);
+
+ mcdc004a (0);
+ mcdc004b (0);
+ mcdc004b (1);
+ mcdc004c (1);
+
+ mcdc004d (0, 0, 0);
+ mcdc004d (1, 1, 1);
+
+ mcdc004e (0, 0, 0);
+ mcdc004e (1, 1, 1);
+
+ mcdc004f (1, 1, 1);
+
+ mcdc005a (1, 0, 1);
+
+ mcdc005b (1, 1, 0, 0);
+ mcdc005b (1, 0, 0, 0);
+
+ mcdc005c (0, 1, 1, 0);
+
+ mcdc005d (1, 0, 0, 0);
+
+ mcdc005e (0, 0);
+ mcdc005e (0, 1);
+ mcdc005e (1, 0);
+ mcdc005e (1, 1);
+
+ mcdc006a (0, 0, 0, 0, 0);
+ mcdc006a (1, 0, 0, 0, 0);
+ mcdc006a (1, 1, 1, 0, 0);
+
+ mcdc006b (0, 0, 0);
+ mcdc006b (1, 0, 0);
+ mcdc006b (1, 1, 0);
+ mcdc006b (1, 1, 1);
+
+ mcdc006c (0, 0, 0);
+ mcdc006c (1, 0, 0);
+ mcdc006c (1, 1, 0);
+ mcdc006c (1, 1, 1);
+
+ mcdc006d (1, 0, 0);
+ mcdc006d (1, 0, 1);
+
+ mcdc006e (0, 0, 0, 0);
+ mcdc006e (0, 0, 1, 0);
+ mcdc006e (0, 1, 0, 0);
+
+ mcdc007a (0, 0, 0, 0);
+ mcdc007a (1, 0, 0, 0);
+ mcdc007a (0, 0, 1, 0);
+
+ mcdc007b (0, 0, 0);
+ mcdc007b (0, 1, 1);
+ mcdc007b (1, 0, 1);
+
+ mcdc007c (0, 0, 0);
+ mcdc007c (0, 1, 1);
+ mcdc007c (1, 0, 1);
+
+ mcdc007d (0, 1, 0, 1, 1);
+
+ mcdc008a (0);
+
+ mcdc008b (0);
+
+ mcdc008c (0);
+ mcdc008c (1);
+
+ mcdc008d (0, 0, 0, 0);
+ mcdc008d (1, 0, 0, 0);
+ mcdc008d (1, 0, 1, 0);
+ mcdc008d (1, 0, 1, 1);
+ mcdc008d (1, 1, 1, 1);
+
+ mcdc009a (0, 0);
+ mcdc009a (1, 1);
+
+ mcdc009b (0, 0);
+ mcdc009b (1, 0);
+
+ mcdc010a (0, 0);
+ mcdc010a (0, 9);
+ mcdc010a (2, 1);
+
+ mcdc010b ();
+
+ mcdc010c (0, 0, 0);
+ mcdc010c (0, 1, 0);
+
+ mcdc010d (1);
+
+ mcdc011a (0, 0, 0);
+ mcdc011a (1, 1, 0);
+ mcdc011a (1, 0, 1);
+
+ mcdc012a (0, 0, 0);
+ mcdc012a (0, 1, 1);
+
+ mcdc013a (0, 0, 0);
+ mcdc013a (0, 0, 1);
+ mcdc013a (0, 1, 0);
+ mcdc013a (0, 1, 1);
+ mcdc013a (1, 0, 0);
+ mcdc013a (1, 0, 1);
+ mcdc013a (1, 1, 0);
+ mcdc013a (1, 1, 1);
+
+ mcdc014a ();
+
+ mcdc015a (0, 0);
+ mcdc015a (1, 0);
+
+ mcdc015b (0, 0);
+ mcdc015b (0, 1);
+ mcdc015b (6, 1);
+
+ mcdc015c (0, 0);
+ mcdc015c (0, 5);
+ mcdc015c (6, 1);
+
+ mcdc015d (1, 0, 0);
+
+ mcdc016a (5, 5);
+
+ mcdc016b (5, 5);
+ mcdc016b (6, 5);
+
+ mcdc016c (5, 5);
+
+ mcdc016d (1, 0);
+
+ mcdc017a (0);
+ mcdc017a (2);
+
+ mcdc017b (2, 0);
+ mcdc017b (0, 1);
+
+ mcdc017c (1, 1);
+
+ mcdc018a (0, 0, 1, 1, 0, 0, 0, 0);
+ mcdc018a (0, 1, 0, 0, 0, 0, 1, -2);
+ mcdc018a (0, 6, 0, 0, 0, 0, 1, -2);
+ mcdc018a (0, 6, 0, 0, 0, 0, 1, -2);
+ mcdc018a (0, 0, 0, 1, 0, 1, 1, 0);
+ mcdc018a (1, 0, 0, 0, 1, 1, 0, 0);
+
+ mcdc018b (1, 0, 0);
+ mcdc018b (1, 1, 0);
+
+ mcdc018c (1, 1);
+
+ mcdc019a ();
+
+ mcdc020a (0);
+ mcdc020a (1);
+
+ mcdc020b (0, 0);
+ mcdc020b (1, 0);
+
+ mcdc020c (0, 1);
+ mcdc020c (1, 1);
+
+ mcdc020d (0, 0, 0, 0, 0);
+ mcdc020d (1, 0, 0, 1, 1);
+ mcdc020d (1, 1, 0, 1, 1);
+
+ mcdc021d (1, 0, 1, 0);
+
+ mcdc022a (0, 0);
+
+ mcdc022b (0);
+ mcdc022b (1);
+
+ mcdc022c (0);
+ mcdc022c (1);
+
+ mcdc022d (1);
+ mcdc022e (0, 1, 1, 0);
+
+ mcdc023a (0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+ mcdc023b (0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1);
+ mcdc023c (0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0);
+ mcdc023d (0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1);
+ mcdc023e (0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+ mcdc023f (0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1);
+ mcdc023g (0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1);
+
+ mcdc024a (0, 1);
+ mcdc024b (0, 1);
+ mcdc024c (0, 1);
+ mcdc024d (0, 1);
+ mcdc024a (1, 0);
+ mcdc024b (1, 0);
+ mcdc024c (1, 0);
+ mcdc024d (1, 0);
+
+ mcdc024e (0, 0, 0);
+ mcdc024f (0, 0, 0);
+ mcdc024g (0, 0, 0);
+ mcdc024h (0, 0, 0);
+ mcdc024i (0, 0, 0);
+
+ mcdc025a (0, 0, 1);
+
+ mcdc026a (1, 1, 1, 0, 1);
+ mcdc026a (1, 1, 0, 0, 1);
+ mcdc026a (1, 1, 1, 1, 1);
+
+ mcdc026b (1, 1, 1, 0, 1);
+ mcdc026b (1, 1, 0, 0, 1);
+ mcdc026b (1, 1, 1, 1, 1);
+
+ mcdc026c (1, 1, 1, 0, 1);
+ mcdc026c (1, 1, 0, 0, 1);
+ mcdc026c (1, 1, 1, 1, 1);
+
+ mcdc026d (1, 1, 1, 0, 1);
+ mcdc026d (1, 1, 0, 0, 1);
+ mcdc026d (1, 1, 1, 1, 1);
+
+ mcdc026e (1, 1, 1, 0, 1);
+ mcdc026e (1, 1, 0, 0, 1);
+ mcdc026e (1, 1, 1, 1, 1);
+}
+
+/* { dg-final { run-gcov conditions { --conditions gcov1.d } } } */