1 //===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
10 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
11 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
12 #include "llvm/ProfileData/InstrProfReader.h"
13 #include "llvm/ProfileData/InstrProfWriter.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/Testing/Support/Error.h"
16 #include "llvm/Testing/Support/SupportHelpers.h"
17 #include "gtest/gtest.h"
18 
19 #include <ostream>
20 #include <utility>
21 
22 using namespace llvm;
23 using namespace coverage;
24 
25 LLVM_NODISCARD static ::testing::AssertionResult
ErrorEquals(coveragemap_error Expected,Error E)26 ErrorEquals(coveragemap_error Expected, Error E) {
27   coveragemap_error Found;
28   std::string FoundMsg;
29   handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
30     Found = CME.get();
31     FoundMsg = CME.message();
32   });
33   if (Expected == Found)
34     return ::testing::AssertionSuccess();
35   return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
36 }
37 
38 namespace llvm {
39 namespace coverage {
PrintTo(const Counter & C,::std::ostream * os)40 void PrintTo(const Counter &C, ::std::ostream *os) {
41   if (C.isZero())
42     *os << "Zero";
43   else if (C.isExpression())
44     *os << "Expression " << C.getExpressionID();
45   else
46     *os << "Counter " << C.getCounterID();
47 }
48 
PrintTo(const CoverageSegment & S,::std::ostream * os)49 void PrintTo(const CoverageSegment &S, ::std::ostream *os) {
50   *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", ";
51   if (S.HasCount)
52     *os << S.Count << ", ";
53   *os << (S.IsRegionEntry ? "true" : "false") << ")";
54 }
55 }
56 }
57 
58 namespace {
59 
60 struct OutputFunctionCoverageData {
61   StringRef Name;
62   uint64_t Hash;
63   std::vector<StringRef> Filenames;
64   std::vector<CounterMappingRegion> Regions;
65   std::vector<CounterExpression> Expressions;
66 
OutputFunctionCoverageData__anonaa9da0780211::OutputFunctionCoverageData67   OutputFunctionCoverageData() : Hash(0) {}
68 
OutputFunctionCoverageData__anonaa9da0780211::OutputFunctionCoverageData69   OutputFunctionCoverageData(OutputFunctionCoverageData &&OFCD)
70       : Name(OFCD.Name), Hash(OFCD.Hash), Filenames(std::move(OFCD.Filenames)),
71         Regions(std::move(OFCD.Regions)) {}
72 
73   OutputFunctionCoverageData(const OutputFunctionCoverageData &) = delete;
74   OutputFunctionCoverageData &
75   operator=(const OutputFunctionCoverageData &) = delete;
76   OutputFunctionCoverageData &operator=(OutputFunctionCoverageData &&) = delete;
77 
fillCoverageMappingRecord__anonaa9da0780211::OutputFunctionCoverageData78   void fillCoverageMappingRecord(CoverageMappingRecord &Record) const {
79     Record.FunctionName = Name;
80     Record.FunctionHash = Hash;
81     Record.Filenames = Filenames;
82     Record.Expressions = Expressions;
83     Record.MappingRegions = Regions;
84   }
85 };
86 
87 struct CoverageMappingReaderMock : CoverageMappingReader {
88   ArrayRef<OutputFunctionCoverageData> Functions;
89 
CoverageMappingReaderMock__anonaa9da0780211::CoverageMappingReaderMock90   CoverageMappingReaderMock(ArrayRef<OutputFunctionCoverageData> Functions)
91       : Functions(Functions) {}
92 
readNextRecord__anonaa9da0780211::CoverageMappingReaderMock93   Error readNextRecord(CoverageMappingRecord &Record) override {
94     if (Functions.empty())
95       return make_error<CoverageMapError>(coveragemap_error::eof);
96 
97     Functions.front().fillCoverageMappingRecord(Record);
98     Functions = Functions.slice(1);
99 
100     return Error::success();
101   }
102 };
103 
104 struct InputFunctionCoverageData {
105   // Maps the global file index from CoverageMappingTest.Files
106   // to the index of that file within this function. We can't just use
107   // global file indexes here because local indexes have to be dense.
108   // This map is used during serialization to create the virtual file mapping
109   // (from local fileId to global Index) in the head of the per-function
110   // coverage mapping data.
111   SmallDenseMap<unsigned, unsigned> ReverseVirtualFileMapping;
112   std::string Name;
113   uint64_t Hash;
114   std::vector<CounterMappingRegion> Regions;
115   std::vector<CounterExpression> Expressions;
116 
InputFunctionCoverageData__anonaa9da0780211::InputFunctionCoverageData117   InputFunctionCoverageData(std::string Name, uint64_t Hash)
118       : Name(std::move(Name)), Hash(Hash) {}
119 
InputFunctionCoverageData__anonaa9da0780211::InputFunctionCoverageData120   InputFunctionCoverageData(InputFunctionCoverageData &&IFCD)
121       : ReverseVirtualFileMapping(std::move(IFCD.ReverseVirtualFileMapping)),
122         Name(std::move(IFCD.Name)), Hash(IFCD.Hash),
123         Regions(std::move(IFCD.Regions)) {}
124 
125   InputFunctionCoverageData(const InputFunctionCoverageData &) = delete;
126   InputFunctionCoverageData &
127   operator=(const InputFunctionCoverageData &) = delete;
128   InputFunctionCoverageData &operator=(InputFunctionCoverageData &&) = delete;
129 };
130 
131 struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
132   bool UseMultipleReaders;
133   StringMap<unsigned> Files;
134   std::vector<std::string> Filenames;
135   std::vector<InputFunctionCoverageData> InputFunctions;
136   std::vector<OutputFunctionCoverageData> OutputFunctions;
137 
138   InstrProfWriter ProfileWriter;
139   std::unique_ptr<IndexedInstrProfReader> ProfileReader;
140 
141   std::unique_ptr<CoverageMapping> LoadedCoverage;
142 
SetUp__anonaa9da0780211::CoverageMappingTest143   void SetUp() override {
144     ProfileWriter.setOutputSparse(std::get<0>(GetParam()));
145     UseMultipleReaders = std::get<1>(GetParam());
146   }
147 
getGlobalFileIndex__anonaa9da0780211::CoverageMappingTest148   unsigned getGlobalFileIndex(StringRef Name) {
149     auto R = Files.find(Name);
150     if (R != Files.end())
151       return R->second;
152     unsigned Index = Files.size() + 1;
153     Files.try_emplace(Name, Index);
154     return Index;
155   }
156 
157   // Return the file index of file 'Name' for the current function.
158   // Add the file into the global map if necessary.
159   // See also InputFunctionCoverageData::ReverseVirtualFileMapping
160   // for additional comments.
getFileIndexForFunction__anonaa9da0780211::CoverageMappingTest161   unsigned getFileIndexForFunction(StringRef Name) {
162     unsigned GlobalIndex = getGlobalFileIndex(Name);
163     auto &CurrentFunctionFileMapping =
164         InputFunctions.back().ReverseVirtualFileMapping;
165     auto R = CurrentFunctionFileMapping.find(GlobalIndex);
166     if (R != CurrentFunctionFileMapping.end())
167       return R->second;
168     unsigned IndexInFunction = CurrentFunctionFileMapping.size();
169     CurrentFunctionFileMapping.insert(
170         std::make_pair(GlobalIndex, IndexInFunction));
171     return IndexInFunction;
172   }
173 
startFunction__anonaa9da0780211::CoverageMappingTest174   void startFunction(StringRef FuncName, uint64_t Hash) {
175     InputFunctions.emplace_back(FuncName.str(), Hash);
176   }
177 
addCMR__anonaa9da0780211::CoverageMappingTest178   void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE,
179               unsigned CE, bool Skipped = false) {
180     auto &Regions = InputFunctions.back().Regions;
181     unsigned FileID = getFileIndexForFunction(File);
182     Regions.push_back(
183         Skipped ? CounterMappingRegion::makeSkipped(FileID, LS, CS, LE, CE)
184                 : CounterMappingRegion::makeRegion(C, FileID, LS, CS, LE, CE));
185   }
186 
addExpansionCMR__anonaa9da0780211::CoverageMappingTest187   void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
188                        unsigned CS, unsigned LE, unsigned CE) {
189     InputFunctions.back().Regions.push_back(CounterMappingRegion::makeExpansion(
190         getFileIndexForFunction(File), getFileIndexForFunction(ExpandedFile),
191         LS, CS, LE, CE));
192   }
193 
addExpression__anonaa9da0780211::CoverageMappingTest194   void addExpression(CounterExpression CE) {
195     InputFunctions.back().Expressions.push_back(CE);
196   }
197 
writeCoverageRegions__anonaa9da0780211::CoverageMappingTest198   std::string writeCoverageRegions(InputFunctionCoverageData &Data) {
199     SmallVector<unsigned, 8> FileIDs(Data.ReverseVirtualFileMapping.size());
200     for (const auto &E : Data.ReverseVirtualFileMapping)
201       FileIDs[E.second] = E.first;
202     std::string Coverage;
203     llvm::raw_string_ostream OS(Coverage);
204     CoverageMappingWriter(FileIDs, Data.Expressions, Data.Regions).write(OS);
205     return OS.str();
206   }
207 
readCoverageRegions__anonaa9da0780211::CoverageMappingTest208   void readCoverageRegions(const std::string &Coverage,
209                            OutputFunctionCoverageData &Data) {
210     // We will re-use the StringRef in duplicate tests, clear it to avoid
211     // clobber previous ones.
212     Filenames.clear();
213     Filenames.resize(Files.size() + 1);
214     for (const auto &E : Files)
215       Filenames[E.getValue()] = E.getKey().str();
216     ArrayRef<std::string> FilenameRefs = llvm::makeArrayRef(Filenames);
217     RawCoverageMappingReader Reader(Coverage, FilenameRefs, Data.Filenames,
218                                     Data.Expressions, Data.Regions);
219     EXPECT_THAT_ERROR(Reader.read(), Succeeded());
220   }
221 
writeAndReadCoverageRegions__anonaa9da0780211::CoverageMappingTest222   void writeAndReadCoverageRegions(bool EmitFilenames = true) {
223     OutputFunctions.resize(InputFunctions.size());
224     for (unsigned I = 0; I < InputFunctions.size(); ++I) {
225       std::string Regions = writeCoverageRegions(InputFunctions[I]);
226       readCoverageRegions(Regions, OutputFunctions[I]);
227       OutputFunctions[I].Name = InputFunctions[I].Name;
228       OutputFunctions[I].Hash = InputFunctions[I].Hash;
229       if (!EmitFilenames)
230         OutputFunctions[I].Filenames.clear();
231     }
232   }
233 
readProfCounts__anonaa9da0780211::CoverageMappingTest234   void readProfCounts() {
235     auto Profile = ProfileWriter.writeBuffer();
236     auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
237     EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
238     ProfileReader = std::move(ReaderOrErr.get());
239   }
240 
readOutputFunctions__anonaa9da0780211::CoverageMappingTest241   Expected<std::unique_ptr<CoverageMapping>> readOutputFunctions() {
242     std::vector<std::unique_ptr<CoverageMappingReader>> CoverageReaders;
243     if (UseMultipleReaders) {
244       for (const auto &OF : OutputFunctions) {
245         ArrayRef<OutputFunctionCoverageData> Funcs(OF);
246         CoverageReaders.push_back(
247             std::make_unique<CoverageMappingReaderMock>(Funcs));
248       }
249     } else {
250       ArrayRef<OutputFunctionCoverageData> Funcs(OutputFunctions);
251       CoverageReaders.push_back(
252           std::make_unique<CoverageMappingReaderMock>(Funcs));
253     }
254     return CoverageMapping::load(CoverageReaders, *ProfileReader);
255   }
256 
loadCoverageMapping__anonaa9da0780211::CoverageMappingTest257   Error loadCoverageMapping(bool EmitFilenames = true) {
258     readProfCounts();
259     writeAndReadCoverageRegions(EmitFilenames);
260     auto CoverageOrErr = readOutputFunctions();
261     if (!CoverageOrErr)
262       return CoverageOrErr.takeError();
263     LoadedCoverage = std::move(CoverageOrErr.get());
264     return Error::success();
265   }
266 };
267 
TEST_P(CoverageMappingTest,basic_write_read)268 TEST_P(CoverageMappingTest, basic_write_read) {
269   startFunction("func", 0x1234);
270   addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);
271   addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2);
272   addCMR(Counter::getZero(),     "foo", 3, 1, 3, 4);
273   addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8);
274   addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4);
275 
276   writeAndReadCoverageRegions();
277   ASSERT_EQ(1u, InputFunctions.size());
278   ASSERT_EQ(1u, OutputFunctions.size());
279   InputFunctionCoverageData &Input = InputFunctions.back();
280   OutputFunctionCoverageData &Output = OutputFunctions.back();
281 
282   size_t N = makeArrayRef(Input.Regions).size();
283   ASSERT_EQ(N, Output.Regions.size());
284   for (size_t I = 0; I < N; ++I) {
285     ASSERT_EQ(Input.Regions[I].Count, Output.Regions[I].Count);
286     ASSERT_EQ(Input.Regions[I].FileID, Output.Regions[I].FileID);
287     ASSERT_EQ(Input.Regions[I].startLoc(), Output.Regions[I].startLoc());
288     ASSERT_EQ(Input.Regions[I].endLoc(), Output.Regions[I].endLoc());
289     ASSERT_EQ(Input.Regions[I].Kind, Output.Regions[I].Kind);
290   }
291 }
292 
TEST_P(CoverageMappingTest,correct_deserialize_for_more_than_two_files)293 TEST_P(CoverageMappingTest, correct_deserialize_for_more_than_two_files) {
294   const char *FileNames[] = {"bar", "baz", "foo"};
295   static const unsigned N = array_lengthof(FileNames);
296 
297   startFunction("func", 0x1234);
298   for (unsigned I = 0; I < N; ++I)
299     // Use LineStart to hold the index of the file name
300     // in order to preserve that information during possible sorting of CMRs.
301     addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);
302 
303   writeAndReadCoverageRegions();
304   ASSERT_EQ(1u, OutputFunctions.size());
305   OutputFunctionCoverageData &Output = OutputFunctions.back();
306 
307   ASSERT_EQ(N, Output.Regions.size());
308   ASSERT_EQ(N, Output.Filenames.size());
309 
310   for (unsigned I = 0; I < N; ++I) {
311     ASSERT_GT(N, Output.Regions[I].FileID);
312     ASSERT_GT(N, Output.Regions[I].LineStart);
313     EXPECT_EQ(FileNames[Output.Regions[I].LineStart],
314               Output.Filenames[Output.Regions[I].FileID]);
315   }
316 }
317 
__anonaa9da0780302(Error E) 318 static const auto Err = [](Error E) { FAIL(); };
319 
TEST_P(CoverageMappingTest,load_coverage_for_more_than_two_files)320 TEST_P(CoverageMappingTest, load_coverage_for_more_than_two_files) {
321   ProfileWriter.addRecord({"func", 0x1234, {0}}, Err);
322 
323   const char *FileNames[] = {"bar", "baz", "foo"};
324   static const unsigned N = array_lengthof(FileNames);
325 
326   startFunction("func", 0x1234);
327   for (unsigned I = 0; I < N; ++I)
328     // Use LineStart to hold the index of the file name
329     // in order to preserve that information during possible sorting of CMRs.
330     addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);
331 
332   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
333 
334   for (unsigned I = 0; I < N; ++I) {
335     CoverageData Data = LoadedCoverage->getCoverageForFile(FileNames[I]);
336     ASSERT_TRUE(!Data.empty());
337     EXPECT_EQ(I, Data.begin()->Line);
338   }
339 }
340 
TEST_P(CoverageMappingTest,load_coverage_with_bogus_function_name)341 TEST_P(CoverageMappingTest, load_coverage_with_bogus_function_name) {
342   ProfileWriter.addRecord({"", 0x1234, {10}}, Err);
343   startFunction("", 0x1234);
344   addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5);
345   EXPECT_TRUE(ErrorEquals(coveragemap_error::malformed, loadCoverageMapping()));
346 }
347 
TEST_P(CoverageMappingTest,load_coverage_for_several_functions)348 TEST_P(CoverageMappingTest, load_coverage_for_several_functions) {
349   ProfileWriter.addRecord({"func1", 0x1234, {10}}, Err);
350   ProfileWriter.addRecord({"func2", 0x2345, {20}}, Err);
351 
352   startFunction("func1", 0x1234);
353   addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5);
354 
355   startFunction("func2", 0x2345);
356   addCMR(Counter::getCounter(0), "bar", 2, 2, 6, 6);
357 
358   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
359 
360   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
361   EXPECT_EQ(2, std::distance(FunctionRecords.begin(), FunctionRecords.end()));
362   for (const auto &FunctionRecord : FunctionRecords) {
363     CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
364     std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
365     ASSERT_EQ(2U, Segments.size());
366     if (FunctionRecord.Name == "func1") {
367       EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
368       EXPECT_EQ(CoverageSegment(5, 5, false), Segments[1]);
369     } else {
370       ASSERT_EQ("func2", FunctionRecord.Name);
371       EXPECT_EQ(CoverageSegment(2, 2, 20, true), Segments[0]);
372       EXPECT_EQ(CoverageSegment(6, 6, false), Segments[1]);
373     }
374   }
375 }
376 
TEST_P(CoverageMappingTest,create_combined_regions)377 TEST_P(CoverageMappingTest, create_combined_regions) {
378   ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3}}, Err);
379   startFunction("func1", 0x1234);
380 
381   // Given regions which start at the same location, emit a segment for the
382   // last region.
383   addCMR(Counter::getCounter(0), "file1", 1, 1, 2, 2);
384   addCMR(Counter::getCounter(1), "file1", 1, 1, 2, 2);
385   addCMR(Counter::getCounter(2), "file1", 1, 1, 2, 2);
386 
387   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
388   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
389   const auto &FunctionRecord = *FunctionRecords.begin();
390   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
391   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
392 
393   ASSERT_EQ(2U, Segments.size());
394   EXPECT_EQ(CoverageSegment(1, 1, 6, true), Segments[0]);
395   EXPECT_EQ(CoverageSegment(2, 2, false), Segments[1]);
396 }
397 
TEST_P(CoverageMappingTest,skipped_segments_have_no_count)398 TEST_P(CoverageMappingTest, skipped_segments_have_no_count) {
399   ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err);
400   startFunction("func1", 0x1234);
401 
402   addCMR(Counter::getCounter(0), "file1", 1, 1, 5, 5);
403   addCMR(Counter::getCounter(0), "file1", 5, 1, 5, 5, /*Skipped=*/true);
404 
405   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
406   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
407   const auto &FunctionRecord = *FunctionRecords.begin();
408   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
409   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
410 
411   ASSERT_EQ(3U, Segments.size());
412   EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
413   EXPECT_EQ(CoverageSegment(5, 1, true), Segments[1]);
414   EXPECT_EQ(CoverageSegment(5, 5, false), Segments[2]);
415 }
416 
TEST_P(CoverageMappingTest,multiple_regions_end_after_parent_ends)417 TEST_P(CoverageMappingTest, multiple_regions_end_after_parent_ends) {
418   ProfileWriter.addRecord({"func1", 0x1234, {1, 0}}, Err);
419   startFunction("func1", 0x1234);
420 
421   // 1| F{ a{
422   // 2|
423   // 3|    a} b{ c{
424   // 4|
425   // 5|    b}
426   // 6|
427   // 7| c} d{   e{
428   // 8|
429   // 9| d}      e} F}
430   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); // < F
431   addCMR(Counter::getCounter(0), "file1", 1, 1, 3, 5); // < a
432   addCMR(Counter::getCounter(0), "file1", 3, 5, 5, 4); // < b
433   addCMR(Counter::getCounter(1), "file1", 3, 5, 7, 3); // < c
434   addCMR(Counter::getCounter(1), "file1", 7, 3, 9, 2); // < d
435   addCMR(Counter::getCounter(1), "file1", 7, 7, 9, 7); // < e
436 
437   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
438   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
439   const auto &FunctionRecord = *FunctionRecords.begin();
440   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
441   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
442 
443   // Old output (not sorted or unique):
444   //   Segment at 1:1 with count 1
445   //   Segment at 1:1 with count 1
446   //   Segment at 3:5 with count 1
447   //   Segment at 3:5 with count 0
448   //   Segment at 3:5 with count 1
449   //   Segment at 5:4 with count 0
450   //   Segment at 7:3 with count 1
451   //   Segment at 7:3 with count 0
452   //   Segment at 7:7 with count 0
453   //   Segment at 9:7 with count 0
454   //   Segment at 9:2 with count 1
455   //   Top level segment at 9:9
456 
457   // New output (sorted and unique):
458   //   Segment at 1:1 (count = 1), RegionEntry
459   //   Segment at 3:5 (count = 1), RegionEntry
460   //   Segment at 5:4 (count = 0)
461   //   Segment at 7:3 (count = 0), RegionEntry
462   //   Segment at 7:7 (count = 0), RegionEntry
463   //   Segment at 9:2 (count = 0)
464   //   Segment at 9:7 (count = 1)
465   //   Segment at 9:9 (count = 0), Skipped
466 
467   ASSERT_EQ(8U, Segments.size());
468   EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
469   EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[1]);
470   EXPECT_EQ(CoverageSegment(5, 4, 0, false), Segments[2]);
471   EXPECT_EQ(CoverageSegment(7, 3, 0, true), Segments[3]);
472   EXPECT_EQ(CoverageSegment(7, 7, 0, true), Segments[4]);
473   EXPECT_EQ(CoverageSegment(9, 2, 0, false), Segments[5]);
474   EXPECT_EQ(CoverageSegment(9, 7, 1, false), Segments[6]);
475   EXPECT_EQ(CoverageSegment(9, 9, false), Segments[7]);
476 }
477 
TEST_P(CoverageMappingTest,multiple_completed_segments_at_same_loc)478 TEST_P(CoverageMappingTest, multiple_completed_segments_at_same_loc) {
479   ProfileWriter.addRecord({"func1", 0x1234, {0, 1, 2}}, Err);
480   startFunction("func1", 0x1234);
481 
482   // PR35495
483   addCMR(Counter::getCounter(1), "file1", 2, 1, 18, 2);
484   addCMR(Counter::getCounter(0), "file1", 8, 10, 14, 6);
485   addCMR(Counter::getCounter(0), "file1", 8, 12, 14, 6);
486   addCMR(Counter::getCounter(1), "file1", 9, 1, 14, 6);
487   addCMR(Counter::getCounter(2), "file1", 11, 13, 11, 14);
488 
489   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
490   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
491   const auto &FunctionRecord = *FunctionRecords.begin();
492   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
493   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
494 
495   ASSERT_EQ(7U, Segments.size());
496   EXPECT_EQ(CoverageSegment(2, 1, 1, true), Segments[0]);
497   EXPECT_EQ(CoverageSegment(8, 10, 0, true), Segments[1]);
498   EXPECT_EQ(CoverageSegment(8, 12, 0, true), Segments[2]);
499   EXPECT_EQ(CoverageSegment(9, 1, 1, true), Segments[3]);
500   EXPECT_EQ(CoverageSegment(11, 13, 2, true), Segments[4]);
501   // Use count=1 (from 9:1 -> 14:6), not count=0 (from 8:12 -> 14:6).
502   EXPECT_EQ(CoverageSegment(11, 14, 1, false), Segments[5]);
503   EXPECT_EQ(CoverageSegment(18, 2, false), Segments[6]);
504 }
505 
TEST_P(CoverageMappingTest,dont_emit_redundant_segments)506 TEST_P(CoverageMappingTest, dont_emit_redundant_segments) {
507   ProfileWriter.addRecord({"func1", 0x1234, {1, 1}}, Err);
508   startFunction("func1", 0x1234);
509 
510   addCMR(Counter::getCounter(0), "file1", 1, 1, 4, 4);
511   addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5);
512   addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 6);
513 
514   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
515   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
516   const auto &FunctionRecord = *FunctionRecords.begin();
517   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
518   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
519 
520   ASSERT_EQ(5U, Segments.size());
521   EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
522   EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]);
523   EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]);
524   EXPECT_EQ(CoverageSegment(4, 4, 1, false), Segments[3]);
525   // A closing segment starting at 5:5 would be redundant: it would have the
526   // same count as the segment starting at 4:4, and has all the same metadata.
527   EXPECT_EQ(CoverageSegment(6, 6, false), Segments[4]);
528 }
529 
TEST_P(CoverageMappingTest,dont_emit_closing_segment_at_new_region_start)530 TEST_P(CoverageMappingTest, dont_emit_closing_segment_at_new_region_start) {
531   ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err);
532   startFunction("func1", 0x1234);
533 
534   addCMR(Counter::getCounter(0), "file1", 1, 1, 6, 5);
535   addCMR(Counter::getCounter(0), "file1", 2, 2, 6, 5);
536   addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 5);
537   addCMR(Counter::getCounter(0), "file1", 6, 5, 7, 7);
538 
539   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
540   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
541   const auto &FunctionRecord = *FunctionRecords.begin();
542   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
543   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
544 
545   ASSERT_EQ(5U, Segments.size());
546   EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
547   EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]);
548   EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]);
549   EXPECT_EQ(CoverageSegment(6, 5, 1, true), Segments[3]);
550   // The old segment builder would get this wrong by emitting multiple segments
551   // which start at 6:5 (a few of which were skipped segments). We should just
552   // get a segment for the region entry.
553   EXPECT_EQ(CoverageSegment(7, 7, false), Segments[4]);
554 }
555 
TEST_P(CoverageMappingTest,handle_consecutive_regions_with_zero_length)556 TEST_P(CoverageMappingTest, handle_consecutive_regions_with_zero_length) {
557   ProfileWriter.addRecord({"func1", 0x1234, {1, 2}}, Err);
558   startFunction("func1", 0x1234);
559 
560   addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
561   addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1);
562   addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
563   addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1);
564   addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
565 
566   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
567   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
568   const auto &FunctionRecord = *FunctionRecords.begin();
569   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
570   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
571 
572   ASSERT_EQ(1U, Segments.size());
573   EXPECT_EQ(CoverageSegment(1, 1, true), Segments[0]);
574   // We need to get a skipped segment starting at 1:1. In this case there is
575   // also a region entry at 1:1.
576 }
577 
TEST_P(CoverageMappingTest,handle_sandwiched_zero_length_region)578 TEST_P(CoverageMappingTest, handle_sandwiched_zero_length_region) {
579   ProfileWriter.addRecord({"func1", 0x1234, {2, 1}}, Err);
580   startFunction("func1", 0x1234);
581 
582   addCMR(Counter::getCounter(0), "file1", 1, 5, 4, 4);
583   addCMR(Counter::getCounter(1), "file1", 1, 9, 1, 50);
584   addCMR(Counter::getCounter(1), "file1", 2, 7, 2, 34);
585   addCMR(Counter::getCounter(1), "file1", 3, 5, 3, 21);
586   addCMR(Counter::getCounter(1), "file1", 3, 21, 3, 21);
587   addCMR(Counter::getCounter(1), "file1", 4, 12, 4, 17);
588 
589   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
590   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
591   const auto &FunctionRecord = *FunctionRecords.begin();
592   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
593   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
594 
595   ASSERT_EQ(10U, Segments.size());
596   EXPECT_EQ(CoverageSegment(1, 5, 2, true), Segments[0]);
597   EXPECT_EQ(CoverageSegment(1, 9, 1, true), Segments[1]);
598   EXPECT_EQ(CoverageSegment(1, 50, 2, false), Segments[2]);
599   EXPECT_EQ(CoverageSegment(2, 7, 1, true), Segments[3]);
600   EXPECT_EQ(CoverageSegment(2, 34, 2, false), Segments[4]);
601   EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[5]);
602   EXPECT_EQ(CoverageSegment(3, 21, 2, true), Segments[6]);
603   // Handle the zero-length region by creating a segment with its predecessor's
604   // count (i.e the count from 1:5 -> 4:4).
605   EXPECT_EQ(CoverageSegment(4, 4, false), Segments[7]);
606   // The area between 4:4 and 4:12 is skipped.
607   EXPECT_EQ(CoverageSegment(4, 12, 1, true), Segments[8]);
608   EXPECT_EQ(CoverageSegment(4, 17, false), Segments[9]);
609 }
610 
TEST_P(CoverageMappingTest,handle_last_completed_region)611 TEST_P(CoverageMappingTest, handle_last_completed_region) {
612   ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3, 4}}, Err);
613   startFunction("func1", 0x1234);
614 
615   addCMR(Counter::getCounter(0), "file1", 1, 1, 8, 8);
616   addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5);
617   addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
618   addCMR(Counter::getCounter(3), "file1", 6, 6, 7, 7);
619 
620   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
621   const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
622   const auto &FunctionRecord = *FunctionRecords.begin();
623   CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
624   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
625 
626   ASSERT_EQ(8U, Segments.size());
627   EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
628   EXPECT_EQ(CoverageSegment(2, 2, 2, true), Segments[1]);
629   EXPECT_EQ(CoverageSegment(3, 3, 3, true), Segments[2]);
630   EXPECT_EQ(CoverageSegment(4, 4, 2, false), Segments[3]);
631   EXPECT_EQ(CoverageSegment(5, 5, 1, false), Segments[4]);
632   EXPECT_EQ(CoverageSegment(6, 6, 4, true), Segments[5]);
633   EXPECT_EQ(CoverageSegment(7, 7, 1, false), Segments[6]);
634   EXPECT_EQ(CoverageSegment(8, 8, false), Segments[7]);
635 }
636 
TEST_P(CoverageMappingTest,expansion_gets_first_counter)637 TEST_P(CoverageMappingTest, expansion_gets_first_counter) {
638   startFunction("func", 0x1234);
639   addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2);
640   // This starts earlier in "foo", so the expansion should get its counter.
641   addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1);
642   addExpansionCMR("bar", "foo", 3, 3, 3, 3);
643 
644   writeAndReadCoverageRegions();
645   ASSERT_EQ(1u, OutputFunctions.size());
646   OutputFunctionCoverageData &Output = OutputFunctions.back();
647 
648   ASSERT_EQ(CounterMappingRegion::ExpansionRegion, Output.Regions[2].Kind);
649   ASSERT_EQ(Counter::getCounter(2), Output.Regions[2].Count);
650   ASSERT_EQ(3U, Output.Regions[2].LineStart);
651 }
652 
TEST_P(CoverageMappingTest,basic_coverage_iteration)653 TEST_P(CoverageMappingTest, basic_coverage_iteration) {
654   ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err);
655 
656   startFunction("func", 0x1234);
657   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
658   addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
659   addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
660   addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
661   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
662 
663   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
664   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
665   ASSERT_EQ(7U, Segments.size());
666   ASSERT_EQ(CoverageSegment(1, 1, 20, true),  Segments[0]);
667   ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]);
668   ASSERT_EQ(CoverageSegment(5, 8, 10, true),  Segments[2]);
669   ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]);
670   ASSERT_EQ(CoverageSegment(9, 9, false),     Segments[4]);
671   ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]);
672   ASSERT_EQ(CoverageSegment(11, 11, false),   Segments[6]);
673 }
674 
TEST_P(CoverageMappingTest,test_line_coverage_iterator)675 TEST_P(CoverageMappingTest, test_line_coverage_iterator) {
676   ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err);
677 
678   startFunction("func", 0x1234);
679   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
680   addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
681   addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
682   addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
683   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
684 
685   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
686 
687   unsigned Line = 0;
688   unsigned LineCounts[] = {20, 20, 20, 20, 30, 10, 10, 10, 10, 0, 0};
689   for (const auto &LCS : getLineCoverageStats(Data)) {
690     ASSERT_EQ(Line + 1, LCS.getLine());
691     errs() << "Line: " << Line + 1 << ", count = " << LCS.getExecutionCount() << "\n";
692     ASSERT_EQ(LineCounts[Line], LCS.getExecutionCount());
693     ++Line;
694   }
695   ASSERT_EQ(11U, Line);
696 }
697 
TEST_P(CoverageMappingTest,uncovered_function)698 TEST_P(CoverageMappingTest, uncovered_function) {
699   startFunction("func", 0x1234);
700   addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
701   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
702 
703   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
704   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
705   ASSERT_EQ(2U, Segments.size());
706   ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
707   ASSERT_EQ(CoverageSegment(3, 4, false),   Segments[1]);
708 }
709 
TEST_P(CoverageMappingTest,uncovered_function_with_mapping)710 TEST_P(CoverageMappingTest, uncovered_function_with_mapping) {
711   startFunction("func", 0x1234);
712   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
713   addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
714   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
715 
716   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
717   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
718   ASSERT_EQ(3U, Segments.size());
719   ASSERT_EQ(CoverageSegment(1, 1, 0, true),  Segments[0]);
720   ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]);
721   ASSERT_EQ(CoverageSegment(9, 9, false),    Segments[2]);
722 }
723 
TEST_P(CoverageMappingTest,combine_regions)724 TEST_P(CoverageMappingTest, combine_regions) {
725   ProfileWriter.addRecord({"func", 0x1234, {10, 20, 30}}, Err);
726 
727   startFunction("func", 0x1234);
728   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
729   addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
730   addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
731   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
732 
733   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
734   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
735   ASSERT_EQ(4U, Segments.size());
736   ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
737   ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]);
738   ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
739   ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
740 }
741 
TEST_P(CoverageMappingTest,restore_combined_counter_after_nested_region)742 TEST_P(CoverageMappingTest, restore_combined_counter_after_nested_region) {
743   ProfileWriter.addRecord({"func", 0x1234, {10, 20, 40}}, Err);
744 
745   startFunction("func", 0x1234);
746   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
747   addCMR(Counter::getCounter(1), "file1", 1, 1, 9, 9);
748   addCMR(Counter::getCounter(2), "file1", 3, 3, 5, 5);
749   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
750 
751   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
752   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
753   ASSERT_EQ(4U, Segments.size());
754   EXPECT_EQ(CoverageSegment(1, 1, 30, true), Segments[0]);
755   EXPECT_EQ(CoverageSegment(3, 3, 40, true), Segments[1]);
756   EXPECT_EQ(CoverageSegment(5, 5, 30, false), Segments[2]);
757   EXPECT_EQ(CoverageSegment(9, 9, false), Segments[3]);
758 }
759 
760 // If CodeRegions and ExpansionRegions cover the same area,
761 // only counts of CodeRegions should be used.
TEST_P(CoverageMappingTest,dont_combine_expansions)762 TEST_P(CoverageMappingTest, dont_combine_expansions) {
763   ProfileWriter.addRecord({"func", 0x1234, {10, 20}}, Err);
764   ProfileWriter.addRecord({"func", 0x1234, {0, 0}}, Err);
765 
766   startFunction("func", 0x1234);
767   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
768   addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
769   addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
770   addExpansionCMR("file1", "include1", 3, 3, 4, 4);
771   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
772 
773   CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
774   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
775   ASSERT_EQ(4U, Segments.size());
776   ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
777   ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]);
778   ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
779   ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
780 }
781 
782 // If an area is covered only by ExpansionRegions, they should be combinated.
TEST_P(CoverageMappingTest,combine_expansions)783 TEST_P(CoverageMappingTest, combine_expansions) {
784   ProfileWriter.addRecord({"func", 0x1234, {2, 3, 7}}, Err);
785 
786   startFunction("func", 0x1234);
787   addCMR(Counter::getCounter(1), "include1", 1, 1, 1, 10);
788   addCMR(Counter::getCounter(2), "include2", 1, 1, 1, 10);
789   addCMR(Counter::getCounter(0), "file", 1, 1, 5, 5);
790   addExpansionCMR("file", "include1", 3, 1, 3, 5);
791   addExpansionCMR("file", "include2", 3, 1, 3, 5);
792 
793   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
794 
795   CoverageData Data = LoadedCoverage->getCoverageForFile("file");
796   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
797   ASSERT_EQ(4U, Segments.size());
798   EXPECT_EQ(CoverageSegment(1, 1, 2, true), Segments[0]);
799   EXPECT_EQ(CoverageSegment(3, 1, 10, true), Segments[1]);
800   EXPECT_EQ(CoverageSegment(3, 5, 2, false), Segments[2]);
801   EXPECT_EQ(CoverageSegment(5, 5, false), Segments[3]);
802 }
803 
804 // Test that counters not associated with any code regions are allowed.
TEST_P(CoverageMappingTest,non_code_region_counters)805 TEST_P(CoverageMappingTest, non_code_region_counters) {
806   // No records in profdata
807 
808   startFunction("func", 0x1234);
809   addCMR(Counter::getCounter(0), "file", 1, 1, 5, 5);
810   addCMR(Counter::getExpression(0), "file", 6, 1, 6, 5);
811   addExpression(CounterExpression(
812       CounterExpression::Add, Counter::getCounter(1), Counter::getCounter(2)));
813 
814   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
815 
816   std::vector<std::string> Names;
817   for (const auto &Func : LoadedCoverage->getCoveredFunctions()) {
818     Names.push_back(Func.Name);
819     ASSERT_EQ(2U, Func.CountedRegions.size());
820   }
821   ASSERT_EQ(1U, Names.size());
822 }
823 
TEST_P(CoverageMappingTest,strip_filename_prefix)824 TEST_P(CoverageMappingTest, strip_filename_prefix) {
825   ProfileWriter.addRecord({"file1:func", 0x1234, {0}}, Err);
826 
827   startFunction("file1:func", 0x1234);
828   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
829   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
830 
831   std::vector<std::string> Names;
832   for (const auto &Func : LoadedCoverage->getCoveredFunctions())
833     Names.push_back(Func.Name);
834   ASSERT_EQ(1U, Names.size());
835   ASSERT_EQ("func", Names[0]);
836 }
837 
TEST_P(CoverageMappingTest,strip_unknown_filename_prefix)838 TEST_P(CoverageMappingTest, strip_unknown_filename_prefix) {
839   ProfileWriter.addRecord({"<unknown>:func", 0x1234, {0}}, Err);
840 
841   startFunction("<unknown>:func", 0x1234);
842   addCMR(Counter::getCounter(0), "", 1, 1, 9, 9);
843   EXPECT_THAT_ERROR(loadCoverageMapping(/*EmitFilenames=*/false), Succeeded());
844 
845   std::vector<std::string> Names;
846   for (const auto &Func : LoadedCoverage->getCoveredFunctions())
847     Names.push_back(Func.Name);
848   ASSERT_EQ(1U, Names.size());
849   ASSERT_EQ("func", Names[0]);
850 }
851 
TEST_P(CoverageMappingTest,dont_detect_false_instantiations)852 TEST_P(CoverageMappingTest, dont_detect_false_instantiations) {
853   ProfileWriter.addRecord({"foo", 0x1234, {10}}, Err);
854   ProfileWriter.addRecord({"bar", 0x2345, {20}}, Err);
855 
856   startFunction("foo", 0x1234);
857   addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
858   addExpansionCMR("main", "expanded", 4, 1, 4, 5);
859 
860   startFunction("bar", 0x2345);
861   addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
862   addExpansionCMR("main", "expanded", 9, 1, 9, 5);
863 
864   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
865 
866   std::vector<InstantiationGroup> InstantiationGroups =
867       LoadedCoverage->getInstantiationGroups("expanded");
868   ASSERT_TRUE(InstantiationGroups.empty());
869 }
870 
TEST_P(CoverageMappingTest,load_coverage_for_expanded_file)871 TEST_P(CoverageMappingTest, load_coverage_for_expanded_file) {
872   ProfileWriter.addRecord({"func", 0x1234, {10}}, Err);
873 
874   startFunction("func", 0x1234);
875   addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
876   addExpansionCMR("main", "expanded", 4, 1, 4, 5);
877 
878   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
879 
880   CoverageData Data = LoadedCoverage->getCoverageForFile("expanded");
881   std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
882   ASSERT_EQ(2U, Segments.size());
883   EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
884   EXPECT_EQ(CoverageSegment(1, 10, false), Segments[1]);
885 }
886 
TEST_P(CoverageMappingTest,skip_duplicate_function_record)887 TEST_P(CoverageMappingTest, skip_duplicate_function_record) {
888   ProfileWriter.addRecord({"func", 0x1234, {1}}, Err);
889 
890   // This record should be loaded.
891   startFunction("func", 0x1234);
892   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
893 
894   // This record should be loaded.
895   startFunction("func", 0x1234);
896   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
897   addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
898 
899   // This record should be skipped.
900   startFunction("func", 0x1234);
901   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
902 
903   // This record should be loaded.
904   startFunction("func", 0x1234);
905   addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
906   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
907 
908   // This record should be skipped.
909   startFunction("func", 0x1234);
910   addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
911   addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
912 
913   EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
914 
915   auto Funcs = LoadedCoverage->getCoveredFunctions();
916   unsigned NumFuncs = std::distance(Funcs.begin(), Funcs.end());
917   ASSERT_EQ(3U, NumFuncs);
918 }
919 
920 INSTANTIATE_TEST_SUITE_P(ParameterizedCovMapTest, CoverageMappingTest,
921                          ::testing::Combine(::testing::Bool(),
922                                             ::testing::Bool()));
923 
TEST(CoverageMappingTest,filename_roundtrip)924 TEST(CoverageMappingTest, filename_roundtrip) {
925   std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
926 
927   for (bool Compress : {false, true}) {
928     std::string EncodedFilenames;
929     {
930       raw_string_ostream OS(EncodedFilenames);
931       CoverageFilenamesSectionWriter Writer(Paths);
932       Writer.write(OS, Compress);
933     }
934 
935     std::vector<std::string> ReadFilenames;
936     RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames);
937     EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
938 
939     ASSERT_EQ(ReadFilenames.size(), Paths.size());
940     for (unsigned I = 1; I < Paths.size(); ++I) {
941       SmallString<256> P(Paths[0]);
942       llvm::sys::path::append(P, Paths[I]);
943       ASSERT_TRUE(ReadFilenames[I] == P);
944     }
945   }
946 }
947 
TEST(CoverageMappingTest,filename_compilation_dir)948 TEST(CoverageMappingTest, filename_compilation_dir) {
949   std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
950 
951   for (bool Compress : {false, true}) {
952     std::string EncodedFilenames;
953     {
954       raw_string_ostream OS(EncodedFilenames);
955       CoverageFilenamesSectionWriter Writer(Paths);
956       Writer.write(OS, Compress);
957     }
958 
959     StringRef CompilationDir = "out";
960     std::vector<std::string> ReadFilenames;
961     RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames,
962                                       CompilationDir);
963     EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
964 
965     ASSERT_EQ(ReadFilenames.size(), Paths.size());
966     for (unsigned I = 1; I < Paths.size(); ++I) {
967       SmallString<256> P(CompilationDir);
968       llvm::sys::path::append(P, Paths[I]);
969       ASSERT_TRUE(ReadFilenames[I] == P);
970     }
971   }
972 }
973 
974 } // end anonymous namespace
975