https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120348
Bug ID: 120348 Summary: Bogus line coverage triggered by passing pointers via extern "C" functions Product: gcc Version: 16.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: --- Hit the issue when measuring https://sources.debian.org/src/lzma/9.22-2.2/CPP/7zip/Compress/LzmaDecoder.cpp/#L101 where RINOK is defined as: #define RINOK(x) \ { \ int __result__ = (x); \ if (__result__ != 0) \ return __result__; \ } The direct output from gcov is: -: 96: for (;;) -: 97: { 6: 98: if (_inPos == _inSize) -: 99: { 6: 100: _inPos = _inSize = 0; 9*: 101: RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); -: 102: } A reduced reproducing step is given as follow: $ gcc --version gcc (GCC) 16.0.0 20250511 (experimental) Copyright (C) 2025 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 > src1.cc << 'EOF' int g; extern "C" { int foo(int *x); } int never; void bar() { int j = 0; while (1) { g++; if (never) { g++; return; } int l; // has to be local and in this scope foo(&l); j++; if (j == 11) return; } } int main() { for (int i = 0; i < 7; i++) bar(); return 0; } EOF $ cat > src2.c << 'EOF' int foo(int *x) { return 0; } EOF $ rm -f *.gcov *.gcda *.gcno $ g++ -c --coverage src1.cc $ gcc -c --coverage src2.c $ g++ --coverage src1.o src2.o -o prog $ ./prog $ gcov src1 $ cat src1.cc.gcov -: 0:Source:src1.cc -: 0:Graph:src1.gcno -: 0:Data:src1.gcda -: 0:Runs:1 -: 1:int g; -: 2: -: 3:extern "C" { -: 4: int foo(int *x); -: 5:} -: 6: -: 7:int never; -: 8: 7: 9:void bar() { 7: 10: int j = 0; -: 11: while (1) -: 12: { 77: 13: g++; 77: 14: if (never) { #####: 15: g++; 7*: 16: return; -: 17: } -: 18: -: 19: int l; // has to be local and in this scope 77: 20: foo(&l); -: 21: 77: 22: j++; 77: 23: if (j == 11) 7: 24: return; 70: 25: } -: 26:} -: 27: 1: 28:int main() { 8: 29: for (int i = 0; i < 7; i++) 7: 30: bar(); 1: 31: return 0; -: 32:} where line coverage for line 16 is reported to be a nonzero value. Tweaking the code format can produce what's closer to the original symptom I experienced in lzma (although the first format seems more concerning): -: 12: { 77: 13: g++; 84*: 14: if (never) { g++; return; } -: 15: