Skip to content

Commit 610bbdf

Browse files
Extract handle_virtual_methods_with_no_callees
1 parent 2f8f09f commit 610bbdf

File tree

2 files changed

+57
-37
lines changed

2 files changed

+57
-37
lines changed

jbmc/src/java_bytecode/ci_lazy_methods.cpp

+51-37
Original file line numberDiff line numberDiff line change
@@ -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+
258272
/// Convert a method, add it to the populated set, add needed methods to
259273
/// methods_to_convert_later and add virtual calls from the method to
260274
/// virtual_function_calls

jbmc/src/java_bytecode/ci_lazy_methods.h

+6
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ class ci_lazy_methodst:public messaget
188188
std::unordered_set<irep_idt> &methods_to_convert_later,
189189
std::unordered_set<irep_idt> &instantiated_classes,
190190
std::unordered_set<exprt, irep_hash> &virtual_function_calls);
191+
192+
bool handle_virtual_methods_with_no_callees(
193+
std::unordered_set<irep_idt> &methods_to_convert_later,
194+
std::unordered_set<irep_idt> &instantiated_classes,
195+
const std::unordered_set<exprt, irep_hash> &virtual_function_calls,
196+
symbol_tablet &symbol_table);
191197
};
192198

193199
#endif // CPROVER_JAVA_BYTECODE_GATHER_METHODS_LAZILY_H

0 commit comments

Comments
 (0)