@@ -167,43 +167,11 @@ bool ci_lazy_methodst::operator()(
167167 }
168168 }
169169
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);
207175 }
208176
209177 // cproverNondetInitialize has to be force-loaded for mocks to return valid
@@ -255,6 +223,52 @@ bool ci_lazy_methodst::operator()(
255223 return false ;
256224}
257225
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+
258272ci_lazy_methodst::convert_method_resultt
259273ci_lazy_methodst::convert_and_analyze_method (
260274 const method_convertert &method_converter,
0 commit comments