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