[Coverage] Handle break/continue outside of loop bodies

Teach the coverage mapping logic to handle break or continue statements
within for loop increments.

Fixes llvm.org/PR36406.

llvm-svn: 325319
This commit is contained in:
Vedant Kumar 2018-02-16 07:59:43 +00:00
parent 2e4b838c06
commit 3e2ae49a25
2 changed files with 27 additions and 8 deletions

View File

@ -982,20 +982,28 @@ struct CounterCoverageMappingBuilder
Counter ParentCount = getRegion().getCounter();
Counter BodyCount = getRegionCounter(S);
// The loop increment may contain a break or continue.
if (S->getInc())
BreakContinueStack.emplace_back();
// Handle the body first so that we can get the backedge count.
BreakContinueStack.push_back(BreakContinue());
BreakContinueStack.emplace_back();
extendRegion(S->getBody());
Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
BreakContinue BC = BreakContinueStack.pop_back_val();
BreakContinue BodyBC = BreakContinueStack.pop_back_val();
// The increment is essentially part of the body but it needs to include
// the count for all the continue statements.
if (const Stmt *Inc = S->getInc())
propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
BreakContinue IncrementBC;
if (const Stmt *Inc = S->getInc()) {
propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc);
IncrementBC = BreakContinueStack.pop_back_val();
}
// Go back to handle the condition.
Counter CondCount =
addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
Counter CondCount = addCounters(
addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
IncrementBC.ContinueCount);
if (const Expr *Cond = S->getCond()) {
propagateCounts(CondCount, Cond);
adjustForOutOfOrderTraversal(getEnd(S));
@ -1007,8 +1015,8 @@ struct CounterCoverageMappingBuilder
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
Counter OutCount =
addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
subtractCounters(CondCount, BodyCount));
if (OutCount != ParentCount)
pushRegion(OutCount);
}

View File

@ -31,3 +31,14 @@ int main() { // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
++cnt;
}
}
// CHECK-LABEL: break_continue_in_increment:
// CHECK: [[@LINE+6]]:11 -> [[@LINE+6]]:45 = #1
// CHECK: [[@LINE+5]]:18 -> [[@LINE+5]]:19 = #1
// CHECK: [[@LINE+4]]:21 -> [[@LINE+4]]:26 = #2
// CHECK: [[@LINE+3]]:33 -> [[@LINE+3]]:41 = (#1 - #2)
// CHECK: [[@LINE+3]]:5 -> [[@LINE+3]]:6 = #1
void break_continue_in_increment(int x) {
for (;; ({ if (x) break; else continue; }))
;
}