http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45890
--- Comment #2 from Sharad Singhai <singhai at gcc dot gnu.org> 2011-10-01 19:42:48 UTC --- I don't know if it is related. But the coverage is imprecise in case of attached source file foo.c. Build it with O2, as gcc --coverage -O2 foo.c ./a.out gcov -b foo.c Now the coverage data for the 'if' condition in 'sum' looks like this: (in attached file foo.c.gcov) 8: 8: if (v[i]) total += 1; branch 0 never executed branch 1 never executed branch 2 taken 75% (fallthrough) branch 3 taken 25% Thus a simple two-way conditional looks like a four-way branch. It is due to early inlining of 'sum' into 'main where a couple of bb's get eliminated/merged so that the branch coverage incorrectly gets attributed to the conditional. Similarly the coverage data for the for-loop in 'sum' looks like this 9: 7: for (i = 0; i < N; ++i) { branch 0 never executed branch 1 never executed branch 2 taken 89% branch 3 taken 11% (fallthrough) After disabling early inlining, the coverage data looks saner. (Attached in foo.c.gcov.no-early-inlining.) gcc --coverage -O2 -fno-early-inlining foo.c ./a.out gcov -b foo.c Adding the following patch mitigates the issue. 2011-09-30 Sharad Singhai <sing...@google.com> * gcc.c (cc1_options): Added -fno-early-inlining for coverage. Index: gcc.c =================================================================== --- gcc.c (revision 179402) +++ gcc.c (working copy) @@ -776,7 +776,7 @@ %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\ %{fsyntax-only:-o %j} %{-param*}\ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}\ - %{coverage:-fprofile-arcs -ftest-coverage}"; + %{coverage:-fprofile-arcs -ftest-coverage -fno-early-inlining}"; /* If an assembler wrapper is used to invoke post-assembly tools like MAO, --save-temps need to be passed to save the output of