55 goto_functionst::function_mapt::const_iterator gf_it,
85 std::map<goto_programt::const_targett, coverage_conditiont>
89 typedef std::map<unsigned, coverage_linet>
104 std::ostringstream oss;
112 fraction=static_cast<float>(covered)/static_cast<float>(total);
115 oss << fraction*100.0 <<
'%';
119 oss << covered <<
" of " << total;
130 std::ostringstream oss;
131 oss <<
rate(covered, total, per_cent)
132 <<
" (" << covered <<
'/' << total <<
')';
138 goto_functionst::function_mapt::const_iterator gf_it,
147 --gf_it->second.body.instructions.end();
149 end_function->is_end_function(),
150 "last instruction in a function body is end function");
151 file_name=end_function->source_location.get_file();
188 for(
const auto &cov_line : coverage_lines_map)
194 if(cov_line.second.conditions.empty())
202 std::size_t number=0, total_taken=0;
203 for(
const auto &c : cov_line.second.conditions)
209 unsigned taken=c.second.false_taken+c.second.true_taken;
215 "condition-coverage",
229 if(it->source_location.is_nil() ||
230 it->source_location.get_file()!=
file_name ||
232 it->is_end_function())
235 const bool is_branch=it->is_goto() && !it->guard.is_constant();
239 std::pair<coverage_lines_mapt::iterator, bool> entry=
250 if(!entry.first->second.conditions.insert(
251 {it, coverage_conditiont()}).second)
255 symex_coveraget::coveraget::const_iterator c_entry=
257 if(c_entry!=coverage.end())
259 if(!(c_entry->second.size()==1 || is_branch))
261 std::cerr << it->location_number <<
'\n';
262 for(
const auto &cov : c_entry->second)
263 std::cerr << cov.second.succ->location_number <<
'\n';
266 c_entry->second.size() == 1 || is_branch,
267 "instructions other than branch instructions have exactly 1 successor");
269 for(
const auto &cov : c_entry->second)
272 cov.second.num_executions > 0,
273 "coverage entries can only exist with at least one execution");
275 if(entry.first->second.hits==0)
278 if(cov.second.num_executions>entry.first->second.hits)
279 entry.first->second.hits=cov.second.num_executions;
283 auto cond_entry=entry.first->second.conditions.find(it);
285 cond_entry != entry.first->second.conditions.end(),
286 "branch should have condition");
288 if(it->get_target()==cov.second.succ)
290 if(!cond_entry->second.false_taken)
292 cond_entry->second.false_taken=
true;
298 if(!cond_entry->second.true_taken)
300 cond_entry->second.true_taken=
true;
314 typedef std::map<irep_idt, coverage_recordt> file_recordst;
315 file_recordst file_records;
319 if(!gf_it->second.body_available() ||
326 std::pair<file_recordst::iterator, bool> entry=
327 file_records.insert(std::make_pair(func_cov.
get_file(),
341 for(xmlt::elementst::const_iterator
358 for(file_recordst::const_iterator it=file_records.begin();
359 it!=file_records.end();
388 xmlt &xml_coverage)
const
393 std::string overall_line_rate_str=
395 std::string overall_branch_rate_str=
398 auto now = std::chrono::system_clock::now();
399 auto current_time = std::chrono::time_point_cast<std::chrono::seconds>(now);
400 std::time_t tt = std::chrono::system_clock::to_time_t(current_time);
406 xml_coverage.
set_attribute(
"line-rate", overall_line_rate_str);
407 xml_coverage.
set_attribute(
"branch-rate", overall_branch_rate_str);
427 package.
set_attribute(
"branch-rate", overall_branch_rate_str);
433 std::ostream &os)
const
435 xmlt xml_coverage(
"coverage");
438 os <<
"<?xml version=\"1.0\"?>\n";
439 os <<
"<!DOCTYPE coverage SYSTEM \""
440 <<
"http://cobertura.sourceforge.net/xml/coverage-04.dtd\">\n";
448 const std::string &path)
const
456 std::ofstream out(path.c_str());