diff options
author | Vedant Kumar <vsk@apple.com> | 2017-11-30 00:28:23 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-11-30 00:28:23 +0000 |
commit | 310bfccbbf7b96ad78c417e362ac3e9714dba6de (patch) | |
tree | 23057e4f85d1b7c6c2d89b9ba816e0cd739e81a8 | |
parent | b45fa1a5376c82a7d53265656a1618527430b7c5 (diff) |
[Coverage] Use the most-recent completed region count (PR35437)
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
-rw-r--r-- | lib/ProfileData/Coverage/CoverageMapping.cpp | 6 | ||||
-rw-r--r-- | test/tools/llvm-cov/deferred-region.cpp | 4 | ||||
-rw-r--r-- | unittests/ProfileData/CoverageMappingTest.cpp | 26 |
3 files changed, 35 insertions, 1 deletions
diff --git a/lib/ProfileData/Coverage/CoverageMapping.cpp b/lib/ProfileData/Coverage/CoverageMapping.cpp index 6cde3863f18..0d52e48084f 100644 --- a/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -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); } diff --git a/test/tools/llvm-cov/deferred-region.cpp b/test/tools/llvm-cov/deferred-region.cpp index 38090fbb498..3bc675d66e7 100644 --- a/test/tools/llvm-cov/deferred-region.cpp +++ b/test/tools/llvm-cov/deferred-region.cpp @@ -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 diff --git a/unittests/ProfileData/CoverageMappingTest.cpp b/unittests/ProfileData/CoverageMappingTest.cpp index 7c94ece1adc..26a8e511b4f 100644 --- a/unittests/ProfileData/CoverageMappingTest.cpp +++ b/unittests/ProfileData/CoverageMappingTest.cpp @@ -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); |