[llvm] [CoverageMapping] Fix LineCoverageStats incorrectly using gap region count (PR #203732)

Maksim Levental via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 13 18:15:37 PDT 2026


https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/203732

>From d7ce52982872550f9ed628185ee0c7071e53b373 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Sat, 13 Jun 2026 16:33:04 -0700
Subject: [PATCH] [llvm-cov] Add failing test for gap region line coverage bug

LineCoverageStats incorrectly reports a line as uncovered when the
wrapping segment has count=0 and the line has no region entries, even
if it has non-entry segments with count > 0.

This test uses coverage data from Apple clang which produces the
specific segment pattern that triggers this: a closing brace "}" after
a never-taken if-block, where the non-gap segment returning to the
parent function's count is ignored.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply at anthropic.com>
---
 .../gap-region-quirk/gap-quirk.covmapping     | Bin 0 -> 213 bytes
 .../Inputs/gap-region-quirk/gap-quirk.cpp     |  13 ++++++++
 .../gap-region-quirk/gap-quirk.profdata       | Bin 0 -> 712 bytes
 .../llvm-cov/gap-region-line-coverage.test    |  30 ++++++++++++++++++
 4 files changed, 43 insertions(+)
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.covmapping
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.cpp
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.profdata
 create mode 100644 llvm/test/tools/llvm-cov/gap-region-line-coverage.test

diff --git a/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.covmapping b/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.covmapping
new file mode 100644
index 0000000000000000000000000000000000000000..138bb3f29a5d53fb78e0440eeaaf32e4f47424d1
GIT binary patch
literal 213
zcmd1FDa%dHFUw_QfB?Q1%sdS7QO0Tc`ALkqiJ5sePzfNV4P~+cX(kN at N&S-C0{xuK
zyi{GF38_Vi>8ZLoiMdHBiM;8F1-gZ$nMK)p$pr;qUGBSYzkS1X-C7mMo45pGkcv{_
z>B#d-t}_AwD=Q<TC_57)BRd1P0xJ^(kYZ)vVd!mWXy9OF;ALikXkqwuwfDJM%GBGO
SK)wW23}FrfBO at 0NGZO#{H!g_)

literal 0
HcmV?d00001

diff --git a/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.cpp b/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.cpp
new file mode 100644
index 0000000000000..ad98fbb84f1ff
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.cpp
@@ -0,0 +1,13 @@
+void foo(bool cond) {
+  if (cond) {
+    int x = 1;
+    (void)x;
+  }
+  int y = 2;
+  (void)y;
+}
+
+int main() {
+  foo(false);
+  return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.profdata b/llvm/test/tools/llvm-cov/Inputs/gap-region-quirk/gap-quirk.profdata
new file mode 100644
index 0000000000000000000000000000000000000000..586f1295ca0fc237c8abd5823915a4e468da19c4
GIT binary patch
literal 712
zcmeyLQ&5zjmf6V5fE_GgLKWYE#y<e%vq6;!KxvpVW+<N#jfQd=VCn?aVIrvXf;N~=
zRB;Dhn8~Q(4<@sq3P5=cQZN^yN-Hd62MfS#fw|{^Iww}~gmqk4#TiU_u!=9(4GCFv
z^FP$_VO4J+&5u<)!VbIm9Y^fqW=`0}?Qw`RG5osP``j#L>TOu~X at K3qz>u4mnI{2d
z!+Zgwp~4ItP=@>N+i%}+UAKmWDFcH6R6IV)I4wUvY2p$H9~Q{y#-JMq<inJ}v~a)}
IFttz`04JCuo&W#<

literal 0
HcmV?d00001

diff --git a/llvm/test/tools/llvm-cov/gap-region-line-coverage.test b/llvm/test/tools/llvm-cov/gap-region-line-coverage.test
new file mode 100644
index 0000000000000..c74d08d24001e
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/gap-region-line-coverage.test
@@ -0,0 +1,30 @@
+// Tests that LineCoverageStats correctly handles lines where a zero-count
+// non-gap wrapping segment precedes a non-entry segment with count > 0.
+//
+// In this test, line 5 ("}") is the closing brace of an if-block that was
+// never entered. The wrapping segment from the if-body has count=0, but
+// line 5's own segment has count=1 (returning to the parent function's
+// coverage region). LineCoverageStats should report count=1 for line 5.
+//
+// Test inputs generated with Apple clang (-O0) which produces the specific
+// segment pattern needed to trigger this bug.
+
+// RUN: llvm-cov show %S/Inputs/gap-region-quirk/gap-quirk.covmapping \
+// RUN:   -instr-profile %S/Inputs/gap-region-quirk/gap-quirk.profdata \
+// RUN:   -path-equivalence=/tmp/line-coverage-lambda,%S/Inputs/gap-region-quirk \
+// RUN:   2>&1 | FileCheck -check-prefix=SHOW %s
+
+// Line 5 ("}") should show count 1, not 0.
+// SHOW:      5|      1|  }
+
+// RUN: llvm-cov report %S/Inputs/gap-region-quirk/gap-quirk.covmapping \
+// RUN:   -instr-profile %S/Inputs/gap-region-quirk/gap-quirk.profdata \
+// RUN:   -path-equivalence=/tmp/line-coverage-lambda,%S/Inputs/gap-region-quirk \
+// RUN:   --show-branch-summary=false \
+// RUN:   2>&1 | FileCheck -check-prefix=REPORT %s
+
+// 12 mapped lines, 2 genuinely missed (lines 3-4: if-body never entered).
+// Line 5 should NOT be counted as missed.
+// REPORT: TOTAL
+// REPORT-SAME: 12
+// REPORT-SAME: 2



More information about the llvm-commits mailing list