llvm-cov: Simplify coverage reports, fixing PR22575 in the process

PR22575 occurred because we were unsafely storing references into a
std::vector. If the vector moved because it grew, we'd be left
iterating through garbage memory. This avoids the issue by simplifying
the logic to gather coverage information as we go, rather than storing
it and iterating over it.

I'm relying on the existing tests showing that this is semantically
NFC, since it's difficult to hit the issue this fixes without
relatively large covered programs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229215 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Justin Bogner
2015-02-14 02:01:24 +00:00
parent 894c8c514a
commit 9bdb194b86
8 changed files with 67 additions and 168 deletions

View File

@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CoverageReport.h"
#include "CoverageSummary.h"
#include "RenderingSupport.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
@ -158,12 +157,12 @@ void CoverageReport::render(const FunctionCoverageSummary &Function,
void CoverageReport::renderFunctionReports(raw_ostream &OS) {
bool isFirst = true;
for (const auto &File : Summary.getFileSummaries()) {
for (StringRef Filename : Coverage->getUniqueSourceFiles()) {
if (isFirst)
isFirst = false;
else
OS << "\n";
OS << "File '" << File.Name << "':\n";
OS << "File '" << Filename << "':\n";
OS << column("Name", FunctionReportColumns[0])
<< column("Regions", FunctionReportColumns[1], Column::RightAlignment)
<< column("Miss", FunctionReportColumns[2], Column::RightAlignment)
@ -174,13 +173,19 @@ void CoverageReport::renderFunctionReports(raw_ostream &OS) {
OS << "\n";
renderDivider(FunctionReportColumns, OS);
OS << "\n";
for (const auto &Function : File.FunctionSummaries)
FunctionCoverageSummary Totals("TOTAL");
for (const auto &F : Coverage->getCoveredFunctions(Filename)) {
FunctionCoverageSummary Function = FunctionCoverageSummary::get(F);
++Totals.ExecutionCount;
Totals.RegionCoverage += Function.RegionCoverage;
Totals.LineCoverage += Function.LineCoverage;
render(Function, OS);
renderDivider(FunctionReportColumns, OS);
OS << "\n";
render(FunctionCoverageSummary("TOTAL", /*ExecutionCount=*/0,
File.RegionCoverage, File.LineCoverage),
OS);
}
if (Totals.ExecutionCount) {
renderDivider(FunctionReportColumns, OS);
OS << "\n";
render(Totals, OS);
}
}
}
@ -194,9 +199,17 @@ void CoverageReport::renderFileReports(raw_ostream &OS) {
<< "\n";
renderDivider(FileReportColumns, OS);
OS << "\n";
for (const auto &File : Summary.getFileSummaries())
render(File, OS);
FileCoverageSummary Totals("TOTAL");
for (StringRef Filename : Coverage->getUniqueSourceFiles()) {
FileCoverageSummary Summary(Filename);
for (const auto &F : Coverage->getCoveredFunctions(Filename)) {
FunctionCoverageSummary Function = FunctionCoverageSummary::get(F);
Summary.addFunction(Function);
Totals.addFunction(Function);
}
render(Summary, OS);
}
renderDivider(FileReportColumns, OS);
OS << "\n";
render(Summary.getCombinedFileSummaries(), OS);
render(Totals, OS);
}