[clang] [compiler-rt] [llvm] Add a field in Coverage Mapping header for tracking coverage capabilities (PR #158059)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 11 05:43:41 PDT 2025


Dorian =?utf-8?q?Péron?= <peron at adacore.com>,
Dorian =?utf-8?q?Péron?= <peron at adacore.com>,
Dorian =?utf-8?q?Péron?= <peron at adacore.com>,
Dorian =?utf-8?q?Péron?= <peron at adacore.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/158059 at github.com>


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Dorian Péron (RenjiSann)

<details>
<summary>Changes</summary>

Example implementation of #<!-- -->158027 

---

Patch is 26.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/158059.diff


14 Files Affected:

- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+9) 
- (modified) clang/test/CoverageMapping/ir.c (+2-2) 
- (modified) clang/test/Profile/def-assignop.cpp (+1-1) 
- (modified) clang/test/Profile/def-ctors.cpp (+1-1) 
- (modified) clang/test/Profile/def-dtors.cpp (+1-1) 
- (modified) compiler-rt/include/profile/InstrProfData.inc (+3-1) 
- (modified) llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h (+61-2) 
- (modified) llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h (+12-1) 
- (modified) llvm/include/llvm/ProfileData/InstrProfData.inc (+3-1) 
- (modified) llvm/lib/ProfileData/Coverage/CoverageMapping.cpp (+19-4) 
- (modified) llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp (+42-9) 
- (modified) llvm/tools/llvm-cov/CodeCoverage.cpp (+12-3) 
- (modified) llvm/tools/llvm-cov/CoverageViewOptions.h (+2-2) 
- (modified) llvm/unittests/ProfileData/CoverageMappingTest.cpp (+5) 


``````````diff
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 05fb137ca0575..441d537e1f33f 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -2604,6 +2604,15 @@ void CoverageMappingModuleGen::emit() {
   };
   auto CovDataHeaderTy =
       llvm::StructType::get(Ctx, ArrayRef(CovDataHeaderTypes));
+
+  // By default, clang instruments the code for "statement" and "branch"
+  // coverage, and can instrument for MCDC when `-fcoverage-mcdc` is passed.
+  uint32_t CovInstrLevels = CoverageCapabilities::CovInstrLevel::Statement |
+                            CoverageCapabilities::CovInstrLevel::Branch;
+  if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
+      CGM.getCodeGenOpts().MCDCCoverage)
+    CovInstrLevels |= CoverageCapabilities::CovInstrLevel::MCDC;
+
   llvm::Constant *CovDataHeaderVals[] = {
 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
 #include "llvm/ProfileData/InstrProfData.inc"
diff --git a/clang/test/CoverageMapping/ir.c b/clang/test/CoverageMapping/ir.c
index b08734cc35113..9f5111afef695 100644
--- a/clang/test/CoverageMapping/ir.c
+++ b/clang/test/CoverageMapping/ir.c
@@ -17,12 +17,12 @@ int main(void) {
 // DARWIN: [[FuncRecord1:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8
 // DARWIN: [[FuncRecord2:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8
 // DARWIN: [[FuncRecord3:@__covrec_[0-9A-F]+]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8
-// DARWIN: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section "__LLVM_COV,__llvm_covmap", align 8
+// DARWIN: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section "__LLVM_COV,__llvm_covmap", align 8
 
 // WINDOWS: [[FuncRecord1:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8
 // WINDOWS: [[FuncRecord2:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8
 // WINDOWS: [[FuncRecord3:@__covrec_[0-9A-F]+]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8
-// WINDOWS: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section ".lcovmap$M", align 8
+// WINDOWS: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section ".lcovmap$M", align 8
 
 // COMMON: @llvm.used = appending global [{{.*}}] [
 // COMMON-SAME: [[FuncRecord1]]
diff --git a/clang/test/Profile/def-assignop.cpp b/clang/test/Profile/def-assignop.cpp
index d17654f31428b..332ea9f1046e9 100644
--- a/clang/test/Profile/def-assignop.cpp
+++ b/clang/test/Profile/def-assignop.cpp
@@ -23,7 +23,7 @@ struct A {
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
-  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }
+  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32, i32 }
   B b;
 };
 
diff --git a/clang/test/Profile/def-ctors.cpp b/clang/test/Profile/def-ctors.cpp
index 0179bc92dbb86..8457c13fe2f9e 100644
--- a/clang/test/Profile/def-ctors.cpp
+++ b/clang/test/Profile/def-ctors.cpp
@@ -28,7 +28,7 @@ struct Derived : public Base {
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
-  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }
+  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32, i32 }
 };
 
 Derived dd;
diff --git a/clang/test/Profile/def-dtors.cpp b/clang/test/Profile/def-dtors.cpp
index dc87508fe7c28..a4d6a38e9e422 100644
--- a/clang/test/Profile/def-dtors.cpp
+++ b/clang/test/Profile/def-dtors.cpp
@@ -23,7 +23,7 @@ struct Derived : public Base {
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
   // COVMAP: section "__llvm_covfun", comdat
-  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }
+  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32, i32 }
 };
 
 int main() {
diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc
index 0496f240dc823..a2af7cfa8cbe1 100644
--- a/compiler-rt/include/profile/InstrProfData.inc
+++ b/compiler-rt/include/profile/InstrProfData.inc
@@ -300,6 +300,8 @@ COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \
               llvm::ConstantInt::get(Int32Ty, CoverageMappingSize))
 COVMAP_HEADER(uint32_t, Int32Ty, Version, \
               llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion))
+COVMAP_HEADER(uint32_t, Int32Ty, CovInstrLevels, \
+              llvm::ConstantInt::get(Int32Ty, CovInstrLevels))
 #undef COVMAP_HEADER
 /* COVMAP_HEADER end.  */
 
@@ -724,7 +726,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
 /* Indexed profile format version (start from 1). */
 #define INSTR_PROF_INDEX_VERSION 12
 /* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 6
+#define INSTR_PROF_COVMAP_VERSION 7
 
 /* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
  * version for other variants of profile. We set the 8th most significant bit
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 7d1a85ba528fc..0623e16aff173 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -984,6 +984,52 @@ class CoverageData {
   ArrayRef<MCDCRecord> getMCDCRecords() const { return MCDCRecords; }
 };
 
+/// Represents a set of available capabilities
+class CoverageCapabilities {
+  uint32_t Capabilities;
+
+public:
+  enum CovInstrLevel {
+    Statement = (1 << 0),
+    Branch = (1 << 1),
+    MCDC = (1 << 2),
+  };
+
+  CoverageCapabilities(uint32_t Capabilities) : Capabilities(Capabilities){};
+
+  static CoverageCapabilities all() {
+    return CoverageCapabilities(Statement | Branch | MCDC);
+  }
+
+  static CoverageCapabilities none() {
+    return CoverageCapabilities(0);
+  }
+
+  bool hasCapability(CovInstrLevel Lvl) const {
+    return (this->Capabilities & Lvl) != 0;
+  }
+
+  /// Returns true if this includes all the capabilities of Other.
+  bool includes(const CoverageCapabilities &Other) const {
+    return (this->Capabilities & Other.Capabilities) == Other.Capabilities;
+  }
+
+  std::string toString() const {
+    std::stringstream SS;
+    SS << std::oct << this->Capabilities;
+    return SS.str();
+  }
+
+  CoverageCapabilities& operator |= (const CoverageCapabilities &Rhs) {
+    this->Capabilities |= Rhs.Capabilities;
+    return *this;
+  }
+
+  CoverageCapabilities operator | (const CoverageCapabilities &Rhs) const {
+    return CoverageCapabilities(this->Capabilities | Rhs.Capabilities);
+  }
+};
+
 /// The mapping of profile information to coverage data.
 ///
 /// This is the main interface to get coverage information, using a profile to
@@ -994,6 +1040,10 @@ class CoverageMapping {
   DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
   std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
 
+  /// Keep track of the coverage capabilities of the loaded object file,
+  /// which depends on the parameters used to compile it.
+  CoverageCapabilities AvailableInstrLevels = CoverageCapabilities::none();
+
   std::optional<bool> SingleByteCoverage;
 
   CoverageMapping() = default;
@@ -1011,6 +1061,7 @@ class CoverageMapping {
                std::optional<std::reference_wrapper<IndexedInstrProfReader>>
                    &ProfileReader,
                CoverageMapping &Coverage, bool &DataFound,
+               CoverageCapabilities RequestedCapabilities,
                SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
 
   /// Add a function record corresponding to \p Record.
@@ -1034,7 +1085,8 @@ class CoverageMapping {
   LLVM_ABI static Expected<std::unique_ptr<CoverageMapping>>
   load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
        std::optional<std::reference_wrapper<IndexedInstrProfReader>>
-           &ProfileReader);
+           &ProfileReader,
+       CoverageCapabilities RequestCapabilities = CoverageCapabilities::none());
 
   /// 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.
@@ -1044,7 +1096,8 @@ class CoverageMapping {
        std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
        ArrayRef<StringRef> Arches = {}, StringRef CompilationDir = "",
        const object::BuildIDFetcher *BIDFetcher = nullptr,
-       bool CheckBinaryIDs = false);
+       bool CheckBinaryIDs = false,
+       CoverageCapabilities RequestCapabilities = CoverageCapabilities::none());
 
   /// The number of functions that couldn't have their profiles mapped.
   ///
@@ -1430,6 +1483,10 @@ struct CovMapHeader {
   template <llvm::endianness Endian> uint32_t getVersion() const {
     return support::endian::byte_swap<uint32_t, Endian>(Version);
   }
+
+  template <llvm::endianness Endian> uint32_t getCovInstrLevels() const {
+    return support::endian::byte_swap<uint32_t, Endian>(CovInstrLevels);
+  }
 };
 
 LLVM_PACKED_END
@@ -1452,6 +1509,8 @@ enum CovMapVersion {
   Version6 = 5,
   // Branch regions extended and Decision Regions added for MC/DC.
   Version7 = 6,
+  // Covmap header tracks the instrumentation level
+  Version8 = 7,
   // The current version is Version7.
   CurrentVersion = INSTR_PROF_COVMAP_VERSION
 };
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index e91ba9147a745..b6e68bf13c10d 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -104,6 +104,10 @@ class CoverageMappingReader {
   virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;
   CoverageMappingIterator begin() { return CoverageMappingIterator(this); }
   CoverageMappingIterator end() { return CoverageMappingIterator(); }
+
+  /// Returns the instrumentation levels for which the code was originally
+  /// instrumented.
+  virtual CoverageCapabilities coverageCapabilities() const = 0;
 };
 
 /// Base class for the raw coverage mapping and filenames data readers.
@@ -188,6 +192,7 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader {
   std::vector<ProfileMappingRecord> MappingRecords;
   std::unique_ptr<InstrProfSymtab> ProfileNames;
   size_t CurrentRecord = 0;
+  CoverageCapabilities AvailableCapabilities;
   std::vector<StringRef> FunctionsFilenames;
   std::vector<CounterExpression> Expressions;
   std::vector<CounterMappingRegion> MappingRegions;
@@ -205,7 +210,9 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader {
   BinaryCoverageReader(std::unique_ptr<InstrProfSymtab> Symtab,
                        FuncRecordsStorage &&FuncRecords,
                        CoverageMapCopyStorage &&CoverageMapCopy)
-      : ProfileNames(std::move(Symtab)), FuncRecords(std::move(FuncRecords)),
+      : ProfileNames(std::move(Symtab)),
+        AvailableCapabilities(CoverageCapabilities::all()),
+        FuncRecords(std::move(FuncRecords)),
         CoverageMapCopy(std::move(CoverageMapCopy)) {}
 
 public:
@@ -226,6 +233,10 @@ class LLVM_ABI BinaryCoverageReader : public CoverageMappingReader {
       llvm::endianness Endian, StringRef CompilationDir = "");
 
   Error readNextRecord(CoverageMappingRecord &Record) override;
+
+  CoverageCapabilities coverageCapabilities() const override {
+    return this->AvailableCapabilities;
+  };
 };
 
 /// Reader for the raw coverage filenames.
diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc
index 0496f240dc823..a2af7cfa8cbe1 100644
--- a/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -300,6 +300,8 @@ COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \
               llvm::ConstantInt::get(Int32Ty, CoverageMappingSize))
 COVMAP_HEADER(uint32_t, Int32Ty, Version, \
               llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion))
+COVMAP_HEADER(uint32_t, Int32Ty, CovInstrLevels, \
+              llvm::ConstantInt::get(Int32Ty, CovInstrLevels))
 #undef COVMAP_HEADER
 /* COVMAP_HEADER end.  */
 
@@ -724,7 +726,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
 /* Indexed profile format version (start from 1). */
 #define INSTR_PROF_INDEX_VERSION 12
 /* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 6
+#define INSTR_PROF_COVMAP_VERSION 7
 
 /* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
  * version for other variants of profile. We set the 8th most significant bit
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 429ec5c19f1f8..a7e8fb8030c04 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -978,6 +978,7 @@ Error CoverageMapping::loadFromReaders(
   Coverage.SingleByteCoverage =
       !ProfileReader || ProfileReader.value().get().hasSingleByteCoverage();
   for (const auto &CoverageReader : CoverageReaders) {
+    Coverage.AvailableInstrLevels |= CoverageReader->coverageCapabilities();
     for (auto RecordOrErr : *CoverageReader) {
       if (Error E = RecordOrErr.takeError())
         return E;
@@ -992,7 +993,7 @@ Error CoverageMapping::loadFromReaders(
 Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
     ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
     std::optional<std::reference_wrapper<IndexedInstrProfReader>>
-        &ProfileReader) {
+        &ProfileReader, CoverageCapabilities RequestedCapabilities) {
   auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
   if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage))
     return std::move(E);
@@ -1013,6 +1014,7 @@ Error CoverageMapping::loadFromFile(
     std::optional<std::reference_wrapper<IndexedInstrProfReader>>
         &ProfileReader,
     CoverageMapping &Coverage, bool &DataFound,
+    CoverageCapabilities RequestedCapabilities,
     SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
   auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
       Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false);
@@ -1045,6 +1047,16 @@ Error CoverageMapping::loadFromFile(
   DataFound |= !Readers.empty();
   if (Error E = loadFromReaders(Readers, ProfileReader, Coverage))
     return createFileError(Filename, std::move(E));
+
+  // Check that the requested coverage capabilities are available.
+  if (!Coverage.AvailableInstrLevels.includes(RequestedCapabilities))
+    return createFileError(
+        Filename, createStringError(
+                      "lacking coverage capabilities (requested %s, got %s)",
+                      RequestedCapabilities.toString().c_str(),
+                      Coverage.AvailableInstrLevels.toString().c_str()
+                    ));
+
   return Error::success();
 }
 
@@ -1052,7 +1064,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
     ArrayRef<StringRef> ObjectFilenames,
     std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
     ArrayRef<StringRef> Arches, StringRef CompilationDir,
-    const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) {
+    const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs,
+    CoverageCapabilities RequestedCapabilities) {
   std::unique_ptr<IndexedInstrProfReader> ProfileReader;
   if (ProfileFilename) {
     auto ProfileReaderOrErr =
@@ -1081,7 +1094,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
   for (const auto &File : llvm::enumerate(ObjectFilenames)) {
     if (Error E = loadFromFile(File.value(), GetArch(File.index()),
                                CompilationDir, ProfileReaderRef, *Coverage,
-                               DataFound, &FoundBinaryIDs))
+                               DataFound, RequestedCapabilities,
+                               &FoundBinaryIDs))
       return std::move(E);
   }
 
@@ -1110,7 +1124,8 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
         std::string Path = std::move(*PathOpt);
         StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
         if (Error E = loadFromFile(Path, Arch, CompilationDir, ProfileReaderRef,
-                                   *Coverage, DataFound))
+                                   *Coverage, DataFound,
+                                   RequestedCapabilities))
           return std::move(E);
       } else if (CheckBinaryIDs) {
         return createFileError(
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index fc2577e6ada5d..8ae7a26bc1b50 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -670,7 +670,13 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
                                             const char *CovBufEnd) override {
     using namespace support;
 
-    if (CovBuf + sizeof(CovMapHeader) > CovBufEnd)
+    // In versions before Version8, the Covmap header only has 4 uint32_t
+    // fields.
+    uint32_t HeaderSize = (Version >= CovMapVersion::Version8)
+                              ? sizeof(CovMapHeader)
+                              : 4 * sizeof(uint32_t);
+
+    if (CovBuf + HeaderSize > CovBufEnd)
       return make_error<CoverageMapError>(
           coveragemap_error::malformed,
           "coverage mapping header section is larger than buffer size");
@@ -679,7 +685,8 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
     uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
     uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
     assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version);
-    CovBuf = reinterpret_cast<const char *>(CovHeader + 1);
+
+    CovBuf = reinterpret_cast<const char *>(CovHeader) + HeaderSize;
 
     // Skip past the function records, saving the start and end for later.
     // This is a no-op in Version4 (function records are read after all headers
@@ -830,6 +837,7 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
   case CovMapVersion::Version5:
   case CovMapVersion::Version6:
   case CovMapVersion::Version7:
+  case CovMapVersion::Version8:
     // Decompress the name data.
     if (Error E = P.create(P.getNameData()))
       return std::move(E);
@@ -851,6 +859,9 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
     else if (Version == CovMapVersion::Version7)
       return std::make_unique<VersionedCovMapFuncRecordReader<
           CovMapVersion::Version7, IntPtrT, Endian>>(P, R, D, F);
+    else if (Version == CovMapVersion::Version8)
+      return std::make_unique<VersionedCovMapFuncRecordReader<
+          CovMapVersion::Version8, IntPtrT, Endian>>(P, R, D, F);
   }
   llvm_unreachable("Unsupported version");
 }
@@ -859,7 +870,8 @@ template <typename T, llvm::endianness Endian>
 static Error readCoverageMappingData(
     InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
     std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
-    StringRef CompilationDir, std::vector<std::string> &Filenames) {
+    StringRef CompilationDir, std::vector<std::string> &Filenames,
+    CoverageCapabilities &AvailableCapabilities) {
   using namespace ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/158059


More information about the llvm-commits mailing list