Skip to content

Commit 2a34b7c

Browse files
committed
[Coverage] Fix handling of abnormal exits through repeat blocks
We do not correctly update the counter expression for conditionals in repeat-while blocks in the following two situations: Situation 1: repeat { // Region 1 if (C1) { // Region 2 break } } while C2 // Should be "Region 1 - Region 2", not "Region 1" Situation 2: repeat { // Region 1 if (C1) { // Region 2 continue } } while C2 // Should be "Region 1", not "Region 1 + Region 2" Fix both of these problems and add thorough regression tests. Closes Swift PR #1244, rdar://problem/24572268
1 parent 5dd6e6f commit 2a34b7c

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/SILGen/SILGenProfiling.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,8 @@ struct CoverageMapping : public ASTWalker {
514514

515515
} else if (auto *CS = dyn_cast<ContinueStmt>(S)) {
516516
// Continues create extra backedges, add them to the appropriate counters.
517-
addToCounter(CS->getTarget(), getCurrentCounter());
517+
if (!isa<RepeatWhileStmt>(CS->getTarget()))
518+
addToCounter(CS->getTarget(), getCurrentCounter());
518519
if (auto *WS = dyn_cast<WhileStmt>(CS->getTarget())) {
519520
if (auto *E = getConditionNode(WS->getCond()))
520521
addToCounter(E, getCurrentCounter());
@@ -525,8 +526,12 @@ struct CoverageMapping : public ASTWalker {
525526

526527
} else if (auto *BS = dyn_cast<BreakStmt>(S)) {
527528
// When we break from a loop, we need to adjust the exit count.
528-
if (!isa<SwitchStmt>(BS->getTarget()))
529+
if (auto *RWS = dyn_cast<RepeatWhileStmt>(BS->getTarget())) {
530+
auto CondCount = CounterExpr::Sub(getCounter(RWS), getCurrentCounter());
531+
addToCounter(RWS->getCond(), createCounter(std::move(CondCount)));
532+
} else if (!isa<SwitchStmt>(BS->getTarget())) {
529533
addToCounter(BS->getTarget(), getCurrentCounter());
534+
}
530535
terminateRegion(S);
531536

532537
} else if (auto *FS = dyn_cast<FallthroughStmt>(S)) {

test/SILGen/coverage_while.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,53 @@ func foo() -> Int32 {
5454
return x
5555
}
5656

57+
// rdar://problem/24572268
58+
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_while.goo
59+
// CHECK: [[@LINE+1]]:12 -> {{[0-9]+}}:2 : [[BAR:[0-9]+]]
60+
func goo() {
61+
var x : Int32 = 0
62+
63+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+2]]:4 : [[RWS1:[0-9]+]]
64+
x += 1
65+
} while x < 10 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : [[RWS1]]
66+
67+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+6]]:4 : [[RWS2:[0-9]+]]
68+
x += 1
69+
if (x % 2 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[CONT1:[0-9]+]]
70+
continue
71+
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+2]]:4 : ([[RWS2]] - [[CONT1]])
72+
x += 1
73+
} while x < 20 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : [[RWS2]]
74+
75+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+6]]:4 : [[RWS3:[0-9]+]]
76+
x += 1
77+
if (x % 2 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[BRK1:[0-9]+]]
78+
break
79+
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+2]]:4 : ([[RWS3]] - [[BRK1]])
80+
x += 1
81+
} while x < 30 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : ([[RWS3]] - [[BRK1]])
82+
83+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+10]]:4 : [[RWS4:[0-9]+]]
84+
x += 1
85+
if (x % 2 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[CONT2:[0-9]+]]
86+
continue
87+
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+6]]:4 : ([[RWS4]] - [[CONT2]])
88+
x += 1
89+
if (x % 7 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[BRK2:[0-9]+]]
90+
break
91+
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+2]]:4 : (([[RWS4]] - [[CONT2]]) - [[BRK2]])
92+
x += 1
93+
} while x < 40 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : ([[RWS4]] - [[BRK2]])
94+
95+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+1]]:4 : [[RWS5:[0-9]+]]
96+
} while false // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:16 : [[RWS5]]
97+
98+
repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+4]]:4 : [[RWS6:[0-9]+]]
99+
repeat { // CHECK-DAG: [[@LINE]]:12 -> [[@LINE+2]]:6 : [[RWS7:[0-9]+]]
100+
return
101+
} while false // CHECK-DAG: [[@LINE]]:13 -> [[@LINE]]:18 : [[RWS7]]
102+
} while false // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:16 : [[RWS6]]
103+
}
104+
57105
foo()
106+
goo()

0 commit comments

Comments
 (0)