[clang] [llvm] [sancov] Add -diff and -union options to compute set difference and union of sancov files (PR #171191)

Manuel Carrasco via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 11 06:22:24 PST 2025


================
@@ -277,6 +284,33 @@ raw_ostream &operator<<(raw_ostream &OS, const RawCoverage &CoverageData) {
   return OS;
 }
 
+// Write coverage addresses in binary format.
+void RawCoverage::write(const std::string &FileName,
+                        const RawCoverage &Coverage, FileHeader Header) {
+  std::error_code EC;
+  raw_fd_ostream OS(FileName, EC, sys::fs::OF_None);
+  failIfError(EC);
+
+  OS.write(reinterpret_cast<const char *>(&Header), sizeof(Header));
+
+  switch (Header.Bitness) {
+  case Bitness64:
+    for (auto Addr : *Coverage.Addrs) {
+      uint64_t Addr64 = Addr;
+      OS.write(reinterpret_cast<const char *>(&Addr64), sizeof(Addr64));
+    }
+    break;
+  case Bitness32:
+    for (auto Addr : *Coverage.Addrs) {
+      uint32_t Addr32 = static_cast<uint32_t>(Addr);
+      OS.write(reinterpret_cast<const char *>(&Addr32), sizeof(Addr32));
+    }
----------------
mgcarrasco wrote:

Thanks for the feedback! The code has been updated to take this into account. `RawCoverage` now carries its bitness.

In this way, for the `RawCoverage::read-then-RawCoverage::write` scenario there can be no data loss. 32-bit addresses are read and implicitly promoted to `uint64_t` in the Addrs set, then truncated back to `uint32_t` during write. Since the original values were originally 32-bit values there is no data loss.

The only scenario for data loss is via -diff and -union but we know can warn about this by checking the bitness of each `RawCoverage` object. I have added a test case to document this behavior.

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


More information about the llvm-commits mailing list