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:}