diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -232,6 +232,13 @@ BinaryCoverageReader::DecompressedData &Decompressed); }; +// Whether to ignore coverage mapping regions that are invalid, for example +// regions for which the frontend has indicated the start location comes after +// the end location. These are typically bugs in the frontend generating source +// location information, but by enabling this option users can have coverage +// information for regions such as these silently ignored. +extern cl::opt IgnoreMalformedCoverageMappingRegions; + } // end namespace coverage } // end namespace llvm diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -45,6 +45,11 @@ STATISTIC(CovMapNumRecords, "The # of coverage function records"); STATISTIC(CovMapNumUsedRecords, "The # of used coverage function records"); +cl::opt coverage::IgnoreMalformedCoverageMappingRegions( + "ignore-malformed-coverage-mapping-regions", + cl::desc("Ignore malformed code coverage mapping regions"), + cl::init(false)); + void CoverageMappingIterator::increment() { if (ReadErr != coveragemap_error::success) return; @@ -297,8 +302,16 @@ auto CMR = CounterMappingRegion(C, InferredFileID, ExpandedFileID, LineStart, ColumnStart, LineStart + NumLines, ColumnEnd, Kind); - if (CMR.startLoc() > CMR.endLoc()) - return make_error(coveragemap_error::malformed); + if (CMR.startLoc() > CMR.endLoc()) { + LLVM_DEBUG(dbgs() << "Malformed coverage mapping region: " + << CMR.startLoc().first << ":" << CMR.startLoc().second + << " -> " << CMR.endLoc().first << ":" + << CMR.endLoc().second << "\n"); + if (IgnoreMalformedCoverageMappingRegions) + continue; + else + return make_error(coveragemap_error::malformed); + } MappingRegions.push_back(CMR); } return Error::success(); diff --git a/llvm/test/tools/llvm-cov/warnings.h b/llvm/test/tools/llvm-cov/warnings.h --- a/llvm/test/tools/llvm-cov/warnings.h +++ b/llvm/test/tools/llvm-cov/warnings.h @@ -14,3 +14,6 @@ // RUN: not llvm-cov report %S/Inputs/malformedRegions.covmapping -instr-profile %S/Inputs/elf_binary_comdat.profdata 2>&1 | FileCheck %s -check-prefix=MALFORMED-REGION // MALFORMED-REGION: malformedRegions.covmapping: Failed to load coverage: Malformed coverage data +// RUN: llvm-cov report -ignore-malformed-coverage-mapping-regions %S/Inputs/malformedRegions.covmapping -instr-profile %S/Inputs/elf_binary_comdat.profdata 2>&1 | FileCheck %s -check-prefix=IGNORE-MALFORMED-REGION +// IGNORE-MALFORMED-REGION: warning: 1 functions have mismatched data +// IGNORE-MALFORMED-REGION-NOT: Failed to load coverage