Skip to content

Commit 7f3a053

Browse files
author
Daniel Kroening
authored
Merge pull request #946 from tautschnig/coverage-fixes
Coverage report fixes
2 parents a304db6 + 31be993 commit 7f3a053

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
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: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,29 @@ static std::string rate(
131131

132132
/*******************************************************************\
133133
134+
Function: rate_detailed
135+
136+
Inputs:
137+
138+
Outputs:
139+
140+
Purpose:
141+
142+
\*******************************************************************/
143+
144+
static std::string rate_detailed(
145+
std::size_t covered,
146+
std::size_t total,
147+
bool per_cent=false)
148+
{
149+
std::ostringstream oss;
150+
oss << rate(covered, total, per_cent)
151+
<< " (" << covered << '/' << total << ')';
152+
return oss.str();
153+
}
154+
155+
/*******************************************************************\
156+
134157
Function: goto_program_coverage_recordt::goto_program_coverage_recordt
135158
136159
Inputs:
@@ -187,7 +210,7 @@ goto_program_coverage_recordt::goto_program_coverage_recordt(
187210
from_type(ns, gf_it->first, sig_type));
188211

189212
xml.set_attribute("line-rate",
190-
rate(lines_covered, lines_total));
213+
rate_detailed(lines_covered, lines_total));
191214
xml.set_attribute("branch-rate",
192215
rate(branches_covered, branches_total));
193216

@@ -219,10 +242,9 @@ goto_program_coverage_recordt::goto_program_coverage_recordt(
219242
condition.set_attribute("coverage", rate(taken, 2, true));
220243
}
221244

222-
std::ostringstream oss;
223-
oss << rate(total_taken, number*2, true)
224-
<< " (" << total_taken << '/' << number*2 << ')';
225-
line.set_attribute("condition-coverage", oss.str());
245+
line.set_attribute(
246+
"condition-coverage",
247+
rate_detailed(total_taken, number*2, true));
226248
}
227249
}
228250
}
@@ -292,7 +314,8 @@ void goto_program_coverage_recordt::compute_coverage_lines(
292314
if(entry.first->second.hits==0)
293315
++lines_covered;
294316

295-
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;
296319

297320
if(is_branch)
298321
{

0 commit comments

Comments
 (0)