From: James Y Knight Date: Wed, 28 Aug 2019 20:35:50 +0000 (+0000) Subject: Ignore object files that lack coverage information. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a0044c42024c69a05cc71af75e104947c7141ca;p=llvm Ignore object files that lack coverage information. Before this change, if multiple binary files were presented, all of them must have been instrumented or the load would fail with coverage_map_error::no_data_found. Patch by Dean Sturtevant. Differential Revision: https://reviews.llvm.org/D66763 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370257 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ProfileData/Coverage/CoverageMapping.h b/include/llvm/ProfileData/Coverage/CoverageMapping.h index 11758ac4cf2..7284a67ba4a 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -527,6 +527,7 @@ public: /// 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> load(ArrayRef ObjectFilenames, StringRef ProfileFilename, ArrayRef Arches = None); diff --git a/lib/ProfileData/Coverage/CoverageMapping.cpp b/lib/ProfileData/Coverage/CoverageMapping.cpp index afd6618e7cb..803605cd79f 100644 --- a/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -270,6 +270,16 @@ Expected> CoverageMapping::load( return std::move(Coverage); } +// If E is a no_data_found error, returns success. Otherwise returns E. +static Error handleMaybeNoDataFoundError(Error E) { + return handleErrors( + std::move(E), [](const CoverageMapError &CME) { + if (CME.get() == coveragemap_error::no_data_found) + return static_cast(Error::success()); + return make_error(CME.get()); + }); +} + Expected> CoverageMapping::load(ArrayRef ObjectFilenames, StringRef ProfileFilename, ArrayRef Arches) { @@ -289,12 +299,21 @@ CoverageMapping::load(ArrayRef ObjectFilenames, CovMappingBufOrErr.get()->getMemBufferRef(); auto CoverageReadersOrErr = BinaryCoverageReader::create(CovMappingBufRef, Arch, Buffers); - if (Error E = CoverageReadersOrErr.takeError()) - return std::move(E); + if (Error E = CoverageReadersOrErr.takeError()) { + E = handleMaybeNoDataFoundError(std::move(E)); + if (E) + return std::move(E); + // E == success (originally a no_data_found error). + continue; + } for (auto &Reader : CoverageReadersOrErr.get()) Readers.push_back(std::move(Reader)); Buffers.push_back(std::move(CovMappingBufOrErr.get())); } + // 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 (Readers.empty() && !ObjectFilenames.empty()) + return make_error(coveragemap_error::no_data_found); return load(Readers, *ProfileReader); } diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented new file mode 100755 index 00000000000..1a8f9b2b209 Binary files /dev/null and b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented differ diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.cc b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.cc new file mode 100644 index 00000000000..5c61d716ca1 --- /dev/null +++ b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.cc @@ -0,0 +1,5 @@ +void f1() {} + +int main(int argc, char** argv) { + f1(); +} diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.profdata b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.profdata new file mode 100644 index 00000000000..3b8a60dd720 Binary files /dev/null and b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.profdata differ diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.raw b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.raw new file mode 100644 index 00000000000..650ea7ed3a4 Binary files /dev/null and b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.raw differ diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented new file mode 100755 index 00000000000..2f9f3f2737a Binary files /dev/null and b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented differ diff --git a/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented.cc b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented.cc new file mode 100644 index 00000000000..4b10444b174 --- /dev/null +++ b/test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented.cc @@ -0,0 +1 @@ +int main(int argc, char** argv) {} diff --git a/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test b/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test new file mode 100644 index 00000000000..c3a0e846bc6 --- /dev/null +++ b/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test @@ -0,0 +1,12 @@ +RUN: llvm-cov export --format=lcov --instr-profile=%S/Inputs/multiple_objects_not_all_instrumented/instrumented.profdata \ +RUN: -object %S/Inputs/multiple_objects_not_all_instrumented/not_instrumented \ +RUN: -object %S/Inputs/multiple_objects_not_all_instrumented/instrumented | FileCheck -check-prefix=FN %s + +FN:1,_Z2f1v + +Instructions for regenerating the test: + +clang -std=c++11 not_instrumented.cc -o not_instrumented +clang -std=c++11 -mllvm -enable-name-compression=false -fprofile-instr-generate -fcoverage-mapping instrumented.cc -o instrumented +LLVM_PROFILE_FILE="instrumented.raw" ./instrumented +llvm-profdata merge instrumented.raw -o instrumented.profdata