https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116452
Bug ID: 116452 Summary: Inconsistent way of reporting negative counter values Product: gcc Version: 15.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: --- Currently branch coverage will report negative counter values as is [1] but line coverage will report 0 [2]. [1] https://github.com/gcc-mirror/gcc/blob/ec9d6d45191f639482344362d048294e74587ca3/gcc/gcov.cc#L3186 [2] https://github.com/gcc-mirror/gcc/blob/ec9d6d45191f639482344362d048294e74587ca3/gcc/gcov.cc#L3276 As a result, the following could happen: 995861: 11:void g() { 995861: 12: if (x % 10000) branch 0 taken 995986 (fallthrough) branch 1 taken -125 995986: 13: ++y; -: 14: else #####: 15: --y; 995861: 16:} Branch 1 is reportedly taken "-125 times" and line 15 is executed 0 time. --- How to reproduce: $ gcc --version gcc (GCC) 15.0.0 20240808 (experimental) Copyright (C) 2024 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 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 10000 int x; int y; void g() { if (x % 10000) ++y; else --y; } void* f(void* thread_id) { x++; for (int i = 0; i < 100; i++) g(); pthread_exit(NULL); } int main() { pthread_t threads[NUM_THREADS]; long t; for(t = 0; t < NUM_THREADS; t++) pthread_create(&threads[t], NULL, f, (void*)t); for(t = 0; t < NUM_THREADS; t++) pthread_join(threads[t], NULL); return 0; } EOF $ gcc --coverage -fprofile-update=single test.c -o test $ ./test $ gcov -b -c test $ cat test.c.gcov