Skip to content

Commit 31be993

Browse files
committed
Fix coverage reporting of forward-goto statements (break, continue)
cr https://code.amazon.com/reviews/CR-198650
1 parent 7b3c96f commit 31be993

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
int main(int argc, char* argv[])
2+
{
3+
if(argc>2)
4+
{
5+
argc=1;
6+
}
7+
else
8+
{
9+
argc=2;
10+
}
11+
12+
switch(argc)
13+
{
14+
case 0:
15+
argc=3;
16+
break;
17+
case 1:
18+
argc=2;
19+
break;
20+
}
21+
22+
return 0;
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
--symex-coverage-report -
4+
<line branch="false" hits="1" number="12"/>
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
^warning: ignoring

src/cbmc/symex_bmc.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ void symex_bmct::symex_step(
6565
}
6666

6767
const goto_programt::const_targett cur_pc=state.source.pc;
68+
const guardt cur_guard=state.guard;
6869

6970
if(!state.guard.is_false() &&
7071
state.source.pc->is_assume() &&
@@ -84,16 +85,23 @@ void symex_bmct::symex_step(
8485
goto_symext::symex_step(goto_functions, state);
8586

8687
if(record_coverage &&
87-
// is the instruction being executed
88-
!state.guard.is_false() &&
8988
// avoid an invalid iterator in state.source.pc
9089
(!cur_pc->is_end_function() ||
91-
cur_pc->function!=goto_functions.entry_point()) &&
92-
// ignore transition to next instruction when goto points elsewhere
93-
(!cur_pc->is_goto() ||
94-
cur_pc->get_target()==state.source.pc ||
95-
!cur_pc->guard.is_true()))
96-
symex_coverage.covered(cur_pc, state.source.pc);
90+
cur_pc->function!=goto_functions.entry_point()))
91+
{
92+
// forward goto will effectively be covered via phi function,
93+
// which does not invoke symex_step; as symex_step is called
94+
// before merge_gotos, also state.guard will be false (we have
95+
// taken an impossible transition); thus we synthesize a
96+
// transition from the goto instruction to its target to make
97+
// sure the goto is considered covered
98+
if(cur_pc->is_goto() &&
99+
cur_pc->get_target()!=state.source.pc &&
100+
cur_pc->guard.is_true())
101+
symex_coverage.covered(cur_pc, cur_pc->get_target());
102+
else if(!state.guard.is_false())
103+
symex_coverage.covered(cur_pc, state.source.pc);
104+
}
97105
}
98106

99107
/*******************************************************************\

src/cbmc/symex_coverage.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ void goto_program_coverage_recordt::compute_coverage_lines(
314314
if(entry.first->second.hits==0)
315315
++lines_covered;
316316

317-
entry.first->second.hits+=cov.second.num_executions;
317+
if(cov.second.num_executions>entry.first->second.hits)
318+
entry.first->second.hits=cov.second.num_executions;
318319

319320
if(is_branch)
320321
{

0 commit comments

Comments
 (0)