Skip to content

Commit 025639b

Browse files
authored
[Coverage] Fix mapping for do-while loops with terminating statements (llvm#139777)
The current region mapping for do-while loops that contain statements such as break or continue results in inaccurate line coverage reports for the line following the loop. This change handles terminating statements the same way that other loop constructs do, correcting the region mapping for accurate reports. It also fixes a fragile test relying on exact line numbers. Fixes llvm#139122
1 parent 3601849 commit 025639b

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,14 +1703,13 @@ struct CounterCoverageMappingBuilder
17031703
if (!IsCounterEqual(OutCount, ParentCount)) {
17041704
pushRegion(OutCount);
17051705
GapRegionCounter = OutCount;
1706+
if (BodyHasTerminateStmt)
1707+
HasTerminateStmt = true;
17061708
}
17071709

17081710
// Create Branch Region around condition.
17091711
if (!llvm::EnableSingleByteCoverage)
17101712
createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped);
1711-
1712-
if (BodyHasTerminateStmt)
1713-
HasTerminateStmt = true;
17141713
}
17151714

17161715
void VisitForStmt(const ForStmt *S) {

clang/test/CoverageMapping/terminate-statements.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,20 @@ int elsecondnoret(void) {
348348

349349
// CHECK-LABEL: _Z18statementexprnoretb:
350350
int statementexprnoret(bool crash) {
351-
int rc = ({ if (crash) abort(); 0; }); // CHECK: File 0, 351:35 -> 352:12 = (#0 - #1)
351+
int rc = ({ if (crash) abort(); 0; }); // CHECK: File 0, [[@LINE]]:35 -> [[@LINE+1]]:12 = (#0 - #1)
352352
return rc; // CHECK-NOT: Gap
353353
}
354354

355+
// CHECK-LABEL: _Z13do_with_breaki:
356+
int do_with_break(int n) {
357+
do {
358+
if (n == 87) {
359+
break;
360+
} // CHECK: File 0, [[@LINE-2]]:18 -> [[@LINE]]:6 = #2
361+
} while (0); // CHECK: File 0, [[@LINE]]:12 -> [[@LINE]]:13 = ((#0 + #1) - #2)
362+
return 0; // CHECK-NOT: Gap,File 0, [[@LINE-1]]:15
363+
}
364+
355365
int main() {
356366
foo(0);
357367
foo(1);
@@ -375,5 +385,6 @@ int main() {
375385
abstractcondnoret();
376386
elsecondnoret();
377387
statementexprnoret(false);
388+
do_with_break(0);
378389
return 0;
379390
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// REQUIRES: lld-available
2+
// XFAIL: powerpc64-target-arch
3+
4+
// RUN: %clangxx_profgen -fuse-ld=lld -fcoverage-mapping -o %t %s
5+
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
6+
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
7+
// RUN: llvm-cov show %t -instr-profile=%t.profdata 2>&1 | FileCheck %s
8+
9+
#include <stdio.h>
10+
11+
// clang-format off
12+
int main(int argc, char **argv) { // CHECK: [[@LINE]]| 1|int main(
13+
do { // CHECK: [[@LINE]]| 1| do {
14+
if (argc == 87) { // CHECK: [[@LINE]]| 1| if (argc
15+
break; // CHECK: [[@LINE]]| 0| break
16+
} // CHECK: [[@LINE]]| 0| }
17+
} while (0); // CHECK: [[@LINE]]| 1| } while
18+
printf("coverage after do is present\n"); // CHECK: [[@LINE]]| 1| printf(
19+
return 0; // CHECK: [[@LINE]]| 1| return
20+
} // CHECK: [[@LINE]]| 1|}
21+
// clang-format on

0 commit comments

Comments
 (0)