[llvm] r312814 - [Coverage] Report errors when reading malformed source regions

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 8 11:44:47 PDT 2017


Author: vedantk
Date: Fri Sep  8 11:44:47 2017
New Revision: 312814

URL: http://llvm.org/viewvc/llvm-project?rev=312814&view=rev
Log:
[Coverage] Report errors when reading malformed source regions

Each source region has a start and end location. Report an error when
the end location does not precede the begin location.

The old lineExecutionCounts.covmapping test actually had a buggy source
region in it. This commit introduces a regenerated copy of the coverage
and moves the old copy to malformedRegions.covmapping, for a test.

Differential Revision: https://reviews.llvm.org/D37387

Added:
    llvm/trunk/test/tools/llvm-cov/Inputs/malformedRegions.covmapping
      - copied, changed from r312813, llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping
Modified:
    llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
    llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
    llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp
    llvm/trunk/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
    llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping
    llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.json
    llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp
    llvm/trunk/test/tools/llvm-cov/warnings.h

Modified: llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h (original)
+++ llvm/trunk/include/llvm/ProfileData/Coverage/CoverageMappingReader.h Fri Sep  8 11:44:47 2017
@@ -44,18 +44,26 @@ struct CoverageMappingRecord {
 /// \brief A file format agnostic iterator over coverage mapping data.
 class CoverageMappingIterator
     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
-  CoverageMappingReader *Reader = nullptr;
+  CoverageMappingReader *Reader;
   CoverageMappingRecord Record;
+  coveragemap_error ReadErr;
 
   void increment();
 
 public:
-  CoverageMappingIterator() = default;
+  CoverageMappingIterator()
+      : Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {}
 
-  CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {
+  CoverageMappingIterator(CoverageMappingReader *Reader)
+      : Reader(Reader), Record(), ReadErr(coveragemap_error::success) {
     increment();
   }
 
+  ~CoverageMappingIterator() {
+    if (ReadErr != coveragemap_error::success)
+      llvm_unreachable("Unexpected error in coverage mapping iterator");
+  }
+
   CoverageMappingIterator &operator++() {
     increment();
     return *this;
@@ -66,8 +74,22 @@ public:
   bool operator!=(const CoverageMappingIterator &RHS) {
     return Reader != RHS.Reader;
   }
-  CoverageMappingRecord &operator*() { return Record; }
-  CoverageMappingRecord *operator->() { return &Record; }
+  Expected<CoverageMappingRecord &> operator*() {
+    if (ReadErr != coveragemap_error::success) {
+      auto E = make_error<CoverageMapError>(ReadErr);
+      ReadErr = coveragemap_error::success;
+      return std::move(E);
+    }
+    return Record;
+  }
+  Expected<CoverageMappingRecord *> operator->() {
+    if (ReadErr != coveragemap_error::success) {
+      auto E = make_error<CoverageMapError>(ReadErr);
+      ReadErr = coveragemap_error::success;
+      return std::move(E);
+    }
+    return &Record;
+  }
 };
 
 class CoverageMappingReader {

Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp (original)
+++ llvm/trunk/lib/ProfileData/Coverage/CoverageMapping.cpp Fri Sep  8 11:44:47 2017
@@ -250,10 +250,15 @@ Expected<std::unique_ptr<CoverageMapping
     IndexedInstrProfReader &ProfileReader) {
   auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
 
-  for (const auto &CoverageReader : CoverageReaders)
-    for (const auto &Record : *CoverageReader)
+  for (const auto &CoverageReader : CoverageReaders) {
+    for (auto RecordOrErr : *CoverageReader) {
+      if (Error E = RecordOrErr.takeError())
+        return std::move(E);
+      const auto &Record = *RecordOrErr;
       if (Error E = Coverage->loadFunctionRecord(Record, ProfileReader))
         return std::move(E);
+    }
+  }
 
   return std::move(Coverage);
 }

Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp (original)
+++ llvm/trunk/lib/ProfileData/Coverage/CoverageMappingReader.cpp Fri Sep  8 11:44:47 2017
@@ -49,16 +49,18 @@ using namespace object;
 #define DEBUG_TYPE "coverage-mapping"
 
 void CoverageMappingIterator::increment() {
+  if (ReadErr != coveragemap_error::success)
+    return;
+
   // Check if all the records were read or if an error occurred while reading
   // the next record.
-  if (auto E = Reader->readNextRecord(Record)) {
+  if (auto E = Reader->readNextRecord(Record))
     handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
       if (CME.get() == coveragemap_error::eof)
         *this = CoverageMappingIterator();
       else
-        llvm_unreachable("Unexpected error in coverage mapping iterator");
+        ReadErr = CME.get();
     });
-  }
 }
 
 Error RawCoverageReader::readULEB128(uint64_t &Result) {
@@ -238,9 +240,12 @@ Error RawCoverageMappingReader::readMapp
       dbgs() << "\n";
     });
 
-    MappingRegions.push_back(CounterMappingRegion(
-        C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
-        LineStart + NumLines, ColumnEnd, Kind));
+    auto CMR = CounterMappingRegion(C, InferredFileID, ExpandedFileID,
+                                    LineStart, ColumnStart,
+                                    LineStart + NumLines, ColumnEnd, Kind);
+    if (CMR.startLoc() > CMR.endLoc())
+      return make_error<CoverageMapError>(coveragemap_error::malformed);
+    MappingRegions.push_back(CMR);
   }
   return Error::success();
 }

Modified: llvm/trunk/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/Coverage/CoverageMappingWriter.cpp?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/Coverage/CoverageMappingWriter.cpp (original)
+++ llvm/trunk/lib/ProfileData/Coverage/CoverageMappingWriter.cpp Fri Sep  8 11:44:47 2017
@@ -116,6 +116,13 @@ static void writeCounter(ArrayRef<Counte
 }
 
 void CoverageMappingWriter::write(raw_ostream &OS) {
+  // Check that we don't have any bogus regions.
+  assert(all_of(MappingRegions,
+                [](const CounterMappingRegion &CMR) {
+                  return CMR.startLoc() <= CMR.endLoc();
+                }) &&
+         "Source region does not begin before it ends");
+
   // Sort the regions in an ascending order by the file id and the starting
   // location. Sort by region kinds to ensure stable order for tests.
   std::stable_sort(

Modified: llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
Binary files - no diff available.

Modified: llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.json
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.json?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.json (original)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.json Fri Sep  8 11:44:47 2017
@@ -14,7 +14,7 @@
 // CHECK-SAME: "summary":{
 // CHECK-SAME: "lines":{"count":20,"covered":16,"percent":80},
 // CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
-// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}}
+// CHECK-SAME: "regions":{"count":11,"covered":8,"notcovered":3,"percent":72}}}
 
 // Close Files Array
 // CHECK-SAME: ],
@@ -33,7 +33,7 @@
 // CHECK-SAME: "lines":{"count":20,"covered":16,"percent":80},
 // CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
 // CHECK-SAME: "instantiations":{"count":1,"covered":1,"percent":100},
-// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}
+// CHECK-SAME: "regions":{"count":11,"covered":8,"notcovered":3,"percent":72}}
 
 // Close the export object, data array, and root object
 // CHECK-SAME: }]}

Copied: llvm/trunk/test/tools/llvm-cov/Inputs/malformedRegions.covmapping (from r312813, llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/malformedRegions.covmapping?p2=llvm/trunk/test/tools/llvm-cov/Inputs/malformedRegions.covmapping&p1=llvm/trunk/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping&r1=312813&r2=312814&rev=312814&view=diff
==============================================================================
Binary files - no diff available.

Modified: llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp (original)
+++ llvm/trunk/test/tools/llvm-cov/showLineExecutionCounts.cpp Fri Sep  8 11:44:47 2017
@@ -50,7 +50,7 @@ int main() {
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>int main() {
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  int x = 0
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>
-// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  if (x) {
+// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  if (x)
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre>
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre><span class='red'>  }</span>
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>    x = 1;
@@ -62,7 +62,7 @@ int main() {
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  x = x < 10
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  x = x > 10
-// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre>        x - 1:
+// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='red'>x - 1</span>:
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>        x + 1;
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>
 // HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>  return 0;
@@ -91,5 +91,5 @@ int main() {
 // HTML-INDEX: <td class='column-entry-yellow'>
 // HTML-INDEX: 80.00% (16/20)
 // HTML-INDEX: <td class='column-entry-red'>
-// HTML-INDEX: 70.00% (7/10)
+// HTML-INDEX: 72.73% (8/11)
 // HTML-INDEX: TOTALS

Modified: llvm/trunk/test/tools/llvm-cov/warnings.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/warnings.h?rev=312814&r1=312813&r2=312814&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/warnings.h (original)
+++ llvm/trunk/test/tools/llvm-cov/warnings.h Fri Sep  8 11:44:47 2017
@@ -11,3 +11,6 @@
 
 // FAKE-FUNC-STDOUT-NOT: warning: Could not read coverage for '{{.*}}'.
 // FAKE-FUNC-STDERR: Could not read coverage for '{{.*}}'.
+
+// 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




More information about the llvm-commits mailing list