Skip to content

Commit b231a5e

Browse files
authored
Add '--filter mcdc' option - to remove MC/DC coverpoints which are (#361)
identical to the corresponding branch: reduce verbosity/noise. Signed-off-by: Henry Cox <[email protected]>
1 parent 06f907a commit b231a5e

File tree

5 files changed

+103
-14
lines changed

5 files changed

+103
-14
lines changed

lib/lcovutil.pm

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ our $FILTER_MISSING_FILE;
302302
our $FILTER_EXCEPTION_BRANCH;
303303
# remove lone branch in block - it can't be an actual conditional
304304
our $FILTER_ORPHAN_BRANCH;
305+
# MC/DC with single expression is identical to branch
306+
our $FILTER_MCDC_SINGLE;
305307
our $FILTER_OMIT_PATTERNS; # special/somewhat faked filter
306308

307309
our %COVERAGE_FILTERS = ("branch" => \$FILTER_BRANCH_NO_COND,
@@ -317,6 +319,7 @@ our %COVERAGE_FILTERS = ("branch" => \$FILTER_BRANCH_NO_COND,
317319
'branch_region' => \$FILTER_EXCLUDE_BRANCH,
318320
'exception' => \$FILTER_EXCEPTION_BRANCH,
319321
'orphan' => \$FILTER_ORPHAN_BRANCH,
322+
'mcdc' => \$FILTER_MCDC_SINGLE,
320323
"trivial" => \$FILTER_TRIVIAL_FUNCTION,);
321324
our @cov_filter; # 'undef' if filter is not enabled,
322325
# [line_count, coverpoint_count] histogram if
@@ -2439,6 +2442,10 @@ sub parse_cov_filters(@)
24392442
"branch filter enabled but neither branch or condition coverage is enabled"
24402443
);
24412444
}
2445+
lcovutil::ignorable_warning($ERROR_USAGE,
2446+
"'mcdc' filter enabled but MC/DC coverage is not enabled.")
2447+
if (defined($cov_filter[$FILTER_MCDC_SINGLE]) &&
2448+
!$mcdc_coverage);
24422449
if ($cov_filter[$FILTER_BRANCH_NO_COND]) {
24432450
# turn on exception and orphan filtering too
24442451
$cov_filter[$FILTER_EXCEPTION_BRANCH] = ['exception', 0, 0];
@@ -7432,6 +7439,8 @@ sub _filterFile
74327439
my $directive = $cov_filter[$FILTER_DIRECTIVE];
74337440
my $omit = $cov_filter[$FILTER_OMIT_PATTERNS]
74347441
if defined($FILTER_OMIT_PATTERNS);
7442+
my $mcdc_single = $cov_filter[$FILTER_MCDC_SINGLE]
7443+
if defined($FILTER_MCDC_SINGLE && $lcovutil::mcdc_coverage);
74357444

74367445
my $context = MessageContext->new("filtering $source_file");
74377446
if (lcovutil::is_filter_enabled()) {
@@ -7637,7 +7646,23 @@ sub _filterFile
76377646
}
76387647
} # foreach line
76397648
} # if branch_coverage
7640-
# Line related data
7649+
if ($mcdc_single) {
7650+
# find single-expression MC/DC's - if there is a matching branch
7651+
# expression on the same line, then remove the MC/DC
7652+
foreach my $line ($mcdc_count->keylist()) {
7653+
my $block = $mcdc_count->value($line);
7654+
my $groups = $block->groups();
7655+
if (exists($groups->{1}) &&
7656+
scalar(keys %$groups) == 1) {
7657+
my $branch = $testbrcount->value($line);
7658+
next unless $branch && ($branch->totals())[0] == 2;
7659+
$mcdc_count->remove($line);
7660+
++$mcdc_single->[-2]; # one MC/DC skipped
7661+
7662+
$mcdc->remove($line); # remove at top
7663+
}
7664+
}
7665+
}
76417666
next
76427667
unless $region ||
76437668
$range ||
@@ -7647,6 +7672,7 @@ sub _filterFile
76477672
$omit ||
76487673
$filter_initializer_list;
76497674

7675+
# Line related data
76507676
my %initializerListRange;
76517677
foreach my $line ($testcount->keylist()) {
76527678
# don't suppresss if this line has associated branch or MC/DC data

man/genhtml.1

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,13 @@ Exclude lines which appear to be part of a C++ std::initializer_list.
22362236
alias for "\-\-filter brace,blank".
22372237
.PP
22382238

2239+
.IP mcdc: 3
2240+
Remove MC/DC coverpoint which contains single expression, if 'branch' coverpoint
2241+
is present on the same line.
2242+
Singe-element MC/DC coverpoints are identical to the corresponding branch - except
2243+
in the case of compile-time expression evaluation, for example, in a template
2244+
function.
2245+
22392246
.IP orphan: 3
22402247
Remove branches which appear by themselves -
22412248
.I i.e.,

tests/lcov/mcdc/main.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ int main(int ac, char ** av)
2121
#endif
2222
return 0;
2323
}
24-

tests/lcov/mcdc/mcdc.sh

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ PARENT=`(cd .. ; pwd)`
104104

105105
LCOV_OPTS="--branch-coverage $PARALLEL $PROFILE"
106106

107-
rm -rf *.xml *.dat *.info *.jsn cover_one *_rpt *Test[123]*
107+
rm -rf *.xml *.dat *.info *.jsn cover_one *_rpt *Test[123]* *.gcno *.gcda gccTest* llvmTest*
108108

109109
if [ "x$COVER" != "x" ] && [ $LOCAL_COVERAGE == 1 ]; then
110110
cover -delete
@@ -170,21 +170,25 @@ function runClang()
170170

171171
function runGcc()
172172
{
173+
NAME=$1
174+
shift
175+
ARG=$1
176+
shift
173177
# runGcc exeName srcFile flags
174-
g++ --coverage -fcondition-coverage -o $1 main.cpp test.cpp $2
178+
eval g++ --coverage -fcondition-coverage -o $NAME main.cpp test.cpp $ARG
175179
if [ $? != 0 ] ; then
176-
echo "ERROR from g++ $1"
180+
echo "ERROR from g++ $NAME"
177181
return 1
178182
fi
179-
./$1
180-
$COVER $GENINFO_TOOL -o $1.info --mcdc --branch $1-test.gcda
183+
./$NAME
184+
$COVER $GENINFO_TOOL -o $NAME.info --mcdc --branch $NAME-test.gcda $@
181185
if [ $? != 0 ] ; then
182-
echo "ERROR from geninfo $1"
186+
echo "ERROR from geninfo $NAME"
183187
return 1
184188
fi
185-
$COVER $GENHTML_TOOL --flat --branch --mcdc -o $1_rpt $1.info
189+
$COVER $GENHTML_TOOL --flat --branch --mcdc -o ${NAME}_rpt $NAME.info
186190
if [ $? != 0 ] ; then
187-
echo "ERROR from genhtml $1"
191+
echo "ERROR from genhtml $NAME"
188192
return 1
189193
fi
190194
rm -f *.gcda *.gcno
@@ -232,6 +236,55 @@ if [ "$ENABLE_MCDC" == 1 ] ; then
232236
exit 1
233237
fi
234238
fi
239+
runGcc gccTest4 '-DSENS2 -DSIMPLE' --filter mcdc
240+
if [ $? != 0 ] ; then
241+
STATUS=1
242+
if [ $KEEP_GOING == 0 ] ; then
243+
exit 1
244+
fi
245+
fi
246+
# the MC/DC should have been filtered out - in favor of the branch
247+
COUNT=`grep -c MCDC gccTest4.info`
248+
if [ 0 != "$COUNT" ] ; then
249+
STATUS=1
250+
echo "filter error MC/DC"
251+
if [ $KEEP_GOING == 0 ] ; then
252+
exit 1
253+
fi
254+
fi
255+
runGcc gccTest4a '-DSENS2 -DSIMPLE'
256+
if [ $? != 0 ] ; then
257+
STATUS=1
258+
if [ $KEEP_GOING == 0 ] ; then
259+
exit 1
260+
fi
261+
fi
262+
# the MC/DC shouldn't be filtered
263+
COUNT=`grep -c MCDC gccTest4a.info`
264+
if [ 0 == "$COUNT" ] ; then
265+
STATUS=1
266+
echo "filter error2 MC/DC"
267+
if [ $KEEP_GOING == 0 ] ; then
268+
exit 1
269+
fi
270+
fi
271+
272+
runGcc gccTest5 -DSENS2 --filter mcdc
273+
if [ $? != 0 ] ; then
274+
STATUS=1
275+
if [ $KEEP_GOING == 0 ] ; then
276+
exit 1
277+
fi
278+
fi
279+
# the MC/DC shouldn't have been filtered out
280+
COUNT=`grep -c MCDC gccTest5.info`
281+
if [ 0 == "$COUNT" ] ; then
282+
STATUS=1
283+
echo "MC/DC filter error"
284+
if [ $KEEP_GOING == 0 ] ; then
285+
exit 1
286+
fi
287+
fi
235288
else
236289
echo "SKIPPING MC/DC tests: ancient compiler"
237290
fi
@@ -258,7 +311,7 @@ if [ "$ENABLE_LLVM" == 1 ] ; then
258311
exit 1
259312
fi
260313
fi
261-
else
314+
else
262315
echo "SKIPPING LLVM tests"
263316
fi
264317

tests/lcov/mcdc/test.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88

99
void test(int a, int b, int c)
1010
{
11-
if (a && (b || c)) {
11+
if
12+
#ifdef SIMPLE
13+
(a)
14+
#else
15+
(a && (b || c))
16+
#endif
1217
printf("%d && (%d || %d)\n", a, b, c);
13-
} else {
18+
else
1419
printf("not..\n");
15-
}
1620
}

0 commit comments

Comments
 (0)