@@ -167,43 +167,11 @@ bool ci_lazy_methodst::operator()(
167
167
}
168
168
}
169
169
170
- any_new_classes = false ;
171
-
172
- // Look for virtual callsites with no candidate targets. If we have
173
- // invokevirtual A.f and we don't believe either A or any of its children
174
- // may exist, we assume specifically A is somehow instantiated. Note this
175
- // may result in an abstract class being classified as instantiated, which
176
- // stands in for some unknown concrete subclass: in this case the called
177
- // method will be a stub.
178
- for (const exprt &virtual_function_call : virtual_function_calls)
179
- {
180
- std::unordered_set<irep_idt> candidate_target_methods;
181
- get_virtual_method_targets (
182
- virtual_function_call,
183
- instantiated_classes,
184
- candidate_target_methods,
185
- symbol_table);
186
-
187
- if (!candidate_target_methods.empty ())
188
- continue ;
189
-
190
- // Add the call class to instantiated_classes and assert that it
191
- // didn't already exist
192
- const irep_idt &call_class = virtual_function_call.get (ID_C_class);
193
- auto ret_class = instantiated_classes.insert (call_class);
194
- CHECK_RETURN (ret_class.second );
195
- any_new_classes = true ;
196
-
197
- // Check that `get_virtual_method_target` returns a method now
198
- const irep_idt &call_basename =
199
- virtual_function_call.get (ID_component_name);
200
- const irep_idt method_name = get_virtual_method_target (
201
- instantiated_classes, call_basename, call_class, symbol_table);
202
- CHECK_RETURN (!method_name.empty ());
203
-
204
- // Add what it returns to methods_to_convert_later
205
- methods_to_convert_later.insert (method_name);
206
- }
170
+ any_new_classes = handle_virtual_methods_with_no_callees (
171
+ methods_to_convert_later,
172
+ instantiated_classes,
173
+ virtual_function_calls,
174
+ symbol_table);
207
175
}
208
176
209
177
// cproverNondetInitialize has to be force-loaded for mocks to return valid
@@ -255,6 +223,52 @@ bool ci_lazy_methodst::operator()(
255
223
return false ;
256
224
}
257
225
226
+ // / Look for virtual callsites with no candidate targets. If we have
227
+ // / invokevirtual A.f and we don't believe either A or any of its children
228
+ // / may exist, we assume specifically A is somehow instantiated. Note this
229
+ // / may result in an abstract class being classified as instantiated, which
230
+ // / stands in for some unknown concrete subclass: in this case the called
231
+ // / method will be a stub.
232
+ // / \return whether a new class was encountered
233
+ bool ci_lazy_methodst::handle_virtual_methods_with_no_callees (
234
+ std::unordered_set<irep_idt> &methods_to_convert_later,
235
+ std::unordered_set<irep_idt> &instantiated_classes,
236
+ const std::unordered_set<exprt, irep_hash> &virtual_function_calls,
237
+ symbol_tablet &symbol_table)
238
+ {
239
+ bool any_new_classes = false ;
240
+ for (const exprt &virtual_function_call : virtual_function_calls)
241
+ {
242
+ std::unordered_set<irep_idt> candidate_target_methods;
243
+ get_virtual_method_targets (
244
+ virtual_function_call,
245
+ instantiated_classes,
246
+ candidate_target_methods,
247
+ symbol_table);
248
+
249
+ if (!candidate_target_methods.empty ())
250
+ continue ;
251
+
252
+ // Add the call class to instantiated_classes and assert that it
253
+ // didn't already exist
254
+ const irep_idt &call_class = virtual_function_call.get (ID_C_class);
255
+ auto ret_class = instantiated_classes.insert (call_class);
256
+ CHECK_RETURN (ret_class.second );
257
+ any_new_classes = true ;
258
+
259
+ // Check that `get_virtual_method_target` returns a method now
260
+ const irep_idt &call_basename =
261
+ virtual_function_call.get (ID_component_name);
262
+ const irep_idt method_name = get_virtual_method_target (
263
+ instantiated_classes, call_basename, call_class, symbol_table);
264
+ CHECK_RETURN (!method_name.empty ());
265
+
266
+ // Add what it returns to methods_to_convert_later
267
+ methods_to_convert_later.insert (method_name);
268
+ }
269
+ return any_new_classes;
270
+ }
271
+
258
272
// / Convert a method, add it to the populated set, add needed methods to
259
273
// / methods_to_convert_later and add virtual calls from the method to
260
274
// / virtual_function_calls
0 commit comments