]> granicus.if.org Git - llvm/commitdiff
Ignore object files that lack coverage information.
authorJames Y Knight <jyknight@google.com>
Wed, 28 Aug 2019 20:35:50 +0000 (20:35 +0000)
committerJames Y Knight <jyknight@google.com>
Wed, 28 Aug 2019 20:35:50 +0000 (20:35 +0000)
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

include/llvm/ProfileData/Coverage/CoverageMapping.h
lib/ProfileData/Coverage/CoverageMapping.cpp
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented [new file with mode: 0755]
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.cc [new file with mode: 0644]
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.profdata [new file with mode: 0644]
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/instrumented.raw [new file with mode: 0644]
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented [new file with mode: 0755]
test/tools/llvm-cov/Inputs/multiple_objects_not_all_instrumented/not_instrumented.cc [new file with mode: 0644]
test/tools/llvm-cov/multiple-objects-not-all-instrumented.test [new file with mode: 0644]

index 11758ac4cf2fa247665b60e51e235b02a3f3b19c..7284a67ba4a059962582318829f3791fc7286a97 100644 (file)
@@ -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<std::unique_ptr<CoverageMapping>>
   load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
        ArrayRef<StringRef> Arches = None);
index afd6618e7cb3ee858b265ea65c9a0c23d202fd16..803605cd79fa83dd26820909230b1a452eba4ba3 100644 (file)
@@ -270,6 +270,16 @@ Expected<std::unique_ptr<CoverageMapping>> 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>(Error::success());
+        return make_error<CoverageMapError>(CME.get());
+      });
+}
+
 Expected<std::unique_ptr<CoverageMapping>>
 CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
                       StringRef ProfileFilename, ArrayRef<StringRef> Arches) {
@@ -289,12 +299,21 @@ CoverageMapping::load(ArrayRef<StringRef> 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<CoverageMapError>(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 (executable)
index 0000000..1a8f9b2
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 (file)
index 0000000..5c61d71
--- /dev/null
@@ -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 (file)
index 0000000..3b8a60d
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 (file)
index 0000000..650ea7e
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 (executable)
index 0000000..2f9f3f2
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 (file)
index 0000000..4b10444
--- /dev/null
@@ -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 (file)
index 0000000..c3a0e84
--- /dev/null
@@ -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