https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99441
Bug ID: 99441 Summary: [GCOV] Wrong coverage with complex "if" condition Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: njuwy at smail dot nju.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/libexec/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.2.0 (GCC) $ cat test.c typedef __SIZE_TYPE__ size_t; typedef __UINTPTR_TYPE__ uintptr_t; struct S { int a; unsigned short b; int c, d, e; long f, g, h; int i, j; }; static struct S *k; static size_t l = 1; int m; static int bar(void) { unsigned i; int j; if (k[0].c == 0) { ++m; size_t n = l * 2; struct S *o; k = (struct S *)__builtin_realloc(k, sizeof(struct S) * n); for (i = l; i < n; i++) { void *p = (void *)&k[i]; int q = 0; size_t r = sizeof(struct S); if ((((uintptr_t)p) % __alignof__(long)) == 0 && r % sizeof(long) == 0) { long __attribute__((may_alias)) *s = (long *)p; long *t = (long *)((char *)s + r); while (s < t) *s++ = 0; } else __builtin_memset(p, q, r); } } return 1; } int main() { k = (struct S *)__builtin_malloc(sizeof(struct S)); __builtin_memset(k, '\0', sizeof(struct S)); k->a = -1; for (int i = 0; i < 15; ++i) bar(); } $ gcc -O0 --coverage test.c;./a.out;gcov test;cat test.c.gcov libgcov profiling error:/home/wangyang/coverage/found bug/gcc/test.gcda:overwriting an existing profile data with a different timestamp File 'test.c' Lines executed:95.45% of 22 Creating 'test.c.gcov' -: 0:Source:test.c -: 0:Graph:test.gcno -: 0:Data:test.gcda -: 0:Runs:1 -: 1:typedef __SIZE_TYPE__ size_t; -: 2:typedef __UINTPTR_TYPE__ uintptr_t; -: 3: -: 4:struct S { -: 5: int a; -: 6: unsigned short b; -: 7: int c, d, e; -: 8: long f, g, h; -: 9: int i, j; -: 10:}; -: 11:static struct S *k; -: 12:static size_t l = 1; -: 13:int m; -: 14: 15: 15:static int bar(void) { -: 16: unsigned i; -: 17: int j; 15: 18: if (k[0].c == 0) { 15: 19: ++m; 15: 20: size_t n = l * 2; -: 21: struct S *o; 15: 22: k = (struct S *)__builtin_realloc(k, sizeof(struct S) * n); 30: 23: for (i = l; i < n; i++) { 15: 24: void *p = (void *)&k[i]; 15: 25: int q = 0; 15: 26: size_t r = sizeof(struct S); 30: 27: if ((((uintptr_t)p) % __alignof__(long)) == 0 && r % sizeof(long) == 0) { 15: 28: long __attribute__((may_alias)) *s = (long *)p; 15: 29: long *t = (long *)((char *)s + r); 120: 30: while (s < t) 105: 31: *s++ = 0; -: 32: } else #####: 33: __builtin_memset(p, q, r); -: 34: } -: 35: } 15: 36: return 1; -: 37:} -: 38: 1: 39:int main() { 1: 40: k = (struct S *)__builtin_malloc(sizeof(struct S)); 1: 41: __builtin_memset(k, '\0', sizeof(struct S)); 1: 42: k->a = -1; 16: 43: for (int i = 0; i < 15; ++i) 15: 44: bar(); -: 45:} Line #27 should only be executed 15 times