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).

Reply via email to