Skip to content

Commit 738e927

Browse files
kuzmich321Swatinem
andauthored
Add executed MC/DC TestVectors to llvm-cov export (#159119)
It adds a new JSON array with the list of test vectors to the end of the mcdc_records. I also bumped the json format version accordingly, which I believe wasn’t done properly in the past when new fields were added. This PR adds tests and comment docs for #105511 --------- Co-authored-by: Arpad Borsos <[email protected]>
1 parent 08c98ba commit 738e927

File tree

3 files changed

+49
-24
lines changed

3 files changed

+49
-24
lines changed

llvm/test/tools/llvm-cov/Inputs/binary-formats.canonical.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ CHECK-SAME: "mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},
3333
CHECK-SAME: "regions":{"count":1,"covered":1,"notcovered":0,"percent":100}}}
3434
CHECK-SAME: ],
3535
CHECK-SAME: "type":"llvm.coverage.json.export"
36-
CHECK-SAME: "version":"3.0.1"
36+
CHECK-SAME: "version":"3.1.0"

llvm/test/tools/llvm-cov/mcdc-export-json.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// RUN: llvm-profdata merge %S/Inputs/mcdc-general.proftext -o %t.profdata
22
// RUN: llvm-cov export --format=text %S/Inputs/mcdc-general.o -instr-profile %t.profdata | FileCheck %s
33

4-
// CHECK: 12,7,12,27,2,4,0,0,5,[true,true,true,true]
5-
// CHECK: 15,7,15,13,1,2,0,0,5,[true,true]
6-
// CHECK: 15,19,15,25,1,1,0,0,5,[true,false]
7-
// CHECK: 18,7,19,15,1,3,0,0,5,[true,true,false,true]
4+
// CHECK: 12,7,12,27,2,4,0,0,5,[true,true,true,true],[{"conditions":[false,null,false,null],"executed":true,"result":false},{"conditions":[false,null,true,false],"executed":true,"result":false},{"conditions":[true,false,false,null],"executed":true,"result":false},{"conditions":[true,false,true,false],"executed":true,"result":false},{"conditions":[true,false,true,true],"executed":true,"result":true},{"conditions":[true,true,null,null],"executed":true,"result":true}]
5+
// CHECK: 15,7,15,13,1,2,0,0,5,[true,true],[{"conditions":[false,null],"executed":true,"result":false},{"conditions":[true,false],"executed":true,"result":false},{"conditions":[true,true],"executed":true,"result":true}]
6+
// CHECK: 15,19,15,25,1,1,0,0,5,[true,false],[{"conditions":[false,null],"executed":true,"result":false},{"conditions":[true,true],"executed":true,"result":true}]
7+
// CHECK: 18,7,19,15,1,3,0,0,5,[true,true,false,true],[{"conditions":[false,null,null,null],"executed":true,"result":false},{"conditions":[true,false,null,null],"executed":true,"result":false},{"conditions":[true,true,true,false],"executed":true,"result":false},{"conditions":[true,true,true,true],"executed":true,"result":true}]
88
// CHECK: "mcdc":{"count":12,"covered":10,"notcovered":2,"percent":83.333333333333343}
99

1010
Instructions for regenerating the test:

llvm/tools/llvm-cov/CoverageExporterJson.cpp

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
// -- Branches: array => List of Branches in the file
2222
// -- Branch: dict => Describes a branch of the file with counters
2323
// -- MCDC Records: array => List of MCDC records in the file
24-
// -- MCDC Values: array => List of T/F covered condition values
24+
// -- MCDC Values: array => List of T/F covered condition values and
25+
// list of executed test vectors
2526
// -- Segments: array => List of Segments contained in the file
2627
// -- Segment: dict => Describes a segment of the file with a counter
2728
// -- Expansions: array => List of expansion records
@@ -62,7 +63,7 @@
6263
#include <utility>
6364

6465
/// The semantic version combined as a string.
65-
#define LLVM_COVERAGE_EXPORT_JSON_STR "3.0.1"
66+
#define LLVM_COVERAGE_EXPORT_JSON_STR "3.1.0"
6667

6768
/// Unique type identifier for JSON coverage export.
6869
#define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR "llvm.coverage.json.export"
@@ -108,13 +109,42 @@ json::Array gatherConditions(const coverage::MCDCRecord &Record) {
108109
return Conditions;
109110
}
110111

112+
json::Value renderCondState(const coverage::MCDCRecord::CondState CondState) {
113+
switch (CondState) {
114+
case coverage::MCDCRecord::MCDC_DontCare:
115+
return json::Value(nullptr);
116+
case coverage::MCDCRecord::MCDC_True:
117+
return json::Value(true);
118+
case coverage::MCDCRecord::MCDC_False:
119+
return json::Value(false);
120+
}
121+
}
122+
123+
json::Array gatherTestVectors(coverage::MCDCRecord &Record) {
124+
json::Array TestVectors;
125+
unsigned NumConditions = Record.getNumConditions();
126+
for (unsigned tv = 0; tv < Record.getNumTestVectors(); tv++) {
127+
128+
json::Array TVConditions;
129+
for (unsigned c = 0; c < NumConditions; c++)
130+
TVConditions.push_back(renderCondState(Record.getTVCondition(tv, c)));
131+
132+
TestVectors.push_back(
133+
json::Object({{"executed", json::Value(true)},
134+
{"result", renderCondState(Record.getTVResult(tv))},
135+
{"conditions", std::move(TVConditions)}}));
136+
}
137+
return TestVectors;
138+
}
139+
111140
json::Array renderMCDCRecord(const coverage::MCDCRecord &Record) {
112141
const llvm::coverage::CounterMappingRegion &CMR = Record.getDecisionRegion();
113142
const auto [TrueDecisions, FalseDecisions] = Record.getDecisions();
114-
return json::Array({CMR.LineStart, CMR.ColumnStart, CMR.LineEnd,
115-
CMR.ColumnEnd, TrueDecisions, FalseDecisions,
116-
CMR.FileID, CMR.ExpandedFileID, int64_t(CMR.Kind),
117-
gatherConditions(Record)});
143+
return json::Array(
144+
{CMR.LineStart, CMR.ColumnStart, CMR.LineEnd, CMR.ColumnEnd,
145+
TrueDecisions, FalseDecisions, CMR.FileID, CMR.ExpandedFileID,
146+
int64_t(CMR.Kind), gatherConditions(Record),
147+
gatherTestVectors(const_cast<coverage::MCDCRecord &>(Record))});
118148
}
119149

120150
json::Array renderRegions(ArrayRef<coverage::CountedRegion> Regions) {
@@ -216,32 +246,28 @@ json::Object renderSummary(const FileCoverageSummary &Summary) {
216246
}
217247

218248
json::Array renderFileExpansions(const coverage::CoverageMapping &Coverage,
219-
const coverage::CoverageData &FileCoverage,
220-
const FileCoverageSummary &FileReport) {
249+
const coverage::CoverageData &FileCoverage) {
221250
json::Array ExpansionArray;
222251
for (const auto &Expansion : FileCoverage.getExpansions())
223252
ExpansionArray.push_back(renderExpansion(Coverage, Expansion));
224253
return ExpansionArray;
225254
}
226255

227-
json::Array renderFileSegments(const coverage::CoverageData &FileCoverage,
228-
const FileCoverageSummary &FileReport) {
256+
json::Array renderFileSegments(const coverage::CoverageData &FileCoverage) {
229257
json::Array SegmentArray;
230258
for (const auto &Segment : FileCoverage)
231259
SegmentArray.push_back(renderSegment(Segment));
232260
return SegmentArray;
233261
}
234262

235-
json::Array renderFileBranches(const coverage::CoverageData &FileCoverage,
236-
const FileCoverageSummary &FileReport) {
263+
json::Array renderFileBranches(const coverage::CoverageData &FileCoverage) {
237264
json::Array BranchArray;
238265
for (const auto &Branch : FileCoverage.getBranches())
239266
BranchArray.push_back(renderBranch(Branch));
240267
return BranchArray;
241268
}
242269

243-
json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage,
244-
const FileCoverageSummary &FileReport) {
270+
json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage) {
245271
json::Array MCDCRecordArray;
246272
for (const auto &Record : FileCoverage.getMCDCRecords())
247273
MCDCRecordArray.push_back(renderMCDCRecord(Record));
@@ -256,12 +282,11 @@ json::Object renderFile(const coverage::CoverageMapping &Coverage,
256282
if (!Options.ExportSummaryOnly) {
257283
// Calculate and render detailed coverage information for given file.
258284
auto FileCoverage = Coverage.getCoverageForFile(Filename);
259-
File["segments"] = renderFileSegments(FileCoverage, FileReport);
260-
File["branches"] = renderFileBranches(FileCoverage, FileReport);
261-
File["mcdc_records"] = renderFileMCDC(FileCoverage, FileReport);
285+
File["segments"] = renderFileSegments(FileCoverage);
286+
File["branches"] = renderFileBranches(FileCoverage);
287+
File["mcdc_records"] = renderFileMCDC(FileCoverage);
262288
if (!Options.SkipExpansions) {
263-
File["expansions"] =
264-
renderFileExpansions(Coverage, FileCoverage, FileReport);
289+
File["expansions"] = renderFileExpansions(Coverage, FileCoverage);
265290
}
266291
}
267292
File["summary"] = renderSummary(FileReport);

0 commit comments

Comments
 (0)