]> granicus.if.org Git - llvm/commitdiff
[Coverage] Use the most-recent completed region count (PR35437)
authorVedant Kumar <vsk@apple.com>
Thu, 30 Nov 2017 00:28:23 +0000 (00:28 +0000)
committerVedant Kumar <vsk@apple.com>
Thu, 30 Nov 2017 00:28:23 +0000 (00:28 +0000)
This is a fix for the coverage segment builder.

If multiple regions must be popped off the active stack at once, and
more than one of them end at the same location, emit a segment using the
count from the most-recent completed region.

Fixes PR35437, rdar://35760630

Testing: invoked llvm-cov on a stage2 build of clang, additional unit
tests, check-profile

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

lib/ProfileData/Coverage/CoverageMapping.cpp
test/tools/llvm-cov/deferred-region.cpp
unittests/ProfileData/CoverageMappingTest.cpp

index 6cde3863f18878a871081bd42e3fc895b1320ac2..0d52e48084fae3f386ce8c6a93b1933af08e5ecd 100644 (file)
@@ -388,6 +388,12 @@ class SegmentBuilder {
       if (CompletedSegmentLoc == CompletedRegion->endLoc())
         continue;
 
+      // Use the count from the next completed region if it ends at the same
+      // location.
+      if (I + 1 < E &&
+          CompletedRegion->endLoc() == ActiveRegions[I + 1]->endLoc())
+        CompletedRegion = ActiveRegions[I + 1];
+
       startSegment(*CompletedRegion, CompletedSegmentLoc, false);
     }
 
index 38090fbb49895e42c2784e652695435f5bf13ca9..3bc675d66e710c400a803ff30f2dbd9b50517357 100644 (file)
@@ -45,7 +45,7 @@ void while_loop() {
         break; // CHECK: [[@LINE]]|{{ +}}1|
                // CHECK: [[@LINE]]|{{ +}}0|
       while (++x < 5) {} // CHECK: [[@LINE]]|{{ +}}0|
-    } // CHECK: [[@LINE]]|{{ +}}1|
+    } // CHECK: [[@LINE]]|{{ +}}0|
 
     if (x == 0) // CHECK: [[@LINE]]|{{ +}}1|
       throw Error(); // CHECK: [[@LINE]]|{{ +}}0|
@@ -97,6 +97,8 @@ int main() {
 // MARKER-NEXT: Highlighted line 47, 14 -> 21
 // MARKER-NEXT: Highlighted line 47, 21 -> 23
 // MARKER-NEXT: Highlighted line 47, 23 -> 25
+// MARKER-NEXT: Highlighted line 47, 25 -> ?
+// MARKER-NEXT: Highlighted line 48, 1 -> 6
 // MARKER-NEXT: Highlighted line 51, 7 -> 20
 // MARKER-NEXT: Marker at 53:5 = 1
 // MARKER-NEXT: Highlighted line 55, 9 -> 14
index 7c94ece1adc7b131820f8fcd07a8796548b35d5c..26a8e511b4f98a6912a2a12bda6f88b3e3737d4b 100644 (file)
@@ -466,6 +466,32 @@ TEST_P(CoverageMappingTest, multiple_regions_end_after_parent_ends) {
   EXPECT_EQ(CoverageSegment(9, 9, false), Segments[7]);
 }
 
+TEST_P(CoverageMappingTest, multiple_completed_segments_at_same_loc) {
+  ProfileWriter.addRecord({"func1", 0x1234, {0, 1, 2}}, Err);
+  startFunction("func1", 0x1234);
+
+  // PR35437
+  addCMR(Counter::getCounter(1), "file1", 2, 1, 18, 2);
+  addCMR(Counter::getCounter(0), "file1", 8, 12, 14, 6);
+  addCMR(Counter::getCounter(1), "file1", 9, 1, 14, 6);
+  addCMR(Counter::getCounter(2), "file1", 11, 13, 11, 14);
+
+  EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
+  const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
+  const auto &FunctionRecord = *FunctionRecords.begin();
+  CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
+  std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+
+  ASSERT_EQ(6U, Segments.size());
+  EXPECT_EQ(CoverageSegment(2, 1, 1, true), Segments[0]);
+  EXPECT_EQ(CoverageSegment(8, 12, 0, true), Segments[1]);
+  EXPECT_EQ(CoverageSegment(9, 1, 1, true), Segments[2]);
+  EXPECT_EQ(CoverageSegment(11, 13, 2, true), Segments[3]);
+  // Use count=1 (from 9:1 -> 14:6), not count=0 (from 8:12 -> 14:6).
+  EXPECT_EQ(CoverageSegment(11, 14, 1, false), Segments[4]);
+  EXPECT_EQ(CoverageSegment(18, 2, false), Segments[5]);
+}
+
 TEST_P(CoverageMappingTest, dont_emit_redundant_segments) {
   ProfileWriter.addRecord({"func1", 0x1234, {1, 1}}, Err);
   startFunction("func1", 0x1234);