https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120321
Bug ID: 120321
Summary: Inconsistent line coverage for "for(;;)" "while(1)"
etc
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: gcov-profile
Assignee: unassigned at gcc dot gnu.org
Reporter: wentaoz5 at illinois dot edu
Target Milestone: ---
Hit the issue when measuring
https://sources.debian.org/src/iproute2/6.1.0-3/lib/libnetlink.c/#L872
etc
How to reproduce:
$ gcc --version
gcc (GCC) 16.0.0 20250511 (experimental)
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat > test.c << 'EOF'
int g, h;
int one = 1;
void foo() {
g = 0;
while(1) { // C1 - C2 ?
g++; // C1
int dummy;
if (g >= 7)
break; // C2
h++; // C1 - C2
}
g = 0;
while(1) { // No code ?
g++; // C1
// int dummy;
if (g >= 7)
break; // C2
h++; // C1 - C2
}
g = 0;
while(one) { // C1 ?
g++; // C1
int dummy;
if (g >= 7)
break; // C2
h++; // C1 - C2
}
}
int main(void) {
for (int i = 0; i < 5; i++)
foo();
}
EOF
$ gcc --coverage test.c -o test
$ ./test
$ gcov test
$ cat test.c.gcov
...
5: 5:void foo() {
5: 6: g = 0;
30: 7: while(1) { // C1 - C2 ?
35: 8: g++; // C1
-: 9: int dummy;
35: 10: if (g >= 7)
5: 11: break; // C2
30: 12: h++; // C1 - C2
-: 13: }
-: 14:
5: 15: g = 0;
-: 16: while(1) { // No code ?
35: 17: g++; // C1
-: 18: // int dummy;
35: 19: if (g >= 7)
5: 20: break; // C2
30: 21: h++; // C1 - C2
-: 22: }
-: 23:
5: 24: g = 0;
35: 25: while(one) { // C1 ?
35: 26: g++; // C1
-: 27: int dummy;
35: 28: if (g >= 7)
5: 29: break; // C2
30: 30: h++; // C1 - C2
-: 31: }
5: 32:}
...
Despite the same semantic, line coverage for line 7, 16, 25 refers to
different things. At line 7, line coverage seems to connect to the end of
loop body. This behavior is also affected by the presence or absence of
variable declaration inside the loop ("int dummy;" in the examples).