[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