Index: llvm/lib/ProfileData/GCOV.cpp =================================================================== --- llvm/lib/ProfileData/GCOV.cpp +++ llvm/lib/ProfileData/GCOV.cpp @@ -13,6 +13,7 @@ #include "llvm/ProfileData/GCOV.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/Config/llvm-config.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/Debug.h" @@ -662,6 +663,8 @@ if (f.startLine >= si.startLineToFunctions.size()) si.startLineToFunctions.resize(f.startLine + 1); si.startLineToFunctions[f.startLine].push_back(&f); + llvm::SmallSet lines; + llvm::SmallSet linesExec; for (const GCOVBlock &b : f.blocksRange()) { if (b.lines.empty()) continue; @@ -670,9 +673,9 @@ si.lines.resize(maxLineNum + 1); for (uint32_t lineNum : b.lines) { LineInfo &line = si.lines[lineNum]; - if (!line.exists) + if (lines.insert(lineNum).second) ++summary.lines; - if (line.count == 0 && b.count) + if (b.count && linesExec.insert(lineNum).second) ++summary.linesExec; line.exists = true; line.count += b.count; Index: llvm/test/tools/llvm-cov/gcov/tmpl.cpp =================================================================== --- /dev/null +++ llvm/test/tools/llvm-cov/gcov/tmpl.cpp @@ -0,0 +1,13 @@ +// Check that the coverage statistics for a template function is calculated. + +// RUN: llvm-cov gcov %s --gcno=%p/Inputs/tmpl.gcno --gcda=%p/Inputs/tmpl.gcda -f | FileCheck %s + +// CHECK: Function '_Z4testILi1EEiv' +// CHECK-NEXT: Lines executed:100.00% of 1 +// CHECK: Function '_Z4testILi2EEiv' +// CHECK-NEXT: Lines executed:100.00% of 1 + +template +int test() { return N; } + +int main() { return test<1>() + test<2>(); }