Skip to content

Commit 1f34e28

Browse files
committed
[gcov] Ignore blocks from another file
Constructs such as inline variables, #line, and #include can create lexical blocks with a different filename. GCOVProfiling and llvm-cov gcov currently don't handle such cases (see GCOVLines::writeOut and GCOVFile::readGCNO) and would incorrectly attribute the line number to the current file. For now, ignore such blocks. Missing line execution counts is better than wrong ones.
1 parent 182de29 commit 1f34e28

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: rm -rf %t && split-file %s %t && cd %t
2+
// RUN: %clangxx --coverage main.cpp -o t
3+
// RUN: %run ./t
4+
// RUN: llvm-cov gcov -t t-main. | FileCheck %s
5+
6+
//--- main.cpp
7+
#include "a.h"
8+
#include <stdio.h>
9+
10+
// CHECK: Runs:1
11+
/// __cxx_global_var_init contains a block from a.h. Don't attribute its lines to main.cpp.
12+
// CHECK-NOT: {{^ +[0-9]+:}}
13+
14+
inline auto *const inl_var_main = // CHECK: 1: [[#]]:inline auto
15+
new A; // CHECK-NEXT: 1: [[#]]:
16+
void foo(int x) { // CHECK-NEXT: 1: [[#]]:
17+
if (x) { // CHECK-NEXT: 1: [[#]]:
18+
#include "a.inc"
19+
}
20+
}
21+
// CHECK-NOT: {{^ +[0-9]+:}}
22+
23+
int main(int argc, char *argv[]) { // CHECK: 1: [[#]]:int main
24+
foo(1); // CHECK-NEXT: 1: [[#]]:
25+
} // CHECK-NEXT: 1: [[#]]:
26+
// CHECK-NOT: {{^ +[0-9]+:}}
27+
28+
// CHECK: Source:a.h
29+
// CHECK: 1: 1:struct A
30+
// CHECK-NOT: {{^ +[0-9]+:}}
31+
32+
//--- a.h
33+
struct A { A() { } }; // CHECK: 2: [[#]]:struct A
34+
inline auto *const inl_var_a =
35+
new A;
36+
/// TODO a.inc:1 should have line execution.
37+
// CHECK-NOT: {{^ +[0-9]+:}}
38+
39+
//--- a.inc
40+
puts("");

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,9 @@ bool GCOVProfiler::emitProfileNotes(
898898

899899
if (Line == Loc.getLine()) continue;
900900
Line = Loc.getLine();
901-
if (SP != getDISubprogram(Loc.getScope()))
901+
MDNode *Scope = Loc.getScope();
902+
// TODO: Handle blocks from another file due to #line, #include, etc.
903+
if (isa<DILexicalBlockFile>(Scope) || SP != getDISubprogram(Scope))
902904
continue;
903905

904906
GCOVLines &Lines = Block.getFile(Filename);

0 commit comments

Comments
 (0)