https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128295
Bug ID: 128295
Summary: Coverage counts __attribute__((assume)) as a branch, a
condition and a call that can never be covered
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: gcov-profile
Assignee: unassigned at gcc dot gnu.org
Reporter: chfast at gmail dot com
CC: chfast at gmail dot com
Target Milestone: ---
int f(int n)
{
__attribute__((assume(n <= 4)));
return n * 2;
}
int main() { return f(3) - 6; }
$ g++ --coverage -fcondition-coverage -O0 -c t.cpp && g++ --coverage t.o &&
./a.out && gcov -b -g --conditions t.cpp
GCC 16.2 t.cpp.gcov:
1: 1:int f(int n)
-: 2:{
1*: 3: __attribute__((assume(n <= 4)));
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
call 2 never executed
condition outcomes covered 1/2
condition 0 not covered (false)
1: 4: return n * 2;
-: 5:}
The assumption is gimplified to if (n <= 4) ... else __builtin_unreachable (),
and the instrumentation counts that as a branch, a condition and a call. The
line is reported as partially executed, with a branch, a condition outcome and
a call that can only be covered by violating the assumption. The expression of
an assumption is not evaluated, so we expect no branch, condition or call on
this line.
The same with [[assume(n <= 4)]] (-std=c++23), with -fno-unreachable-traps, at
-Og, -O1 and -O2 (f noinline), and with GCC 15.2.
We hit this in intx (a multi-precision integer library), where lines with
assumptions keep branch and condition coverage below 100%.