Skip to content

Commit f9aac34

Browse files
committed
Avoid duplicate callee class-ids in virtual dispatch tables. Fixes #684
These were introduced because remove-virtual-functions' class hierarchy walk assumed it was tree-structured, but Java interfaces show up in the graph like multiple inheritence and falsify that assumption. This simply truncates the walk when class IDs have been seen before.
1 parent 29af567 commit f9aac34

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/goto-programs/remove_virtual_functions.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ class remove_virtual_functionst
5757
typedef std::vector<functiont> functionst;
5858
void get_functions(const exprt &, functionst &);
5959
void get_child_functions_rec(
60-
const irep_idt &, const symbol_exprt &,
61-
const irep_idt &, functionst &) const;
60+
const irep_idt &,
61+
const symbol_exprt &,
62+
const irep_idt &,
63+
functionst &,
64+
std::set<irep_idt> &visited) const;
6265
exprt get_method(
6366
const irep_idt &class_id,
6467
const irep_idt &component_name) const;
@@ -254,14 +257,17 @@ void remove_virtual_functionst::get_child_functions_rec(
254257
const irep_idt &this_id,
255258
const symbol_exprt &last_method_defn,
256259
const irep_idt &component_name,
257-
functionst &functions) const
260+
functionst &functions,
261+
std::set<irep_idt> &visited) const
258262
{
259263
auto findit=class_hierarchy.class_map.find(this_id);
260264
if(findit==class_hierarchy.class_map.end())
261265
return;
262266

263267
for(const auto &child : findit->second.children)
264268
{
269+
if(!visited.insert(child).second)
270+
continue;
265271
exprt method=get_method(child, component_name);
266272
functiont function(child);
267273
if(method.is_not_nil())
@@ -279,7 +285,8 @@ void remove_virtual_functionst::get_child_functions_rec(
279285
child,
280286
function.symbol_expr,
281287
component_name,
282-
functions);
288+
functions,
289+
visited);
283290
}
284291
}
285292

@@ -333,11 +340,13 @@ void remove_virtual_functionst::get_functions(
333340
}
334341

335342
// iterate over all children, transitively
343+
std::set<irep_idt> visited;
336344
get_child_functions_rec(
337345
class_id,
338346
root_function.symbol_expr,
339347
component_name,
340-
functions);
348+
functions,
349+
visited);
341350

342351
if(root_function.symbol_expr!=symbol_exprt())
343352
functions.push_back(root_function);

0 commit comments

Comments
 (0)