[llvm-cov] add ability to show non executed test vectors for mc/dc coverage (#187517)
- Added `-show-mcdc-non-executed-vectors` option - Non-executed test vectors now are tracked - When the opt is present it's get written to UI
This commit is contained in:
parent
d917027334
commit
ee51de9836
@ -459,15 +459,56 @@ struct MCDCRecord {
|
||||
private:
|
||||
CounterMappingRegion Region;
|
||||
TestVectors TV;
|
||||
TestVectors NotExecutedTV;
|
||||
std::optional<TVPairMap> IndependencePairs;
|
||||
BoolVector Folded;
|
||||
CondIDMap PosToID;
|
||||
LineColPairMap CondLoc;
|
||||
|
||||
std::string formatTestVectorRow(const TestVector &Vec, CondState Result,
|
||||
unsigned DisplayRowNumber) const {
|
||||
std::ostringstream OS;
|
||||
const auto NumConditions = getNumConditions();
|
||||
// Add individual condition values to the string.
|
||||
OS << " " << DisplayRowNumber << " { ";
|
||||
for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
|
||||
if (isCondFolded(Condition))
|
||||
OS << "C";
|
||||
else {
|
||||
auto It = PosToID.find(Condition);
|
||||
assert(It != PosToID.end() && "Ordinal without CondID mapping");
|
||||
switch (Vec[It->second]) {
|
||||
case MCDC_DontCare:
|
||||
OS << "-";
|
||||
break;
|
||||
case MCDC_True:
|
||||
OS << "T";
|
||||
break;
|
||||
case MCDC_False:
|
||||
OS << "F";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Condition != NumConditions - 1)
|
||||
OS << ", ";
|
||||
}
|
||||
|
||||
// Add result value to the string.
|
||||
OS << " = ";
|
||||
if (Result == MCDC_True)
|
||||
OS << "T";
|
||||
else
|
||||
OS << "F";
|
||||
OS << " }\n";
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
public:
|
||||
MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV,
|
||||
BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
|
||||
: Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
|
||||
TestVectors &&NotExecutedTV, BoolVector &&Folded,
|
||||
CondIDMap &&PosToID, LineColPairMap &&CondLoc)
|
||||
: Region(Region), TV(std::move(TV)),
|
||||
NotExecutedTV(std::move(NotExecutedTV)), Folded(std::move(Folded)),
|
||||
PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
|
||||
findIndependencePairs();
|
||||
}
|
||||
@ -481,6 +522,8 @@ public:
|
||||
return Region.getDecisionParams().NumConditions;
|
||||
}
|
||||
unsigned getNumTestVectors() const { return TV.size(); }
|
||||
unsigned getNumNotExecutedTestVectors() const { return NotExecutedTV.size(); }
|
||||
|
||||
bool isCondFolded(unsigned Condition) const {
|
||||
return Folded[false][Condition] || Folded[true][Condition];
|
||||
}
|
||||
@ -495,6 +538,11 @@ public:
|
||||
return TV[TestVectorIndex].first[PosToID[Condition]];
|
||||
}
|
||||
|
||||
CondState getNotExecutedTVCondition(unsigned NotExecutedIndex,
|
||||
unsigned Condition) {
|
||||
return NotExecutedTV[NotExecutedIndex].first[PosToID[Condition]];
|
||||
}
|
||||
|
||||
/// Return the number of True and False decisions for all executed test
|
||||
/// vectors.
|
||||
std::pair<unsigned, unsigned> getDecisions() const {
|
||||
@ -510,6 +558,10 @@ public:
|
||||
return TV[TestVectorIndex].second;
|
||||
}
|
||||
|
||||
CondState getNotExecutedTVResult(unsigned NotExecutedIndex) {
|
||||
return NotExecutedTV[NotExecutedIndex].second;
|
||||
}
|
||||
|
||||
/// Determine whether a given condition (indicated by Condition) is covered
|
||||
/// by an Independence Pair. Because condition IDs are not associated based
|
||||
/// on their position in the expression, accessing conditions in the
|
||||
@ -559,7 +611,7 @@ public:
|
||||
|
||||
std::string getTestVectorHeaderString() const {
|
||||
std::ostringstream OS;
|
||||
if (getNumTestVectors() == 0) {
|
||||
if (getNumTestVectors() == 0 && getNumNotExecutedTestVectors() == 0) {
|
||||
OS << "None.\n";
|
||||
return OS.str();
|
||||
}
|
||||
@ -576,39 +628,16 @@ public:
|
||||
std::string getTestVectorString(unsigned TestVectorIndex) {
|
||||
assert(TestVectorIndex < getNumTestVectors() &&
|
||||
"TestVector index out of bounds!");
|
||||
std::ostringstream OS;
|
||||
const auto NumConditions = getNumConditions();
|
||||
// Add individual condition values to the string.
|
||||
OS << " " << TestVectorIndex + 1 << " { ";
|
||||
for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
|
||||
if (isCondFolded(Condition))
|
||||
OS << "C";
|
||||
else {
|
||||
switch (getTVCondition(TestVectorIndex, Condition)) {
|
||||
case MCDCRecord::MCDC_DontCare:
|
||||
OS << "-";
|
||||
break;
|
||||
case MCDCRecord::MCDC_True:
|
||||
OS << "T";
|
||||
break;
|
||||
case MCDCRecord::MCDC_False:
|
||||
OS << "F";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Condition != NumConditions - 1)
|
||||
OS << ", ";
|
||||
}
|
||||
const auto &[Vec, Res] = TV[TestVectorIndex];
|
||||
return formatTestVectorRow(Vec, Res, TestVectorIndex + 1);
|
||||
}
|
||||
|
||||
// Add result value to the string.
|
||||
OS << " = ";
|
||||
if (getTVResult(TestVectorIndex) == MCDC_True)
|
||||
OS << "T";
|
||||
else
|
||||
OS << "F";
|
||||
OS << " }\n";
|
||||
|
||||
return OS.str();
|
||||
std::string getNotExecutedTestVectorString(unsigned NotExecutedIndex) {
|
||||
assert(NotExecutedIndex < getNumNotExecutedTestVectors() &&
|
||||
"Not-executed test vector index out of bounds!");
|
||||
const auto &[Vec, Res] = NotExecutedTV[NotExecutedIndex];
|
||||
return formatTestVectorRow(Vec, Res,
|
||||
getNumTestVectors() + NotExecutedIndex + 1);
|
||||
}
|
||||
|
||||
std::string getConditionCoverageString(unsigned Condition) {
|
||||
|
||||
@ -426,11 +426,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
|
||||
/// Mapping of calculated MC/DC Independence Pairs for each condition.
|
||||
MCDCRecord::TVPairMap IndependencePairs;
|
||||
|
||||
/// Helper for sorting ExecVectors.
|
||||
/// Helper for sorting ExecVectors / NotExecVectors.
|
||||
struct TVIdxTuple {
|
||||
MCDCRecord::CondState MCDCCond; /// True/False
|
||||
unsigned BIdx; /// Bitmap Index
|
||||
unsigned Ord; /// Last position on ExecVectors
|
||||
unsigned Ord; /// Last position in exec / not-exec TVs
|
||||
|
||||
TVIdxTuple(MCDCRecord::CondState MCDCCond, unsigned BIdx, unsigned Ord)
|
||||
: MCDCCond(MCDCCond), BIdx(BIdx), Ord(Ord) {}
|
||||
@ -441,12 +441,14 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
|
||||
}
|
||||
};
|
||||
|
||||
// Indices for sorted TestVectors;
|
||||
std::vector<TVIdxTuple> ExecVectorIdxs;
|
||||
std::vector<TVIdxTuple> NotExecVectorIdxs;
|
||||
|
||||
/// Actual executed Test Vectors for the boolean expression, based on
|
||||
/// ExecutedTestVectorBitmap.
|
||||
MCDCRecord::TestVectors ExecVectors;
|
||||
/// Never-executed test vectors
|
||||
MCDCRecord::TestVectors NotExecVectors;
|
||||
|
||||
#ifndef NDEBUG
|
||||
DenseSet<unsigned> TVIdxs;
|
||||
@ -486,17 +488,21 @@ private:
|
||||
assert(TVIdx < SavedNodes[ID].Width);
|
||||
assert(TVIdxs.insert(NextTVIdx).second && "Duplicate TVIdx");
|
||||
|
||||
if (!Bitmap[IsVersion11
|
||||
? DecisionParams.BitmapIdx * CHAR_BIT + TV.getIndex()
|
||||
: DecisionParams.BitmapIdx - NumTestVectors + NextTVIdx])
|
||||
continue;
|
||||
|
||||
ExecVectorIdxs.emplace_back(MCDCCond, NextTVIdx, ExecVectors.size());
|
||||
|
||||
// Copy the completed test vector to the vector of testvectors.
|
||||
// The final value (T,F) is equal to the last non-dontcare state on the
|
||||
// path (in a short-circuiting system).
|
||||
ExecVectors.push_back({TV, MCDCCond});
|
||||
bool Executed =
|
||||
Bitmap[IsVersion11
|
||||
? DecisionParams.BitmapIdx * CHAR_BIT + TV.getIndex()
|
||||
: DecisionParams.BitmapIdx - NumTestVectors + NextTVIdx];
|
||||
if (Executed) {
|
||||
ExecVectorIdxs.emplace_back(MCDCCond, NextTVIdx, ExecVectors.size());
|
||||
// Copy the completed test vector to the vector of testvectors.
|
||||
// The final value (T,F) is equal to the last non-dontcare state on the
|
||||
// path (in a short-circuiting system).
|
||||
ExecVectors.push_back({TV, MCDCCond});
|
||||
} else {
|
||||
NotExecVectorIdxs.emplace_back(MCDCCond, NextTVIdx,
|
||||
NotExecVectors.size());
|
||||
NotExecVectors.push_back({TV, MCDCCond});
|
||||
}
|
||||
}
|
||||
|
||||
// Reset back to DontCare.
|
||||
@ -505,7 +511,8 @@ private:
|
||||
|
||||
/// Walk the bits in the bitmap. A bit set to '1' indicates that the test
|
||||
/// vector at the corresponding index was executed during a test run.
|
||||
void findExecutedTestVectors() {
|
||||
/// Vectors with '0' bit are collected separately for UI.
|
||||
void findTestVectors() {
|
||||
// Walk the binary decision diagram to enumerate all possible test vectors.
|
||||
// We start at the root node (ID == 0) with all values being DontCare.
|
||||
// `TVIdx` starts with 0 and is in the traversal.
|
||||
@ -516,10 +523,16 @@ private:
|
||||
"TVIdxs wasn't fulfilled");
|
||||
|
||||
llvm::sort(ExecVectorIdxs);
|
||||
MCDCRecord::TestVectors NewTestVectors;
|
||||
MCDCRecord::TestVectors NewExec;
|
||||
for (const auto &IdxTuple : ExecVectorIdxs)
|
||||
NewTestVectors.push_back(std::move(ExecVectors[IdxTuple.Ord]));
|
||||
ExecVectors = std::move(NewTestVectors);
|
||||
NewExec.push_back(std::move(ExecVectors[IdxTuple.Ord]));
|
||||
ExecVectors = std::move(NewExec);
|
||||
|
||||
llvm::sort(NotExecVectorIdxs);
|
||||
MCDCRecord::TestVectors NewNotExec;
|
||||
for (const auto &IdxTuple : NotExecVectorIdxs)
|
||||
NewNotExec.push_back(std::move(NotExecVectors[IdxTuple.Ord]));
|
||||
NotExecVectors = std::move(NewNotExec);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -554,12 +567,13 @@ public:
|
||||
Folded[true][I] = B->Count.isZero();
|
||||
}
|
||||
|
||||
// Using Profile Bitmap from runtime, mark the executed test vectors.
|
||||
findExecutedTestVectors();
|
||||
// Using Profile Bitmap from runtime, mark the test vectors.
|
||||
findTestVectors();
|
||||
|
||||
// Record Test vectors, executed vectors, and independence pairs.
|
||||
return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded),
|
||||
std::move(PosToID), std::move(CondLoc));
|
||||
// Record executed vectors, not-executed vectors, and independence pairs.
|
||||
return MCDCRecord(Region, std::move(ExecVectors), std::move(NotExecVectors),
|
||||
std::move(Folded), std::move(PosToID),
|
||||
std::move(CondLoc));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -19,7 +19,9 @@
|
||||
// CHECKGENERALCASE-NEXT: | Condition C4 --> (12:25)
|
||||
// CHECKGENERALCASE-NEXT: | Condition C5 --> (12:31)
|
||||
// CHECKGENERALCASE-NEXT: |
|
||||
// CHECKGENERALCASE-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECKGENERALCASE-NEXT: | MC/DC Test Vectors:
|
||||
// CHECKGENERALCASE-NEXT: |
|
||||
// CHECKGENERALCASE-NEXT: | Executed:
|
||||
// CHECKGENERALCASE-NEXT: |
|
||||
// CHECKGENERALCASE-NEXT: | C1, C2, C3, C4, C5 Result
|
||||
// CHECKGENERALCASE-NEXT: | 1 { F, C, C, -, C = F }
|
||||
@ -36,7 +38,6 @@
|
||||
|
||||
// RUN: llvm-profdata merge %S/Inputs/mcdc-const-folding.proftext -o %t.profdata
|
||||
// RUN: llvm-cov show --show-mcdc %S/Inputs/mcdc-const-folding.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=CHECKFULLCASE
|
||||
// RUN: llvm-cov report --show-mcdc-summary %S/Inputs/mcdc-const-folding.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-const-folding.cpp | FileCheck %s -check-prefix=REPORT
|
||||
|
||||
// CHECKFULLCASE: | 1 { C, - = F }
|
||||
// CHECKFULLCASE: | C1-Pair: constant folded
|
||||
@ -176,6 +177,148 @@
|
||||
// CHECKFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
|
||||
// RUN: llvm-cov show --show-mcdc --show-mcdc-non-executed-vectors %S/Inputs/mcdc-const-folding.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=ALLFULLCASE
|
||||
|
||||
// ALLFULLCASE: | 1 { C, - = F }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { F, C = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C = F }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { C, F = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: covered: (1,2)
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { F, C = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: covered: (1,2)
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { C, - = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, C = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { C, F = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: covered: (1,2)
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { F, C = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: covered: (1,2)
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { C, -, - = F }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { F, C, - = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C, - = F }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { C, F, - = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { C, T, F = F }
|
||||
// ALLFULLCASE-NEXT: | 3 { C, T, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: covered: (1,3)
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: covered: (2,3)
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { F, C, - = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C, F = F }
|
||||
// ALLFULLCASE-NEXT: | 3 { T, C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: covered: (1,3)
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: covered: (2,3)
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { C, -, - = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, C, - = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, C, - = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { C, T, - = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { C, F, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, C, - = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { F, -, C = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, F, C = F }
|
||||
// ALLFULLCASE-NEXT: | 3 { T, T, C = F }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { F, C, - = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C, - = F }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { F, -, C = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, F, C = F }
|
||||
// ALLFULLCASE-NEXT: | 3 { T, T, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: covered: (1,3)
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: covered: (2,3)
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { F, C, - = F }
|
||||
// ALLFULLCASE-NEXT: | 2 { T, C, F = F }
|
||||
// ALLFULLCASE-NEXT: | 3 { T, C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: covered: (1,3)
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: covered: (2,3)
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALLFULLCASE: | 1 { T, -, C = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, T, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, C, - = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, C, - = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, -, C = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, T, C = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: constant folded
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALLFULLCASE: | 1 { T, C, - = T }
|
||||
// ALLFULLCASE-NEXT: | 2 { F, C, T = T }
|
||||
// ALLFULLCASE: | C1-Pair: not covered
|
||||
// ALLFULLCASE-NEXT: | C2-Pair: constant folded
|
||||
// ALLFULLCASE-NEXT: | C3-Pair: not covered
|
||||
// ALLFULLCASE: | MC/DC Coverage for Decision: 0.00%
|
||||
|
||||
// RUN: llvm-cov report --show-mcdc-summary %S/Inputs/mcdc-const-folding.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-const-folding.cpp | FileCheck %s -check-prefix=REPORT
|
||||
|
||||
// REPORT: _Z5case0b {{.*}} 1 1 0.00%
|
||||
// REPORT-NEXT: _Z5case1b {{.*}} 1 1 0.00%
|
||||
// REPORT-NEXT: _Z5case2b {{.*}} 1 0 100.00%
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
// RUN: llvm-profdata merge %S/Inputs/mcdc-general.proftext -o %t.profdata
|
||||
// RUN: llvm-cov export --format=text %S/Inputs/mcdc-general.o -instr-profile %t.profdata | FileCheck %s
|
||||
// RUN: llvm-cov export --format=text %S/Inputs/mcdc-general.o -instr-profile %t.profdata | FileCheck %s --check-prefix=DEFAULT
|
||||
|
||||
// CHECK: 12,7,12,27,2,4,0,0,5,[true,true,true,true],[{"conditions":[false,null,false,null],"executed":true,"result":false},{"conditions":[true,false,false,null],"executed":true,"result":false},{"conditions":[false,null,true,false],"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}]
|
||||
// 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}]
|
||||
// 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}]
|
||||
// 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}]
|
||||
// CHECK: "mcdc":{"count":12,"covered":10,"notcovered":2,"percent":83.333333333333343}
|
||||
// DEFAULT: 12,7,12,27,2,4,0,0,5,[true,true,true,true],[{"conditions":[false,null,false,null],"executed":true,"result":false},{"conditions":[true,false,false,null],"executed":true,"result":false},{"conditions":[false,null,true,false],"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}]
|
||||
// DEFAULT: 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}]
|
||||
// DEFAULT: 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}]
|
||||
// DEFAULT: 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}]
|
||||
// DEFAULT: "mcdc":{"count":12,"covered":10,"notcovered":2,"percent":83.333333333333343}
|
||||
|
||||
// RUN: llvm-cov export --format=text --show-mcdc-non-executed-vectors %S/Inputs/mcdc-general.o -instr-profile %t.profdata | FileCheck %s --check-prefix=ALL
|
||||
|
||||
// ALL: 12,7,12,27,2,4,0,0,5,[true,true,true,true],[{"conditions":[false,null,false,null],"executed":true,"result":false},{"conditions":[true,false,false,null],"executed":true,"result":false},{"conditions":[false,null,true,false],"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},{"conditions":[false,null,true,true],"executed":false,"result":true}]
|
||||
// ALL: 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}]
|
||||
// ALL: 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},{"conditions":[true,false],"executed":false,"result":false}]
|
||||
// ALL: 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},{"conditions":[true,true,false,null],"executed":false,"result":false}]
|
||||
// ALL: "mcdc":{"count":12,"covered":10,"notcovered":2,"percent":83.333333333333343}
|
||||
|
||||
Instructions for regenerating the test:
|
||||
|
||||
@ -13,6 +21,6 @@ Instructions for regenerating the test:
|
||||
cp mcdc-general.cpp /tmp
|
||||
|
||||
clang -fcoverage-mcdc -fprofile-instr-generate -fcoverage-compilation-dir=. \
|
||||
-fcoverage-mapping /tmp/mcdc-general.cpp -o /tmp/mcdc-const.o
|
||||
-fcoverage-mapping /tmp/mcdc-general.cpp -o /tmp/mcdc-general.o
|
||||
|
||||
mv /tmp/mcdc-general.o %S/Inputs
|
||||
|
||||
@ -15,9 +15,11 @@
|
||||
// CHECK-NEXT: | Condition C3 --> (12:20)
|
||||
// CHECK-NEXT: | Condition C4 --> (12:25)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | None.
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | None.
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1-Pair: not covered
|
||||
// CHECK-NEXT: | C2-Pair: not covered
|
||||
@ -27,6 +29,124 @@
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: ------------------
|
||||
|
||||
// RUN: llvm-cov show --show-mcdc --show-mcdc-non-executed-vectors %S/Inputs/mcdc-general.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=ALL
|
||||
|
||||
// ALL: test(bool
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (12:7) to (12:27)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 4
|
||||
// ALL-NEXT: | Condition C1 --> (12:8)
|
||||
// ALL-NEXT: | Condition C2 --> (12:13)
|
||||
// ALL-NEXT: | Condition C3 --> (12:20)
|
||||
// ALL-NEXT: | Condition C4 --> (12:25)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | None.
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 1 { F, -, F, - = F }
|
||||
// ALL-NEXT: | 2 { T, F, F, - = F }
|
||||
// ALL-NEXT: | 3 { F, -, T, F = F }
|
||||
// ALL-NEXT: | 4 { T, F, T, F = F }
|
||||
// ALL-NEXT: | 5 { F, -, T, T = T }
|
||||
// ALL-NEXT: | 6 { T, F, T, T = T }
|
||||
// ALL-NEXT: | 7 { T, T, -, - = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | C3-Pair: not covered
|
||||
// ALL-NEXT: | C4-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (15:7) to (15:13)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 2
|
||||
// ALL-NEXT: | Condition C1 --> (15:7)
|
||||
// ALL-NEXT: | Condition C2 --> (15:12)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | None.
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 1 { F, - = F }
|
||||
// ALL-NEXT: | 2 { T, F = F }
|
||||
// ALL-NEXT: | 3 { T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (15:19) to (15:25)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 2
|
||||
// ALL-NEXT: | Condition C1 --> (15:19)
|
||||
// ALL-NEXT: | Condition C2 --> (15:24)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | None.
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 1 { F, - = F }
|
||||
// ALL-NEXT: | 2 { T, F = F }
|
||||
// ALL-NEXT: | 3 { T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (18:7) to (19:15)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 4
|
||||
// ALL-NEXT: | Condition C1 --> (18:8)
|
||||
// ALL-NEXT: | Condition C2 --> (18:13)
|
||||
// ALL-NEXT: | Condition C3 --> (19:8)
|
||||
// ALL-NEXT: | Condition C4 --> (19:13)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | None.
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 1 { F, -, -, - = F }
|
||||
// ALL-NEXT: | 2 { T, F, -, - = F }
|
||||
// ALL-NEXT: | 3 { T, T, F, - = F }
|
||||
// ALL-NEXT: | 4 { T, T, T, F = F }
|
||||
// ALL-NEXT: | 5 { T, T, T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | C3-Pair: not covered
|
||||
// ALL-NEXT: | C4-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// Turn off MC/DC visualization.
|
||||
// RUN: llvm-cov show %S/Inputs/mcdc-general.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=NOMCDC
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
// RUN: llvm-profdata merge %S/Inputs/mcdc-general.proftext -o %t.profdata
|
||||
// RUN: llvm-cov show --show-mcdc %S/Inputs/mcdc-general.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s
|
||||
// RUN: llvm-cov show --show-mcdc --show-mcdc-non-executed-vectors %S/Inputs/mcdc-general.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=ALL
|
||||
// RUN: llvm-cov report --show-mcdc-summary %S/Inputs/mcdc-general.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-general.cpp | FileCheck %s -check-prefix=REPORT
|
||||
|
||||
// CHECK: test(bool
|
||||
@ -15,7 +16,9 @@
|
||||
// CHECK-NEXT: | Condition C3 --> (12:20)
|
||||
// CHECK-NEXT: | Condition C4 --> (12:25)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2, C3, C4 Result
|
||||
// CHECK-NEXT: | 1 { F, -, F, - = F }
|
||||
@ -40,7 +43,9 @@
|
||||
// CHECK-NEXT: | Condition C1 --> (15:7)
|
||||
// CHECK-NEXT: | Condition C2 --> (15:12)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2 Result
|
||||
// CHECK-NEXT: | 1 { F, - = F }
|
||||
@ -57,7 +62,9 @@
|
||||
// CHECK-NEXT: | Condition C1 --> (15:19)
|
||||
// CHECK-NEXT: | Condition C2 --> (15:24)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2 Result
|
||||
// CHECK-NEXT: | 1 { F, - = F }
|
||||
@ -78,7 +85,9 @@
|
||||
// CHECK-NEXT: | Condition C3 --> (19:8)
|
||||
// CHECK-NEXT: | Condition C4 --> (19:13)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2, C3, C4 Result
|
||||
// CHECK-NEXT: | 1 { F, -, -, - = F }
|
||||
@ -94,6 +103,125 @@
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: ------------------
|
||||
|
||||
// Same as CHECK above, but with --show-mcdc-non-executed-vectors (Not executed section after each decision).
|
||||
|
||||
// ALL: test(bool
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (12:7) to (12:27)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 4
|
||||
// ALL-NEXT: | Condition C1 --> (12:8)
|
||||
// ALL-NEXT: | Condition C2 --> (12:13)
|
||||
// ALL-NEXT: | Condition C3 --> (12:20)
|
||||
// ALL-NEXT: | Condition C4 --> (12:25)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 1 { F, -, F, - = F }
|
||||
// ALL-NEXT: | 2 { T, F, F, - = F }
|
||||
// ALL-NEXT: | 3 { F, -, T, F = F }
|
||||
// ALL-NEXT: | 4 { T, F, T, F = F }
|
||||
// ALL-NEXT: | 5 { T, F, T, T = T }
|
||||
// ALL-NEXT: | 6 { T, T, -, - = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 7 { F, -, T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: covered: (1,6)
|
||||
// ALL-NEXT: | C2-Pair: covered: (2,6)
|
||||
// ALL-NEXT: | C3-Pair: covered: (2,5)
|
||||
// ALL-NEXT: | C4-Pair: covered: (4,5)
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (15:7) to (15:13)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 2
|
||||
// ALL-NEXT: | Condition C1 --> (15:7)
|
||||
// ALL-NEXT: | Condition C2 --> (15:12)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 1 { F, - = F }
|
||||
// ALL-NEXT: | 2 { T, F = F }
|
||||
// ALL-NEXT: | 3 { T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | None.
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: covered: (1,3)
|
||||
// ALL-NEXT: | C2-Pair: covered: (2,3)
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 100.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (15:19) to (15:25)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 2
|
||||
// ALL-NEXT: | Condition C1 --> (15:19)
|
||||
// ALL-NEXT: | Condition C2 --> (15:24)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 1 { F, - = F }
|
||||
// ALL-NEXT: | 2 { T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 3 { T, F = F }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: covered: (1,2)
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 50.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (18:7) to (19:15)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 4
|
||||
// ALL-NEXT: | Condition C1 --> (18:8)
|
||||
// ALL-NEXT: | Condition C2 --> (18:13)
|
||||
// ALL-NEXT: | Condition C3 --> (19:8)
|
||||
// ALL-NEXT: | Condition C4 --> (19:13)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 1 { F, -, -, - = F }
|
||||
// ALL-NEXT: | 2 { T, F, -, - = F }
|
||||
// ALL-NEXT: | 3 { T, T, T, F = F }
|
||||
// ALL-NEXT: | 4 { T, T, T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4 Result
|
||||
// ALL-NEXT: | 5 { T, T, F, - = F }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: covered: (1,4)
|
||||
// ALL-NEXT: | C2-Pair: covered: (2,4)
|
||||
// ALL-NEXT: | C3-Pair: not covered
|
||||
// ALL-NEXT: | C4-Pair: covered: (3,4)
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 75.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// Turn off MC/DC visualization.
|
||||
// RUN: llvm-cov show %S/Inputs/mcdc-general.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=NOMCDC
|
||||
// NOMCDC-NOT: MC/DC Decision Region
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
// RUN: llvm-profdata merge %S/Inputs/mcdc-macro.proftext -o %t.profdata
|
||||
// RUN: llvm-cov show --show-expansions --show-branches=count --show-mcdc %S/Inputs/mcdc-macro.o -instr-profile %t.profdata --compilation-dir=%S/Inputs | FileCheck %s
|
||||
// RUN: llvm-cov show --show-expansions --show-branches=count --show-mcdc --show-mcdc-non-executed-vectors %S/Inputs/mcdc-macro.o -instr-profile %t.profdata --compilation-dir=%S/Inputs | FileCheck %s -check-prefix=ALL
|
||||
|
||||
// CHECK: | | | Branch (2:11): [Folded - Ignored]
|
||||
// CHECK: | | | Branch (3:11): [True: 1, False: 0]
|
||||
@ -18,7 +19,9 @@
|
||||
// CHECK-NEXT: | Condition C4 --> (3:23)
|
||||
// CHECK-NEXT: | Condition C5 --> (9:22)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2, C3, C4, C5 Result
|
||||
// CHECK-NEXT: | 1 { T, C, T, T, - = T }
|
||||
@ -41,7 +44,9 @@
|
||||
// CHECK-NEXT: | Condition C1 --> (11:7)
|
||||
// CHECK-NEXT: | Condition C2 --> (2:11)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2 Result
|
||||
// CHECK-NEXT: | 1 { T, C = T }
|
||||
@ -69,7 +74,9 @@
|
||||
// CHECK-NEXT: | Condition C5 --> (3:11)
|
||||
// CHECK-NEXT: | Condition C6 --> (3:23)
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed MC/DC Test Vectors:
|
||||
// CHECK-NEXT: | MC/DC Test Vectors:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | Executed:
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: | C1, C2, C3, C4, C5, C6 Result
|
||||
// CHECK-NEXT: | 1 { T, T, T, C, -, - = T }
|
||||
@ -84,6 +91,129 @@
|
||||
// CHECK-NEXT: |
|
||||
// CHECK-NEXT: ------------------
|
||||
|
||||
// Same as CHECK above, but with --show-mcdc-non-executed-vectors (Not executed section after each decision).
|
||||
|
||||
// ALL: | | | Branch (2:11): [Folded - Ignored]
|
||||
// ALL: | | | Branch (3:11): [True: 1, False: 0]
|
||||
// ALL: | | | Branch (3:23): [True: 1, False: 0]
|
||||
// ALL: | Branch (9:7): [True: 1, False: 0]
|
||||
// ALL-NEXT: | Branch (9:22): [True: 0, False: 0]
|
||||
// ALL-NEXT: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (9:7) to (9:23)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 5
|
||||
// ALL-NEXT: | Condition C1 --> (9:7)
|
||||
// ALL-NEXT: | Condition C2 --> (2:11)
|
||||
// ALL-NEXT: | Condition C3 --> (3:11)
|
||||
// ALL-NEXT: | Condition C4 --> (3:23)
|
||||
// ALL-NEXT: | Condition C5 --> (9:22)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4, C5 Result
|
||||
// ALL-NEXT: | 1 { T, C, T, T, - = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4, C5 Result
|
||||
// ALL-NEXT: | 2 { F, C, -, -, F = F }
|
||||
// ALL-NEXT: | 3 { T, C, -, -, F = F }
|
||||
// ALL-NEXT: | 4 { T, C, F, -, F = F }
|
||||
// ALL-NEXT: | 5 { T, C, T, F, F = F }
|
||||
// ALL-NEXT: | 6 { F, C, -, -, T = T }
|
||||
// ALL-NEXT: | 7 { T, C, -, -, T = T }
|
||||
// ALL-NEXT: | 8 { T, C, F, -, T = T }
|
||||
// ALL-NEXT: | 9 { T, C, T, F, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: constant folded
|
||||
// ALL-NEXT: | C3-Pair: not covered
|
||||
// ALL-NEXT: | C4-Pair: not covered
|
||||
// ALL-NEXT: | C5-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: | | | Branch (2:11): [Folded - Ignored]
|
||||
// ALL: | Branch (11:7): [True: 1, False: 0]
|
||||
// ALL-NEXT: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (11:7) to (11:13)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 2
|
||||
// ALL-NEXT: | Condition C1 --> (11:7)
|
||||
// ALL-NEXT: | Condition C2 --> (2:11)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 1 { T, C = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2 Result
|
||||
// ALL-NEXT: | 2 { F, C = F }
|
||||
// ALL-NEXT: | 3 { T, C = F }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: constant folded
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
// ALL: | | | Branch (1:11): [True: 1, False: 0]
|
||||
// ALL: | | | Branch (2:11): [Folded - Ignored]
|
||||
// ALL: | | | | | Branch (3:11): [True: 0, False: 0]
|
||||
// ALL: | | | | | Branch (3:23): [True: 0, False: 0]
|
||||
// ALL: | Branch (13:7): [True: 1, False: 0]
|
||||
// ALL-NEXT: | Branch (13:13): [True: 1, False: 0]
|
||||
// ALL-NEXT: ------------------
|
||||
// ALL-NEXT: |---> MC/DC Decision Region (13:7) to (13:32)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Number of Conditions: 6
|
||||
// ALL-NEXT: | Condition C1 --> (13:7)
|
||||
// ALL-NEXT: | Condition C2 --> (13:13)
|
||||
// ALL-NEXT: | Condition C3 --> (1:11)
|
||||
// ALL-NEXT: | Condition C4 --> (2:11)
|
||||
// ALL-NEXT: | Condition C5 --> (3:11)
|
||||
// ALL-NEXT: | Condition C6 --> (3:23)
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | MC/DC Test Vectors:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4, C5, C6 Result
|
||||
// ALL-NEXT: | 1 { T, T, T, C, -, - = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | Not executed:
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1, C2, C3, C4, C5, C6 Result
|
||||
// ALL-NEXT: | 2 { F, -, -, C, -, - = F }
|
||||
// ALL-NEXT: | 3 { T, F, -, C, -, - = F }
|
||||
// ALL-NEXT: | 4 { T, T, F, C, -, - = F }
|
||||
// ALL-NEXT: | 5 { F, -, -, C, F, - = F }
|
||||
// ALL-NEXT: | 6 { T, F, -, C, F, - = F }
|
||||
// ALL-NEXT: | 7 { T, T, F, C, F, - = F }
|
||||
// ALL-NEXT: | 8 { F, -, -, C, T, F = F }
|
||||
// ALL-NEXT: | 9 { T, F, -, C, T, F = F }
|
||||
// ALL-NEXT: | 10 { T, T, F, C, T, F = F }
|
||||
// ALL-NEXT: | 11 { F, -, -, C, T, T = T }
|
||||
// ALL-NEXT: | 12 { T, F, -, C, T, T = T }
|
||||
// ALL-NEXT: | 13 { T, T, F, C, T, T = T }
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: | C1-Pair: not covered
|
||||
// ALL-NEXT: | C2-Pair: not covered
|
||||
// ALL-NEXT: | C3-Pair: not covered
|
||||
// ALL-NEXT: | C4-Pair: constant folded
|
||||
// ALL-NEXT: | C5-Pair: not covered
|
||||
// ALL-NEXT: | C6-Pair: not covered
|
||||
// ALL-NEXT: | MC/DC Coverage for Decision: 0.00%
|
||||
// ALL-NEXT: |
|
||||
// ALL-NEXT: ------------------
|
||||
|
||||
Instructions for regenerating the test:
|
||||
|
||||
cd %S/Inputs # Or copy mcdc-macro.c into the working directory
|
||||
|
||||
@ -1024,6 +1024,11 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
|
||||
cl::desc("Show the MCDC Coverage for each applicable boolean expression"),
|
||||
cl::cat(ViewCategory));
|
||||
|
||||
cl::opt<bool> ShowMCDCNonExecutedVectors(
|
||||
"show-mcdc-non-executed-vectors", cl::Optional,
|
||||
cl::desc("Show MC/DC test vectors that were not executed"),
|
||||
cl::cat(ViewCategory));
|
||||
|
||||
cl::opt<bool> ShowBestLineRegionsCounts(
|
||||
"show-line-counts-or-regions", cl::Optional,
|
||||
cl::desc("Show the execution counts for each line, or the execution "
|
||||
@ -1130,6 +1135,7 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
|
||||
ViewOpts.ShowBranchCounts =
|
||||
ShowBranches == CoverageViewOptions::BranchOutputType::Count;
|
||||
ViewOpts.ShowMCDC = ShowMCDC;
|
||||
ViewOpts.ShowMCDCNonExecutedVectors = ShowMCDCNonExecutedVectors;
|
||||
ViewOpts.ShowBranchPercents =
|
||||
ShowBranches == CoverageViewOptions::BranchOutputType::Percent;
|
||||
ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
|
||||
@ -1321,6 +1327,12 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
|
||||
cl::desc("Unify function instantiations"),
|
||||
cl::init(true), cl::cat(ExportCategory));
|
||||
|
||||
cl::opt<bool> ShowMCDCNonExecutedVectors(
|
||||
"show-mcdc-non-executed-vectors", cl::Optional,
|
||||
cl::desc("Include MC/DC test vectors that were not executed in the "
|
||||
"export"),
|
||||
cl::cat(ExportCategory));
|
||||
|
||||
auto Err = commandLineParser(argc, argv);
|
||||
if (Err)
|
||||
return Err;
|
||||
@ -1329,6 +1341,7 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
|
||||
ViewOpts.SkipFunctions = SkipFunctions;
|
||||
ViewOpts.SkipBranches = SkipBranches;
|
||||
ViewOpts.UnifyFunctionInstantiations = UnifyInstantiations;
|
||||
ViewOpts.ShowMCDCNonExecutedVectors = ShowMCDCNonExecutedVectors;
|
||||
|
||||
if (ViewOpts.Format != CoverageViewOptions::OutputFormat::Text &&
|
||||
ViewOpts.Format != CoverageViewOptions::OutputFormat::Lcov) {
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
// -- Branch: dict => Describes a branch of the file with counters
|
||||
// -- MCDC Records: array => List of MCDC records in the file
|
||||
// -- MCDC Values: array => List of T/F covered condition values and
|
||||
// list of executed test vectors
|
||||
// list of test vectors with execution status
|
||||
// -- Segments: array => List of Segments contained in the file
|
||||
// -- Segment: dict => Describes a segment of the file with a counter
|
||||
// -- Expansions: array => List of expansion records
|
||||
@ -121,11 +121,13 @@ json::Value renderCondState(const coverage::MCDCRecord::CondState CondState) {
|
||||
llvm_unreachable("Unknown llvm::coverage::MCDCRecord::CondState enum");
|
||||
}
|
||||
|
||||
json::Array gatherTestVectors(coverage::MCDCRecord &Record) {
|
||||
json::Array gatherTestVectors(coverage::MCDCRecord &Record,
|
||||
const CoverageViewOptions &Options) {
|
||||
json::Array TestVectors;
|
||||
unsigned NumConditions = Record.getNumConditions();
|
||||
for (unsigned tv = 0; tv < Record.getNumTestVectors(); tv++) {
|
||||
const bool ShowNonExecutedVectors = Options.ShowMCDCNonExecutedVectors;
|
||||
|
||||
for (unsigned tv = 0; tv < Record.getNumTestVectors(); tv++) {
|
||||
json::Array TVConditions;
|
||||
for (unsigned c = 0; c < NumConditions; c++)
|
||||
TVConditions.push_back(renderCondState(Record.getTVCondition(tv, c)));
|
||||
@ -135,17 +137,31 @@ json::Array gatherTestVectors(coverage::MCDCRecord &Record) {
|
||||
{"result", renderCondState(Record.getTVResult(tv))},
|
||||
{"conditions", std::move(TVConditions)}}));
|
||||
}
|
||||
if (ShowNonExecutedVectors) {
|
||||
for (unsigned tv = 0; tv < Record.getNumNotExecutedTestVectors(); tv++) {
|
||||
json::Array TVConditions;
|
||||
for (unsigned c = 0; c < NumConditions; c++)
|
||||
TVConditions.push_back(
|
||||
renderCondState(Record.getNotExecutedTVCondition(tv, c)));
|
||||
|
||||
TestVectors.push_back(json::Object(
|
||||
{{"executed", json::Value(false)},
|
||||
{"result", renderCondState(Record.getNotExecutedTVResult(tv))},
|
||||
{"conditions", std::move(TVConditions)}}));
|
||||
}
|
||||
}
|
||||
return TestVectors;
|
||||
}
|
||||
|
||||
json::Array renderMCDCRecord(const coverage::MCDCRecord &Record) {
|
||||
json::Array renderMCDCRecord(const coverage::MCDCRecord &Record,
|
||||
const CoverageViewOptions &Options) {
|
||||
const llvm::coverage::CounterMappingRegion &CMR = Record.getDecisionRegion();
|
||||
const auto [TrueDecisions, FalseDecisions] = Record.getDecisions();
|
||||
return json::Array(
|
||||
{CMR.LineStart, CMR.ColumnStart, CMR.LineEnd, CMR.ColumnEnd,
|
||||
TrueDecisions, FalseDecisions, CMR.FileID, CMR.ExpandedFileID,
|
||||
int64_t(CMR.Kind), gatherConditions(Record),
|
||||
gatherTestVectors(const_cast<coverage::MCDCRecord &>(Record))});
|
||||
gatherTestVectors(const_cast<coverage::MCDCRecord &>(Record), Options)});
|
||||
}
|
||||
|
||||
json::Array renderRegions(ArrayRef<coverage::CountedRegion> Regions) {
|
||||
@ -163,10 +179,11 @@ json::Array renderBranchRegions(ArrayRef<coverage::CountedRegion> Regions) {
|
||||
return RegionArray;
|
||||
}
|
||||
|
||||
json::Array renderMCDCRecords(ArrayRef<coverage::MCDCRecord> Records) {
|
||||
json::Array renderMCDCRecords(ArrayRef<coverage::MCDCRecord> Records,
|
||||
const CoverageViewOptions &Options) {
|
||||
json::Array RecordArray;
|
||||
for (auto &Record : Records)
|
||||
RecordArray.push_back(renderMCDCRecord(Record));
|
||||
RecordArray.push_back(renderMCDCRecord(Record, Options));
|
||||
return RecordArray;
|
||||
}
|
||||
|
||||
@ -268,10 +285,11 @@ json::Array renderFileBranches(const coverage::CoverageData &FileCoverage) {
|
||||
return BranchArray;
|
||||
}
|
||||
|
||||
json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage) {
|
||||
json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage,
|
||||
const CoverageViewOptions &Options) {
|
||||
json::Array MCDCRecordArray;
|
||||
for (const auto &Record : FileCoverage.getMCDCRecords())
|
||||
MCDCRecordArray.push_back(renderMCDCRecord(Record));
|
||||
MCDCRecordArray.push_back(renderMCDCRecord(Record, Options));
|
||||
return MCDCRecordArray;
|
||||
}
|
||||
|
||||
@ -285,7 +303,7 @@ json::Object renderFile(const coverage::CoverageMapping &Coverage,
|
||||
auto FileCoverage = Coverage.getCoverageForFile(Filename);
|
||||
File["segments"] = renderFileSegments(FileCoverage);
|
||||
File["branches"] = renderFileBranches(FileCoverage);
|
||||
File["mcdc_records"] = renderFileMCDC(FileCoverage);
|
||||
File["mcdc_records"] = renderFileMCDC(FileCoverage, Options);
|
||||
if (!Options.SkipExpansions) {
|
||||
File["expansions"] = renderFileExpansions(Coverage, FileCoverage);
|
||||
}
|
||||
@ -325,16 +343,17 @@ json::Array renderFiles(const coverage::CoverageMapping &Coverage,
|
||||
}
|
||||
|
||||
json::Array renderFunctions(
|
||||
const iterator_range<coverage::FunctionRecordIterator> &Functions) {
|
||||
const iterator_range<coverage::FunctionRecordIterator> &Functions,
|
||||
const CoverageViewOptions &Options) {
|
||||
json::Array FunctionArray;
|
||||
for (const auto &F : Functions)
|
||||
FunctionArray.push_back(
|
||||
json::Object({{"name", F.Name},
|
||||
{"count", clamp_uint64_to_int64(F.ExecutionCount)},
|
||||
{"regions", renderRegions(F.CountedRegions)},
|
||||
{"branches", renderBranchRegions(F.CountedBranchRegions)},
|
||||
{"mcdc_records", renderMCDCRecords(F.MCDCRecords)},
|
||||
{"filenames", json::Array(F.Filenames)}}));
|
||||
FunctionArray.push_back(json::Object(
|
||||
{{"name", F.Name},
|
||||
{"count", clamp_uint64_to_int64(F.ExecutionCount)},
|
||||
{"regions", renderRegions(F.CountedRegions)},
|
||||
{"branches", renderBranchRegions(F.CountedBranchRegions)},
|
||||
{"mcdc_records", renderMCDCRecords(F.MCDCRecords, Options)},
|
||||
{"filenames", json::Array(F.Filenames)}}));
|
||||
return FunctionArray;
|
||||
}
|
||||
|
||||
@ -368,7 +387,8 @@ void CoverageExporterJson::renderRoot(ArrayRef<std::string> SourceFiles) {
|
||||
{{"files", std::move(Files)}, {"totals", renderSummary(Totals)}});
|
||||
// Skip functions-level information if necessary.
|
||||
if (!Options.ExportSummaryOnly && !Options.SkipFunctions)
|
||||
Export["functions"] = renderFunctions(Coverage.getCoveredFunctions());
|
||||
Export["functions"] =
|
||||
renderFunctions(Coverage.getCoveredFunctions(), Options);
|
||||
|
||||
auto ExportArray = json::Array({std::move(Export)});
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ struct CoverageViewOptions {
|
||||
bool ShowLineStats;
|
||||
bool ShowRegionMarkers;
|
||||
bool ShowMCDC;
|
||||
bool ShowMCDCNonExecutedVectors = false;
|
||||
bool ShowBranchCounts;
|
||||
bool ShowBranchPercents;
|
||||
bool ShowExpandedRegions;
|
||||
|
||||
@ -1152,6 +1152,8 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
|
||||
|
||||
void SourceCoverageViewHTML::renderMCDCView(raw_ostream &OS, MCDCView &MRV,
|
||||
unsigned ViewDepth) {
|
||||
const bool ShowNonExecutedVectors = getOptions().ShowMCDCNonExecutedVectors;
|
||||
|
||||
for (auto &Record : MRV.Records) {
|
||||
OS << BeginExpansionDiv;
|
||||
OS << BeginPre;
|
||||
@ -1179,10 +1181,33 @@ void SourceCoverageViewHTML::renderMCDCView(raw_ostream &OS, MCDCView &MRV,
|
||||
OS << " " << Record.getConditionHeaderString(i);
|
||||
}
|
||||
OS << "\n";
|
||||
OS << " Executed MC/DC Test Vectors:\n\n ";
|
||||
OS << Record.getTestVectorHeaderString();
|
||||
for (unsigned i = 0; i < Record.getNumTestVectors(); i++)
|
||||
OS << Record.getTestVectorString(i);
|
||||
OS << " MC/DC Test Vectors\n\n";
|
||||
|
||||
const unsigned NumExecuted = Record.getNumTestVectors();
|
||||
const unsigned NumNotExecuted = Record.getNumNotExecutedTestVectors();
|
||||
|
||||
const std::string HeaderStr = Record.getTestVectorHeaderString();
|
||||
|
||||
OS << " Executed:\n\n ";
|
||||
if (NumExecuted == 0) {
|
||||
OS << "None.\n";
|
||||
} else {
|
||||
OS << HeaderStr;
|
||||
for (unsigned k = 0; k < NumExecuted; k++)
|
||||
OS << Record.getTestVectorString(k);
|
||||
}
|
||||
|
||||
if (ShowNonExecutedVectors) {
|
||||
OS << "\n Not executed:\n\n ";
|
||||
if (NumNotExecuted == 0) {
|
||||
OS << "None.\n";
|
||||
} else {
|
||||
OS << HeaderStr;
|
||||
for (unsigned k = 0; k < NumNotExecuted; k++)
|
||||
OS << Record.getNotExecutedTestVectorString(k);
|
||||
}
|
||||
}
|
||||
|
||||
OS << "\n";
|
||||
for (unsigned i = 0; i < Record.getNumConditions(); i++)
|
||||
OS << Record.getConditionCoverageString(i);
|
||||
|
||||
@ -337,6 +337,8 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
|
||||
|
||||
void SourceCoverageViewText::renderMCDCView(raw_ostream &OS, MCDCView &MRV,
|
||||
unsigned ViewDepth) {
|
||||
const bool ShowNonExecutedVectors = getOptions().ShowMCDCNonExecutedVectors;
|
||||
|
||||
for (auto &Record : MRV.Records) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "---> MC/DC Decision Region (";
|
||||
@ -359,16 +361,53 @@ void SourceCoverageViewText::renderMCDCView(raw_ostream &OS, MCDCView &MRV,
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " Executed MC/DC Test Vectors:\n";
|
||||
OS << " MC/DC Test Vectors:\n";
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
|
||||
const unsigned NumExecuted = Record.getNumTestVectors();
|
||||
const unsigned NumNotExecuted = Record.getNumNotExecutedTestVectors();
|
||||
|
||||
const std::string HeaderStr = Record.getTestVectorHeaderString();
|
||||
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " ";
|
||||
OS << Record.getTestVectorHeaderString();
|
||||
for (unsigned i = 0; i < Record.getNumTestVectors(); i++) {
|
||||
OS << " Executed:\n";
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
if (NumExecuted == 0) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << Record.getTestVectorString(i);
|
||||
OS << " None.\n";
|
||||
} else {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " ";
|
||||
OS << HeaderStr;
|
||||
for (unsigned k = 0; k < NumExecuted; k++) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << Record.getTestVectorString(k);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowNonExecutedVectors) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " Not executed:\n";
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
if (NumNotExecuted == 0) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " None.\n";
|
||||
} else {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " ";
|
||||
OS << HeaderStr;
|
||||
for (unsigned k = 0; k < NumNotExecuted; k++) {
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << Record.getNotExecutedTestVectorString(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << "\n";
|
||||
for (unsigned i = 0; i < Record.getNumConditions(); i++) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user