https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120332

            Bug ID: 120332
           Summary: Line coverage for labels refers to implicit "else"
                    clauses before it
           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/lzo2/2.10-2/src/lzo1x_d.ch/#L166

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;

void foo(int a, int b) {
    if (a) {
        g++;
        if (b) {
            g++;
        } // C_else_2
    } // C_else_1

    // g++; // Uncommenting this changes the behavior

L1: // C_else_1 + C_else_2

    if (a) {
        g++;
        if (b) {
            g++;
        } else {
            g--; // C_else_2
        }
    } // C_else_1

    // g++; // Uncommenting this changes the behavior

L2: // C_else_1

    return;
}

int main(void) {
    for (int i = 0; i < 1; i++)
        foo(0, 0);
    for (int i = 0; i < 20; i++)
        foo(1, 0);
    for (int i = 0; i < 300; i++)
        foo(0, 1);
    for (int i = 0; i < 4000; i++)
        foo(1, 1);
}
EOF

$ gcc --coverage test.c -o test
$ ./test
$ gcov test
$ cat test.c.gcov
...
     4321:    3:void foo(int a, int b) {
     4321:    4:    if (a) {
     4020:    5:        g++;
     4020:    6:        if (b) {
     4000:    7:            g++;
        -:    8:        } // C_else_2
        -:    9:    } // C_else_1
        -:   10:
        -:   11:    // g++; // Uncommenting this changes the behavior
        -:   12:
      321:   13:L1: // C_else_1 + C_else_2
        -:   14:
     4321:   15:    if (a) {
     4020:   16:        g++;
     4020:   17:        if (b) {
     4000:   18:            g++;
        -:   19:        } else {
       20:   20:            g--; // C_else_2
        -:   21:        }
        -:   22:    } // C_else_1
        -:   23:
        -:   24:    // g++; // Uncommenting this changes the behavior
        -:   25:
      301:   26:L2: // C_else_1
        -:   27:
     4321:   28:    return;
        -:   29:}
...

This is suboptimal as users generally expect (1) the same number as the next 
statement (2) (less commonly) how many times this label is goto'ed.

I don't know for sure at the stage of gcov instrumentation is there still
ways of doing such mapping?

Reply via email to