Relands #130976 with adjustments to test requirements. Calls to __noreturn__ functions result in region termination for coverage mapping. But this creates incorrect coverage results when __noreturn__ functions (or other constructs that result in region termination) occur within [GNU statement expressions][1]. In this scenario an extra gap region is introduced within VisitStmt, such that if the following line does not introduce a new region it is unconditionally counted as uncovered. This change adjusts the mapping such that terminate statements within statement expressions do not propagate that termination state after the statement expression is processed. [1]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Fixes #124296
25 lines
1.3 KiB
C++
25 lines
1.3 KiB
C++
// REQUIRES: lld-available
|
|
// XFAIL: powerpc64-target-arch
|
|
|
|
// RUN: %clangxx_profgen -std=gnu++17 -fuse-ld=lld -fcoverage-mapping -o %t %s
|
|
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
|
|
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
|
|
// RUN: llvm-cov show %t -instr-profile=%t.profdata 2>&1 | FileCheck %s
|
|
|
|
#include <stdio.h>
|
|
|
|
// clang-format off
|
|
__attribute__ ((__noreturn__))
|
|
void foo(void) { while (1); } // CHECK: [[@LINE]]| 0|void foo(void)
|
|
_Noreturn void bar(void) { while (1); } // CHECK: [[@LINE]]| 0|_Noreturn void bar(void)
|
|
// CHECK: [[@LINE]]| |
|
|
int main(int argc, char **argv) { // CHECK: [[@LINE]]| 1|int main(
|
|
int rc = ({ if (argc > 3) foo(); 0; }); // CHECK: [[@LINE]]| 1| int rc =
|
|
printf("coverage after foo is present\n"); // CHECK: [[@LINE]]| 1| printf(
|
|
// CHECK: [[@LINE]]| |
|
|
int rc2 = ({ if (argc > 3) bar(); 0; }); // CHECK: [[@LINE]]| 1| int rc2 =
|
|
printf("coverage after bar is present\n"); // CHECK: [[@LINE]]| 1| printf(
|
|
return rc + rc2; // CHECK: [[@LINE]]| 1| return rc
|
|
} // CHECK: [[@LINE]]| 1|}
|
|
// clang-format on
|