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

            Bug ID: 90104
           Summary: [GCOV] Wrong coverage for variable arguments function
                    call statement while the function is inline function
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: gcov-profile
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yangyibiao at nju dot edu.cn
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/9.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --enable-languages=c,c++
--disable-multilib --prefix=/usr/local/gcc-trunk
Thread model: posix
gcc version 9.0.1 20190414 (experimental) (GCC) 

$ cat small.c
#include <stdarg.h>

extern void abort (void);
long x = 0, y = 0;

inline void __attribute__((always_inline))
f1i (va_list ap)
{
  x = va_arg (ap, double);
  x += va_arg (ap, long);
}

void f4 (int i, ...)
{
  va_list ap;

  va_start (ap, i);
  switch (i)
  {
    case 4:
      y = va_arg (ap, double);
      break;
    case 5:
      y = va_arg (ap, double);
      y += va_arg (ap, double);
      break;
    default:
      ; // abort ();
  }
  f1i (ap);
  va_end (ap);
}

int main ()
{
  f4 (4, 6.0, 9.0, 16L, 18.0);
  return 0;
}

$ rm small.g*; gcc -O0 --coverage small.c -w; ./a.out; gcov small.c; cat
small.c.gcov
File 'small.c'
Lines executed:78.95% of 19
Creating 'small.c.gcov'

        -:    0:Source:small.c
        -:    0:Graph:small.gcno
        -:    0:Data:small.gcda
        -:    0:Runs:1
        -:    1:#include <stdarg.h>
        -:    2:
        -:    3:extern void abort (void);
        -:    4:long x = 0, y = 0;
        -:    5:
        -:    6:inline void __attribute__((always_inline))
        -:    7:f1i (va_list ap)
        -:    8:{
        2:    9:  x = va_arg (ap, double);
        1:   10:  x += va_arg (ap, long);
        1:   11:}
        -:   12:
        1:   13:void f4 (int i, ...)
        -:   14:{
        -:   15:  va_list ap;
        -:   16:
        1:   17:  va_start (ap, i);
        1:   18:  switch (i)
        -:   19:  {
        1:   20:    case 4:
        1:   21:      y = va_arg (ap, double);
        1:   22:      break;
    #####:   23:    case 5:
    #####:   24:      y = va_arg (ap, double);
    #####:   25:      y += va_arg (ap, double);
    #####:   26:      break;
        1:   27:    default:
        -:   28:      ; // abort ();
        -:   29:  }
        -:   30:  f1i (ap);
        1:   31:  va_end (ap);
        1:   32:}
        -:   33:
        1:   34:int main ()
        -:   35:{
        1:   36:  f4 (4, 6.0, 9.0, 16L, 18.0);
        1:   37:  return 0;
        -:   38:}

Line #9 is wrongly marked as executed twice. 

While Line #28 is removed, the result is correct as follows: 

$ gcc -O0 --coverage small.c -w; ./a.out; gcov small.c; cat small.c.gcov
File 'small.c'
Lines executed:70.00% of 20
Creating 'small.c.gcov'

        -:    0:Source:small.c
        -:    0:Graph:small.gcno
        -:    0:Data:small.gcda
        -:    0:Runs:1
        -:    1:#include <stdarg.h>
        -:    2:
        -:    3:extern void abort (void);
        -:    4:long x = 0, y = 0;
        -:    5:
        -:    6:inline void __attribute__((always_inline))
        -:    7:f1i (va_list ap)
        -:    8:{
        1:    9:  x = va_arg (ap, double);
        1:   10:  x += va_arg (ap, long);
        1:   11:}
        -:   12:
        1:   13:void f4 (int i, ...)
        -:   14:{
        -:   15:  va_list ap;
        -:   16:
        1:   17:  va_start (ap, i);
        1:   18:  switch (i)
        -:   19:  {
        1:   20:    case 4:
        1:   21:      y = va_arg (ap, double);
        1:   22:      break;
    #####:   23:    case 5:
    #####:   24:      y = va_arg (ap, double);
    #####:   25:      y += va_arg (ap, double);
    #####:   26:      break;
    #####:   27:    default:
    #####:   28:      abort ();
        -:   29:  }
        -:   30:  f1i (ap);
        1:   31:  va_end (ap);
        1:   32:}
        -:   33:
        1:   34:int main ()
        -:   35:{
        1:   36:  f4 (4, 6.0, 9.0, 16L, 18.0);
        1:   37:  return 0;
        -:   38:}

Reply via email to