Skip to content

Commit 0003d8a

Browse files
authored
Merge pull request diffblue#1864 from owen-jones-diffblue/owen-jones-diffblue/consistent-casts-in-remove-virtual-function
Make remove_virtual_function() consistent
2 parents c62b957 + c9f3ea4 commit 0003d8a

File tree

7 files changed

+63
-14
lines changed

7 files changed

+63
-14
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
public class VirtualFunctions {
2+
Object static_object;
3+
4+
public static class A {
5+
public void f() {
6+
}
7+
}
8+
9+
public static class B extends A{
10+
public void f() {
11+
}
12+
}
13+
14+
public static class C extends B {
15+
}
16+
17+
public static void check(A a, B b, C c) {
18+
// multiple possibilities, one needs a cast
19+
a.f();
20+
21+
// single possibility, does not need a cast
22+
b.f();
23+
24+
// single possibility, needs cast
25+
c.f();
26+
}
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
VirtualFunctions.class
3+
--lazy-methods --java-max-vla-length 48 --unwind 8 --java-unwind-enum-static --trace --cover location --function VirtualFunctions.check --show-goto-functions
4+
\(struct VirtualFunctions\$B \*\)a \. VirtualFunctions\$B\.f:\(\)V\(\);$
5+
a \. VirtualFunctions\$A\.f:\(\)V\(\);$
6+
b \. VirtualFunctions\$B\.f:\(\)V\(\);$
7+
\(struct VirtualFunctions\$B \*\)c \. VirtualFunctions\$B\.f:\(\)V\(\);$
8+
--

src/goto-programs/remove_virtual_functions.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,28 @@ void remove_virtual_functionst::remove_virtual_function(
9696
virtual_dispatch_fallback_actiont::CALL_LAST_FUNCTION);
9797
}
9898

99+
/// Create a concrete function call to replace a virtual one
100+
/// \param call [in/out]: the function call to update
101+
/// \param function_symbol: the function to be called
102+
/// \param ns: namespace
103+
static void create_static_function_call(
104+
code_function_callt &call,
105+
const symbol_exprt &function_symbol,
106+
const namespacet &ns)
107+
{
108+
call.function() = function_symbol;
109+
// Cast the `this` pointer to the correct type for the new callee:
110+
const auto &callee_type =
111+
to_code_type(ns.lookup(function_symbol.get_identifier()).type);
112+
const code_typet::parametert *this_param = callee_type.get_this();
113+
INVARIANT(
114+
this_param != nullptr,
115+
"Virtual function callees must have a `this` argument");
116+
typet need_type = this_param->type();
117+
if(!type_eq(call.arguments()[0].type(), need_type, ns))
118+
call.arguments()[0].make_typecast(need_type);
119+
}
120+
99121
void remove_virtual_functionst::remove_virtual_function(
100122
goto_programt &goto_program,
101123
goto_programt::targett target,
@@ -121,8 +143,10 @@ void remove_virtual_functionst::remove_virtual_function(
121143
if(functions.begin()->symbol_expr==symbol_exprt())
122144
target->make_skip();
123145
else
124-
to_code_function_call(target->code).function()=
125-
functions.begin()->symbol_expr;
146+
{
147+
create_static_function_call(
148+
to_code_function_call(target->code), functions.front().symbol_expr, ns);
149+
}
126150
return;
127151
}
128152

@@ -187,18 +211,8 @@ void remove_virtual_functionst::remove_virtual_function(
187211
{
188212
// call function
189213
t1->make_function_call(code);
190-
auto &newcall=to_code_function_call(t1->code);
191-
newcall.function()=fun.symbol_expr;
192-
// Cast the `this` pointer to the correct type for the new callee:
193-
const auto &callee_type=
194-
to_code_type(ns.lookup(fun.symbol_expr.get_identifier()).type);
195-
const code_typet::parametert *this_param = callee_type.get_this();
196-
INVARIANT(
197-
this_param != nullptr,
198-
"Virtual function callees must have a `this` argument");
199-
typet need_type=this_param->type();
200-
if(!type_eq(newcall.arguments()[0].type(), need_type, ns))
201-
newcall.arguments()[0].make_typecast(need_type);
214+
create_static_function_call(
215+
to_code_function_call(t1->code), fun.symbol_expr, ns);
202216
}
203217
else
204218
{

0 commit comments

Comments
 (0)