Skip to content

Commit ef3eb4f

Browse files
Merge pull request #2567 from peterschrammel/fix-mcdc
Fix MCDC coverage instrumentation
2 parents 53baae6 + 370d4c6 commit ef3eb4f

File tree

16 files changed

+58
-122
lines changed

16 files changed

+58
-122
lines changed
+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc --unwind 5
44
^EXIT=0$
@@ -7,6 +7,3 @@ main.c
77
--
88
^warning: ignoring
99
^\[.*<builtin-library-
10-
--
11-
Knownbug added because this test triggers an invariant in cover.cpp
12-
See #1622 for details

regression/cbmc-cover/mcdc1/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -12,6 +12,3 @@ main.c
1212
^\*\* .* of .* covered \(100.0%\)$
1313
--
1414
^warning: ignoring
15-
--
16-
Knownbug added because this test triggers an invariant in cover.cpp
17-
See #1622 for details
+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -10,6 +10,3 @@ main.c
1010
^\*\* .* of .* covered \(100.0%\)$
1111
--
1212
^warning: ignoring
13-
--
14-
Knownbug added because this test triggers an invariant in cover.cpp
15-
See #1622 for details

regression/cbmc-cover/mcdc11/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -12,6 +12,3 @@ main.c
1212
^\*\* .* of .* covered \(100.0%\)$
1313
--
1414
^warning: ignoring
15-
--
16-
Knownbug added because this test triggers an invariant in cover.cpp
17-
See #1622 for details

regression/cbmc-cover/mcdc12/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -15,6 +15,3 @@ main.c
1515
^\*\* .* of .* covered \(100.0%\)$
1616
--
1717
^warning: ignoring
18-
--
19-
Knownbug added because this test triggers an invariant in cover.cpp
20-
See #1622 for details
+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -10,6 +10,3 @@ main.c
1010
^\*\* .* of .* covered \(100.0%\)$
1111
--
1212
^warning: ignoring
13-
--
14-
Knownbug added because this test triggers an invariant in cover.cpp
15-
See #1622 for details
+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -8,6 +8,3 @@ main.c
88
^\*\* .* of .* covered \(100.0%\)$
99
--
1010
^warning: ignoring
11-
--
12-
Knownbug added because this test triggers an invariant in cover.cpp
13-
See #1622 for details

regression/cbmc-cover/mcdc2/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -10,6 +10,3 @@ main.c
1010
^\*\* .* of .* covered \(100.0%\)$
1111
--
1212
^warning: ignoring
13-
--
14-
Knownbug added because this test triggers an invariant in cover.cpp
15-
See #1622 for details

regression/cbmc-cover/mcdc3/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -9,6 +9,3 @@ main.c
99
^\*\* .* of .* covered \(100.0%\)$
1010
--
1111
^warning: ignoring
12-
--
13-
Knownbug added because this test triggers an invariant in cover.cpp
14-
See #1622 for details

regression/cbmc-cover/mcdc4/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -11,6 +11,3 @@ main.c
1111
^\*\* .* of .* covered \(100.0%\)$
1212
--
1313
^warning: ignoring
14-
--
15-
Knownbug added because this test triggers an invariant in cover.cpp
16-
See #1622 for details

regression/cbmc-cover/mcdc5/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -11,6 +11,3 @@ main.c
1111
^\*\* .* of .* covered \(100.0%\)$
1212
--
1313
^warning: ignoring
14-
--
15-
Knownbug added because this test triggers an invariant in cover.cpp
16-
See #1622 for details

regression/cbmc-cover/mcdc6/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -8,6 +8,3 @@ main.c
88
^\*\* .* of .* covered \(100.0%\)$
99
--
1010
^warning: ignoring
11-
--
12-
Knownbug added because this test triggers an invariant in cover.cpp
13-
See #1622 for details

regression/cbmc-cover/mcdc7/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -10,6 +10,3 @@ main.c
1010
^\*\* .* of .* covered \(100.0%\)$
1111
--
1212
^warning: ignoring
13-
--
14-
Knownbug added because this test triggers an invariant in cover.cpp
15-
See #1622 for details

regression/cbmc-cover/mcdc8/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -10,6 +10,3 @@ main.c
1010
^\*\* .* of .* covered \(100.0%\)$
1111
--
1212
^warning: ignoring
13-
--
14-
Knownbug added because this test triggers an invariant in cover.cpp
15-
See #1622 for details

regression/cbmc-cover/mcdc9/test.desc

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--cover mcdc
44
^EXIT=0$
@@ -11,6 +11,3 @@ main.c
1111
^\*\* .* of .* covered \(100.0%\)$
1212
--
1313
^warning: ignoring
14-
--
15-
Knownbug added because this test triggers an invariant in cover.cpp
16-
See #1622 for details

src/goto-instrument/cover_instrument_mcdc.cpp

+43-62
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,9 @@ void collect_mcdc_controlling_rec(
120120
}
121121
else
122122
{
123-
/**
124-
* It may happen that ''is_condition(src)'' is valid,
125-
* but we ignore this case here as it can be handled
126-
* by the routine decision/condition detection.
127-
**/
123+
// It may happen that ''is_condition(src)'' is valid,
124+
// but we ignore this case here as it can be handled
125+
// by the routine decision/condition detection.
128126
}
129127
}
130128

@@ -174,11 +172,10 @@ collect_mcdc_controlling_nested(const std::set<exprt> &decisions)
174172
for(auto &src : controlling)
175173
{
176174
std::set<exprt> s1, s2;
177-
/**
178-
* The final controlling conditions resulted from ''src''
179-
* will be stored in ''s1''; ''s2'' is usd to hold the
180-
* temporary expansion.
181-
**/
175+
176+
// The final controlling conditions resulted from ''src''
177+
// will be stored in ''s1''; ''s2'' is usd to hold the
178+
// temporary expansion.
182179
s1.insert(src);
183180

184181
// dual-loop structure to eliminate complex
@@ -204,11 +201,9 @@ collect_mcdc_controlling_nested(const std::set<exprt> &decisions)
204201
for(std::size_t i = 0; i < operands.size(); i++)
205202
{
206203
std::set<exprt> res;
207-
/**
208-
* To expand an operand if it is not atomic,
209-
* and label the ''changed'' flag; the resulted
210-
* expansion of such an operand is stored in ''res''.
211-
**/
204+
// To expand an operand if it is not atomic,
205+
// and label the ''changed'' flag; the resulted
206+
// expansion of such an operand is stored in ''res''.
212207
if(operands[i].id() == ID_not)
213208
{
214209
exprt no = operands[i].op0();
@@ -281,9 +276,7 @@ std::set<signed> sign_of_expr(const exprt &e, const exprt &E)
281276
}
282277
}
283278

284-
/**
285-
* In the general case, we analyze each operand of ''E''.
286-
**/
279+
// In the general case, we analyze each operand of ''E''.
287280
std::vector<exprt> ops;
288281
collect_operands(E, ops);
289282
for(auto &x : ops)
@@ -348,12 +341,10 @@ void remove_repetition(std::set<exprt> &exprs)
348341
for(auto &x : exprs)
349342
{
350343
bool red = false;
351-
/**
352-
* To check if ''x'' is identical with some
353-
* expr in ''new_exprs''. Two exprs ''x''
354-
* and ''y'' are identical iff they have the
355-
* same sign for every atomic condition ''c''.
356-
**/
344+
// To check if ''x'' is identical with some
345+
// expr in ''new_exprs''. Two exprs ''x''
346+
// and ''y'' are identical iff they have the
347+
// same sign for every atomic condition ''c''.
357348
for(auto &y : new_exprs)
358349
{
359350
bool iden = true;
@@ -380,11 +371,9 @@ void remove_repetition(std::set<exprt> &exprs)
380371
}
381372
}
382373
}
383-
/**
384-
* If ''x'' is found identical w.r.t some
385-
* expr in ''new_conditions, we label it
386-
* and break.
387-
**/
374+
// If ''x'' is found identical w.r.t some
375+
// expr in ''new_conditions, we label it
376+
// and break.
388377
if(iden)
389378
{
390379
red = true;
@@ -509,12 +498,10 @@ bool is_mcdc_pair(
509498
eval_expr(atomic_exprs_e2, decision))
510499
return false;
511500

512-
/**
513-
* A mcdc pair of controlling exprs regarding ''c''
514-
* can have different values for only one atomic
515-
* expr, i.e., ''c''. Otherwise, they are not
516-
* a mcdc pair.
517-
**/
501+
// A mcdc pair of controlling exprs regarding ''c''
502+
// can have different values for only one atomic
503+
// expr, i.e., ''c''. Otherwise, they are not
504+
// a mcdc pair.
518505
int diff_count = 0;
519506
auto e1_it = atomic_exprs_e1.begin();
520507
auto e2_it = atomic_exprs_e2.begin();
@@ -577,22 +564,20 @@ void minimize_mcdc_controlling(
577564
{
578565
std::set<exprt> new_controlling;
579566
bool ctrl_update = false;
580-
/**
581-
* Iteratively, we test that after removing an item ''x''
582-
* from the ''controlling'', can a complete mcdc coverage
583-
* over ''decision'' still be reserved?
584-
*
585-
* If yes, we update ''controlling'' with the
586-
* ''new_controlling'' without ''x''; otherwise, we should
587-
* keep ''x'' within ''controlling''.
588-
*
589-
* If in the end all elements ''x'' in ''controlling'' are
590-
* reserved, this means that current ''controlling'' set is
591-
* minimum and the ''while'' loop should be broken out of.
592-
*
593-
* Note: implementation here for the above procedure is
594-
* not (meant to be) optimal.
595-
**/
567+
// Iteratively, we test that after removing an item ''x''
568+
// from the ''controlling'', can a complete mcdc coverage
569+
// over ''decision'' still be reserved?
570+
//
571+
// If yes, we update ''controlling'' with the
572+
// ''new_controlling'' without ''x''; otherwise, we should
573+
// keep ''x'' within ''controlling''.
574+
//
575+
// If in the end all elements ''x'' in ''controlling'' are
576+
// reserved, this means that current ''controlling'' set is
577+
// minimum and the ''while'' loop should be broken out of.
578+
//
579+
// Note: implementation here for the above procedure is
580+
// not (meant to be) optimal.
596581
for(auto &x : controlling)
597582
{
598583
// To create a new ''controlling'' set without ''x''
@@ -607,11 +592,9 @@ void minimize_mcdc_controlling(
607592
for(auto &c : conditions)
608593
{
609594
bool cOK = has_mcdc_pair(c, new_controlling, conditions, decision);
610-
/**
611-
* If there is no mcdc pair for an atomic condition ''c'',
612-
* then ''x'' should not be removed from the original
613-
* ''controlling'' set
614-
**/
595+
// If there is no mcdc pair for an atomic condition ''c'',
596+
// then ''x'' should not be removed from the original
597+
// ''controlling'' set
615598
if(!cOK)
616599
{
617600
removing_x = false;
@@ -679,7 +662,6 @@ void cover_mcdc_instrumentert::instrument(
679662
std::string comment_t = description + " `" + p_string + "' true";
680663
const irep_idt function = i_it->function;
681664
goto_program.insert_before_swap(i_it);
682-
// i_it->make_assertion(p);
683665
i_it->make_assertion(not_exprt(p));
684666
i_it->source_location = source_location;
685667
i_it->source_location.set_comment(comment_t);
@@ -690,7 +672,6 @@ void cover_mcdc_instrumentert::instrument(
690672

691673
std::string comment_f = description + " `" + p_string + "' false";
692674
goto_program.insert_before_swap(i_it);
693-
// i_it->make_assertion(not_exprt(p));
694675
i_it->make_assertion(p);
695676
i_it->source_location = source_location;
696677
i_it->source_location.set_comment(comment_f);
@@ -701,13 +682,14 @@ void cover_mcdc_instrumentert::instrument(
701682
}
702683

703684
std::set<exprt> controlling;
704-
// controlling=collect_mcdc_controlling(decisions);
705685
controlling = collect_mcdc_controlling_nested(decisions);
706686
remove_repetition(controlling);
707687
// for now, we restrict to the case of a single ''decision'';
708688
// however, this is not true, e.g., ''? :'' operator.
709-
INVARIANT(!decisions.empty(), "There must be at least one decision");
710-
minimize_mcdc_controlling(controlling, *decisions.begin());
689+
if(!decisions.empty())
690+
{
691+
minimize_mcdc_controlling(controlling, *decisions.begin());
692+
}
711693

712694
for(const auto &p : controlling)
713695
{
@@ -719,7 +701,6 @@ void cover_mcdc_instrumentert::instrument(
719701
const irep_idt function = i_it->function;
720702
goto_program.insert_before_swap(i_it);
721703
i_it->make_assertion(not_exprt(p));
722-
// i_it->make_assertion(p);
723704
i_it->source_location = source_location;
724705
i_it->source_location.set_comment(description);
725706
i_it->source_location.set(ID_coverage_criterion, coverage_criterion);

0 commit comments

Comments
 (0)