Files
clang-p2996/compiler-rt/test/profile/Posix/gcov-file-change.cpp
int-zjt b6b8fa3b15 [llvm-cov][gcov] Support multi-files coverage in one basic block (#144504)
In the current gcov implementation, all lines within a basic block are
attributed to the source file of the block's containing function. This
is inaccurate when a block contains lines from other files (e.g., via
#include "foo.inc").

Commit
[406e81b](406e81b79d)
attempted to address this by filtering lines based on debug info types,
but this approach has two limitations:

* **Over-filtering**: Some valid lines belonging to the function are
incorrectly excluded.
* **Under-counting**: Lines not belonging to the function are filtered
out and omitted from coverage statistics.

**GCC Reference Behavior**
GCC's gcov implementation handles this case correctly.This change aligns
the LLVM behavior with GCC.

**Proposed Solution**
1. **GCNO Generation**:

* **Current**: Each block stores a single GCOVLines record (filename +
lines).

* **New**: Dynamically create new GCOVLines records whenever consecutive
lines in a block originate from different source files. Group subsequent
lines from the same file under one record.

2. **GCNO Parsing**:

* **Current**: Lines are directly attributed to the function's source
file.

* **New**: Introduce a GCOVLocation type to track filename/line mappings
within blocks. Statistics will reflect the actual source file for each
line.
2025-06-20 01:24:19 -07:00

40 lines
1.3 KiB
C++

// RUN: rm -rf %t && split-file %s %t && cd %t
// RUN: %clangxx --coverage main.cpp -o t
// RUN: %run ./t
// RUN: llvm-cov gcov -t t-main. | FileCheck %s
//--- main.cpp
#include "a.h"
#include <stdio.h>
// CHECK: Runs:1
/// __cxx_global_var_init contains a block from a.h. Don't attribute its lines to main.cpp.
// CHECK-NOT: {{^ +[0-9]+:}}
inline auto *const inl_var_main = // CHECK: 1: [[#]]:inline auto
new A; // CHECK-NEXT: 1: [[#]]:
void foo(int x) { // CHECK-NEXT: 1: [[#]]:
if (x) { // CHECK-NEXT: 1: [[#]]:
#include "a.inc"
} // CHECK: 1: [[#]]:
} // CHECK-NEXT: 1: [[#]]:
// CHECK-NOT: {{^ +[0-9]+:}}
int main(int argc, char *argv[]) { // CHECK: 1: [[#]]:int main
foo(1); // CHECK-NEXT: 1: [[#]]:
} // CHECK-NEXT: 1: [[#]]:
// CHECK-NOT: {{^ +[0-9]+:}}
// CHECK: Source:a.h
// CHECK: 1: 1:struct A
// CHECK-NOT: {{^ +[0-9]+:}}
//--- a.h
/// Apple targets doesn't enable -mconstructor-aliases by default and the count may be 4.
struct A { A() { } }; // CHECK: {{[24]}}: [[#]]:struct A
inline auto *const inl_var_a = // CHECK-NEXT: 1: [[#]]:
new A; // CHECK-NEXT: 1: [[#]]:
//--- a.inc
puts(""); // CHECK: 1: [[#]]:puts