Index: llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h =================================================================== --- llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -603,7 +603,7 @@ /// Load the coverage mapping from the given object files and profile. If /// \p Arches is non-empty, it must specify an architecture for each object. /// Ignores non-instrumented object files unless all are not instrumented. - static Expected> + static std::pair>, StringRef> load(ArrayRef ObjectFilenames, StringRef ProfileFilename, ArrayRef Arches = None, StringRef CompilationDir = ""); Index: llvm/lib/ProfileData/Coverage/CoverageMapping.cpp =================================================================== --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -343,13 +343,13 @@ }); } -Expected> +std::pair>, StringRef> CoverageMapping::load(ArrayRef ObjectFilenames, StringRef ProfileFilename, ArrayRef Arches, StringRef CompilationDir) { auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); if (Error E = ProfileReaderOrErr.takeError()) - return std::move(E); + return {std::move(E), ProfileFilename}; auto ProfileReader = std::move(ProfileReaderOrErr.get()); auto Coverage = std::unique_ptr(new CoverageMapping()); bool DataFound = false; @@ -358,7 +358,7 @@ auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN( File.value(), /*IsText=*/false, /*RequiresNullTerminator=*/false); if (std::error_code EC = CovMappingBufOrErr.getError()) - return errorCodeToError(EC); + return {errorCodeToError(EC), File.value()}; StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()]; MemoryBufferRef CovMappingBufRef = CovMappingBufOrErr.get()->getMemBufferRef(); @@ -368,7 +368,7 @@ if (Error E = CoverageReadersOrErr.takeError()) { E = handleMaybeNoDataFoundError(std::move(E)); if (E) - return std::move(E); + return {std::move(E), File.value()}; // E == success (originally a no_data_found error). continue; } @@ -378,13 +378,13 @@ Readers.push_back(std::move(Reader)); DataFound |= !Readers.empty(); if (Error E = loadFromReaders(Readers, *ProfileReader, *Coverage)) - return std::move(E); + return {std::move(E), File.value()}; } // If no readers were created, either no objects were provided or none of them // had coverage data. Return an error in the latter case. if (!DataFound && !ObjectFilenames.empty()) - return make_error(coveragemap_error::no_data_found); - return std::move(Coverage); + return {make_error(coveragemap_error::no_data_found), ""}; + return {std::move(Coverage), ""}; } namespace { Index: llvm/test/tools/llvm-cov/missing-binaries.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-cov/missing-binaries.test @@ -0,0 +1,4 @@ +RUN: llvm-profdata merge %S/Inputs/binary-formats.proftext -o %t.profdata +RUN: not llvm-cov show -instr-profile=%t.profdata --object=%t.nonexistent.binary.1 --object=%t.nonexistent.binary.2 2>&1 | FileCheck %s + +CHECK: nonexistent.binary.1: Failed to load coverage: Index: llvm/tools/llvm-cov/CodeCoverage.cpp =================================================================== --- llvm/tools/llvm-cov/CodeCoverage.cpp +++ llvm/tools/llvm-cov/CodeCoverage.cpp @@ -432,15 +432,15 @@ if (modifiedTimeGT(ObjectFilename, PGOFilename)) warning("profile data may be out of date - object is newer", ObjectFilename); - auto CoverageOrErr = + auto CoveragePair = CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches, ViewOpts.CompilationDirectory); - if (Error E = CoverageOrErr.takeError()) { + if (Error E = CoveragePair.first.takeError()) { error("Failed to load coverage: " + toString(std::move(E)), - join(ObjectFilenames.begin(), ObjectFilenames.end(), ", ")); + CoveragePair.second); return nullptr; } - auto Coverage = std::move(CoverageOrErr.get()); + auto Coverage = std::move(CoveragePair.first.get()); unsigned Mismatched = Coverage->getMismatchedCount(); if (Mismatched) { warning(Twine(Mismatched) + " functions have mismatched data");