Skip to content

Commit 3ab7e8b

Browse files
Merge pull request #1153 from lucasccordeiro/fix-existing-coverage
extended the existing-coverage option to support bytecode_index
2 parents 5110f18 + cc01a04 commit 3ab7e8b

File tree

2 files changed

+108
-32
lines changed

2 files changed

+108
-32
lines changed

src/goto-instrument/cover.cpp

Lines changed: 101 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ class basic_blockst
108108
bool coverage_goalst::get_coverage_goals(
109109
const std::string &coverage_file,
110110
message_handlert &message_handler,
111-
coverage_goalst &goals)
111+
coverage_goalst &goals,
112+
const irep_idt &mode)
112113
{
113114
jsont json;
114115
source_locationt source_location;
@@ -132,50 +133,113 @@ bool coverage_goalst::get_coverage_goals(
132133
return true;
133134
}
134135

135-
for(const auto &goal : json.array)
136+
// traverse the given JSON file
137+
for(const auto &goals_in_json : json.array)
136138
{
137-
// get the file of each existing goal
138-
irep_idt file=goal["file"].value;
139-
source_location.set_file(file);
140-
141-
// get the function of each existing goal
142-
irep_idt function=goal["function"].value;
143-
source_location.set_function(function);
144-
145-
// get the lines array
146-
if(goal["lines"].is_array())
139+
// get the set of goals
140+
if(goals_in_json["goals"].is_array())
147141
{
148-
for(const auto &line_json : goal["lines"].array)
142+
// store the source location for each existing goal
143+
for(const auto &each_goal : goals_in_json["goals"].array)
149144
{
150-
// get the line of each existing goal
151-
irep_idt line=line_json["number"].value;
152-
source_location.set_line(line);
145+
// ensure minimal requirements for a goal entry
146+
PRECONDITION(
147+
(!each_goal["goal"].is_null()) ||
148+
(!each_goal["sourceLocation"]["bytecode_index"].is_null()) ||
149+
(!each_goal["sourceLocation"]["file"].is_null() &&
150+
!each_goal["sourceLocation"]["function"].is_null() &&
151+
!each_goal["sourceLocation"]["line"].is_null()));
152+
153+
// check whether bytecode_index is provided for Java programs
154+
if(mode==ID_java &&
155+
each_goal["sourceLocation"]["bytecode_index"].is_null())
156+
{
157+
messaget message(message_handler);
158+
message.error() << coverage_file
159+
<< " file does not contain bytecode_index"
160+
<< messaget::eom;
161+
return true;
162+
}
163+
164+
if(!each_goal["sourceLocation"]["bytecode_index"].is_null())
165+
{
166+
// get and set the bytecode_index
167+
irep_idt bytecode_index=
168+
each_goal["sourceLocation"]["bytecode_index"].value;
169+
source_location.set_java_bytecode_index(bytecode_index);
170+
}
171+
172+
if(!each_goal["sourceLocation"]["file"].is_null())
173+
{
174+
// get and set the file
175+
irep_idt file=each_goal["sourceLocation"]["file"].value;
176+
source_location.set_file(file);
177+
}
178+
179+
if(!each_goal["sourceLocation"]["function"].is_null())
180+
{
181+
// get and set the function
182+
irep_idt function=each_goal["sourceLocation"]["function"].value;
183+
source_location.set_function(function);
184+
}
185+
186+
if(!each_goal["sourceLocation"]["line"].is_null())
187+
{
188+
// get and set the line
189+
irep_idt line=each_goal["sourceLocation"]["line"].value;
190+
source_location.set_line(line);
191+
}
192+
193+
// store the existing goal
153194
goals.add_goal(source_location);
154195
}
155196
}
156197
}
157198
return false;
158199
}
159200

201+
/// store existing goal
202+
/// \param goal: source location of the existing goal
160203
void coverage_goalst::add_goal(source_locationt goal)
161204
{
162-
existing_goals.push_back(goal);
205+
existing_goals[goal]=false;
206+
}
207+
208+
/// check whether we have an existing goal that is uncovered
209+
/// \param msg: message to be printed about the uncovered goal
210+
void coverage_goalst::check_uncovered_goals(messaget &msg)
211+
{
212+
for(const auto &existing_loc : existing_goals)
213+
{
214+
if(!existing_loc.second)
215+
{
216+
msg.warning()
217+
<< "Warning: existing goal in file "
218+
<< existing_loc.first.get_file()
219+
<< " line " << existing_loc.first.get_line()
220+
<< " function " << existing_loc.first.get_function()
221+
<< " is uncovered" << messaget::eom;
222+
}
223+
}
163224
}
164225

165226
/// compare the value of the current goal to the existing ones
166227
/// \param source_loc: source location of the current goal
167228
/// \return true : if the current goal exists false : otherwise
168-
bool coverage_goalst::is_existing_goal(source_locationt source_loc) const
229+
bool coverage_goalst::is_existing_goal(source_locationt source_loc)
169230
{
170231
for(const auto &existing_loc : existing_goals)
171232
{
172-
if((source_loc.get_file()==existing_loc.get_file()) &&
173-
(source_loc.get_function()==existing_loc.get_function()) &&
174-
(source_loc.get_line()==existing_loc.get_line()) &&
233+
if((source_loc.get_file()==existing_loc.first.get_file()) &&
234+
(source_loc.get_function()==existing_loc.first.get_function()) &&
235+
(source_loc.get_line()==existing_loc.first.get_line()) &&
175236
(source_loc.get_java_bytecode_index().empty() ||
176237
(source_loc.get_java_bytecode_index()==
177-
existing_loc.get_java_bytecode_index())))
178-
return true;
238+
existing_loc.first.get_java_bytecode_index())))
239+
{
240+
existing_goals[existing_loc.first]=true;
241+
return true;
242+
}
179243
}
180244
return false;
181245
}
@@ -989,7 +1053,7 @@ void instrument_cover_goals(
9891053
const symbol_tablet &symbol_table,
9901054
goto_programt &goto_program,
9911055
coverage_criteriont criterion,
992-
const coverage_goalst &goals,
1056+
coverage_goalst &goals,
9931057
bool function_only,
9941058
bool ignore_trivial)
9951059
{
@@ -1333,7 +1397,7 @@ void instrument_cover_goals(
13331397
const symbol_tablet &symbol_table,
13341398
goto_functionst &goto_functions,
13351399
coverage_criteriont criterion,
1336-
const coverage_goalst &goals,
1400+
coverage_goalst &goals,
13371401
bool function_only,
13381402
bool ignore_trivial)
13391403
{
@@ -1444,11 +1508,17 @@ bool instrument_cover_goals(
14441508
coverage_goalst existing_goals;
14451509
if(cmdline.isset("existing-coverage"))
14461510
{
1447-
msg.status() << "Check existing coverage goals" << messaget::eom;
1511+
// get the mode to ensure invariants
1512+
// (e.g., bytecode_index for Java programs)
1513+
namespacet ns(symbol_table);
1514+
const irep_idt &mode=ns.lookup(goto_functions.entry_point()).mode;
1515+
1516+
msg.status() << "Add existing coverage goals" << messaget::eom;
14481517
// get file with covered test goals
14491518
const std::string coverage=cmdline.get_value("existing-coverage");
14501519
// get a coverage_goalst object
1451-
if(coverage_goalst::get_coverage_goals(coverage, msgh, existing_goals))
1520+
if(coverage_goalst::get_coverage_goals(
1521+
coverage, msgh, existing_goals, mode))
14521522
{
14531523
msg.error() << "get_coverage_goals failed" << messaget::eom;
14541524
return true;
@@ -1468,6 +1538,10 @@ bool instrument_cover_goals(
14681538
cmdline.isset("no-trivial-tests"));
14691539
}
14701540

1541+
// check whether all existing goals have been covered
1542+
msg.status() << "Checking uncovered goals" << messaget::eom;
1543+
existing_goals.check_uncovered_goals(msg);
1544+
14711545
if(cmdline.isset("cover-traces-must-terminate"))
14721546
{
14731547
// instrument an additional goal in CPROVER_START. This will rephrase

src/goto-instrument/cover.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ class coverage_goalst
2323
static bool get_coverage_goals(
2424
const std::string &coverage,
2525
message_handlert &message_handler,
26-
coverage_goalst &goals);
26+
coverage_goalst &goals,
27+
const irep_idt &mode);
2728
void add_goal(source_locationt goal);
28-
bool is_existing_goal(source_locationt source_loc) const;
29+
bool is_existing_goal(source_locationt source_loc);
30+
void check_uncovered_goals(messaget &msg);
2931

3032
private:
31-
std::vector<source_locationt> existing_goals;
33+
std::map<source_locationt, bool> existing_goals;
3234
};
3335

3436
enum class coverage_criteriont
@@ -56,15 +58,15 @@ void instrument_cover_goals(
5658
const symbol_tablet &symbol_table,
5759
goto_functionst &goto_functions,
5860
coverage_criteriont,
59-
const coverage_goalst &goals,
61+
coverage_goalst &goals,
6062
bool function_only=false,
6163
bool ignore_trivial=false);
6264

6365
void instrument_cover_goals(
6466
const symbol_tablet &symbol_table,
6567
goto_programt &goto_program,
6668
coverage_criteriont,
67-
const coverage_goalst &goals,
69+
coverage_goalst &goals,
6870
bool function_only=false,
6971
bool ignore_trivial=false);
7072

0 commit comments

Comments
 (0)