Open
Description
Code coverage reporting is incorrect in situations like this:
// coverage.c
#include <stdio.h>
int main(int argc, char *argv[])
{
{
if (argc > 2) {
return 2;
}
printf("one\n");
}
printf("two\n");
return 0;
}
The expectation is without additional arguments both "one" and "two" will be printed and both print statements will be reported as covered, but:
# build.sh
/usr/bin/clang --version | /bin/grep "clang version"
/usr/bin/clang -fprofile-instr-generate -fcoverage-mapping coverage.c -o coverage
./coverage
/usr/bin/llvm-profdata merge -sparse default.profraw -o default.profdata
/usr/bin/llvm-cov show ./coverage -instr-profile=default.profdata
The coverage report incorrectly marks the second printf
statement as uncovered:
$ ./build.sh
clang version 21.0.0
one
two
1| |#include <stdio.h>
2| |
3| |int main(int argc, char *argv[])
4| 1|{
5| 1| {
6| 1| if (argc > 2) {
7| 0| return 2;
8| 0| }
9| 1| printf("one\n");
10| 1| }
11| 0| printf("two\n"); // INCORRECT
12| 1| return 0;
13| 1|}
It appears related to the region-terminating statement in the conditional. The same behavior appears with abort()
or goto
instead of return 2
, for example. But the behavior disappears if the statement is non-region-terminating:
$ ./build.sh
clang version 21.0.0
one
two
1| |#include <stdio.h>
2| |
3| |int main(int argc, char *argv[])
4| 1|{
5| 1| {
6| 1| if (argc > 2) {
7| 0| printf("zero\n"); // NO LONGER TERMINATING
8| 0| }
9| 1| printf("one\n");
10| 1| }
11| 1| printf("two\n"); // NOW CORRECT
12| 1| return 0;
13| 1|}
I have not narrowed down if this is a region mapping issue versus an llvm-cov reporting issue.