@@ -108,7 +108,8 @@ class basic_blockst
108
108
bool coverage_goalst::get_coverage_goals (
109
109
const std::string &coverage_file,
110
110
message_handlert &message_handler,
111
- coverage_goalst &goals)
111
+ coverage_goalst &goals,
112
+ const irep_idt &mode)
112
113
{
113
114
jsont json;
114
115
source_locationt source_location;
@@ -132,50 +133,113 @@ bool coverage_goalst::get_coverage_goals(
132
133
return true ;
133
134
}
134
135
135
- for (const auto &goal : json.array )
136
+ // traverse the given JSON file
137
+ for (const auto &goals_in_json : json.array )
136
138
{
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 ())
147
141
{
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 )
149
144
{
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
153
194
goals.add_goal (source_location);
154
195
}
155
196
}
156
197
}
157
198
return false ;
158
199
}
159
200
201
+ // / store existing goal
202
+ // / \param goal: source location of the existing goal
160
203
void coverage_goalst::add_goal (source_locationt goal)
161
204
{
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
+ }
163
224
}
164
225
165
226
// / compare the value of the current goal to the existing ones
166
227
// / \param source_loc: source location of the current goal
167
228
// / \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)
169
230
{
170
231
for (const auto &existing_loc : existing_goals)
171
232
{
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 ()) &&
175
236
(source_loc.get_java_bytecode_index ().empty () ||
176
237
(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
+ }
179
243
}
180
244
return false ;
181
245
}
@@ -989,7 +1053,7 @@ void instrument_cover_goals(
989
1053
const symbol_tablet &symbol_table,
990
1054
goto_programt &goto_program,
991
1055
coverage_criteriont criterion,
992
- const coverage_goalst &goals,
1056
+ coverage_goalst &goals,
993
1057
bool function_only,
994
1058
bool ignore_trivial)
995
1059
{
@@ -1333,7 +1397,7 @@ void instrument_cover_goals(
1333
1397
const symbol_tablet &symbol_table,
1334
1398
goto_functionst &goto_functions,
1335
1399
coverage_criteriont criterion,
1336
- const coverage_goalst &goals,
1400
+ coverage_goalst &goals,
1337
1401
bool function_only,
1338
1402
bool ignore_trivial)
1339
1403
{
@@ -1444,11 +1508,17 @@ bool instrument_cover_goals(
1444
1508
coverage_goalst existing_goals;
1445
1509
if (cmdline.isset (" existing-coverage" ))
1446
1510
{
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;
1448
1517
// get file with covered test goals
1449
1518
const std::string coverage=cmdline.get_value (" existing-coverage" );
1450
1519
// 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))
1452
1522
{
1453
1523
msg.error () << " get_coverage_goals failed" << messaget::eom;
1454
1524
return true ;
@@ -1468,6 +1538,10 @@ bool instrument_cover_goals(
1468
1538
cmdline.isset (" no-trivial-tests" ));
1469
1539
}
1470
1540
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
+
1471
1545
if (cmdline.isset (" cover-traces-must-terminate" ))
1472
1546
{
1473
1547
// instrument an additional goal in CPROVER_START. This will rephrase
0 commit comments