Skip to content

[coverage] __noreturn__ attribute leads to incorrect coverage report #124296

@justincady

Description

@justincady

The __noreturn__ attribute appears to invalidate coverage of the following line, whereas _Noreturn demonstrates correct behavior.

// coverage.c
#include <stdio.h>

__attribute__ ((__noreturn__)) void foo(void) { while (1); }
_Noreturn void bar(void) { while (1); }

int main(int argc, char **argv) {
    int rc = ({ if (argc > 3) foo(); 0; });
    printf("coverage after foo is missing\n");

    int rc2 = ({ if (argc > 3) bar(); 0; });
    printf("coverage after bar is present\n");
    return rc + rc2;
}
# 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

Running the script:

$ ./build.sh
clang version 19.1.1 (Red Hat, Inc. 19.1.1-5.el10)
coverage after foo is missing
coverage after bar is present
    1|       |#include <stdio.h>
    2|       |
    3|      0|__attribute__ ((__noreturn__)) void foo(void) { while (1); }
    4|      0|_Noreturn void bar(void) { while (1); }
    5|       |
    6|      1|int main(int argc, char **argv) {
    7|      1|    int rc = ({ if (argc > 3) foo(); 0; });
    8|      0|    printf("coverage after foo is missing\n");
    9|       |
   10|      1|    int rc2 = ({ if (argc > 3) bar(); 0; });
   11|      1|    printf("coverage after bar is present\n");
   12|      1|    return rc + rc2;
   13|      1|}

$
  • Line 8 is reported as uncovered, though it prints as expected. (incorrect behavior)
  • Line 11 is reported as covered, and prints as expected. (correct behavior)

This seems like a bug connected to __noreturn__. FWIW I also tested this in C++ and observed the same results.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions