[Coverage] Handle break/continue outside of loop bodies
authorVedant Kumar <vsk@apple.com>
Fri, 16 Feb 2018 07:59:43 +0000 (07:59 +0000)
committerVedant Kumar <vsk@apple.com>
Fri, 16 Feb 2018 07:59:43 +0000 (07:59 +0000)
Teach the coverage mapping logic to handle break or continue statements
within for loop increments.

Fixes llvm.org/PR36406.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325319 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CoverageMappingGen.cpp
test/CoverageMapping/break.c

index 5eb48c2b579d99eb7b2029394296c744fa4c0471..d4ff7dac6c032eb832d2ce664f56d0f72bec0cc7 100644 (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);
   }
index d42c1bd082d2dbcf5c3aeab0088fd055259de9f0..08461d7ed2de23c9fb5e17386d624272b1c091cd 100644 (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; }))
+    ;
+}