Skip to content

Commit 565f5bf

Browse files
authored
Merge pull request #1228 from thk123/bugfix/lazy-method-params
Lazy Methods not loading base classes of params
2 parents 5b0c34f + e788227 commit 565f5bf

21 files changed

+952
-540
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
test.class
3+
--lazy-methods --verbosity 10 --function test.test
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
elaborate java::Base\.f:\(\)V
7+
--
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Base
2+
{
3+
void f() { }
4+
}
5+
6+
class Middle extends Base
7+
{
8+
}
9+
10+
class Derived extends Middle
11+
{
12+
void f() { }
13+
}
14+
15+
class Foo
16+
{
17+
public Middle m;
18+
}
19+
20+
public class test {
21+
22+
public static void test(Foo foo) {
23+
if(foo != null && foo.m != null) {
24+
foo.m.f();
25+
}
26+
}
27+
}

src/goto-programs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ SRC = basic_blocks.cpp \
4949
remove_vector.cpp \
5050
remove_virtual_functions.cpp \
5151
replace_java_nondet.cpp \
52+
resolve_concrete_function_call.cpp \
5253
safety_checker.cpp \
5354
set_properties.cpp \
5455
show_goto_functions.cpp \

src/goto-programs/class_hierarchy.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ void class_hierarchyt::get_children_trans_rec(
6464
get_children_trans_rec(child, dest);
6565
}
6666

67+
/// Get all the classes that inherit (directly or indirectly) from class c. The
68+
/// first element(s) will be the immediate parents of c, followed by their
69+
/// immedatiate parents and so on.
70+
/// \param c: The class to consider
71+
/// \param [out] dest: A list of class ids that c eventually inherits from.
6772
void class_hierarchyt::get_parents_trans_rec(
6873
const irep_idt &c,
6974
idst &dest) const

src/goto-programs/remove_virtual_functions.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Author: Daniel Kroening, [email protected]
1313
#include "class_hierarchy.h"
1414
#include "class_identifier.h"
1515

16+
#include <goto-programs/resolve_concrete_function_call.h>
17+
1618
#include <util/c_types.h>
1719
#include <util/prefix.h>
1820
#include <util/type_eq.h>
@@ -258,32 +260,26 @@ void remove_virtual_functionst::get_functions(
258260
{
259261
const irep_idt class_id=function.get(ID_C_class);
260262
const irep_idt component_name=function.get(ID_component_name);
261-
assert(!class_id.empty());
263+
INVARIANT(!class_id.empty(), "All virtual functions must have a class");
264+
265+
resolve_concrete_function_callt get_virtual_call_target(
266+
symbol_table, class_hierarchy);
267+
const resolve_concrete_function_callt::concrete_function_callt &
268+
resolved_call=get_virtual_call_target(class_id, component_name);
262269
functiont root_function;
263270

264-
// Start from current class, go to parents until something
265-
// is found.
266-
irep_idt c=class_id;
267-
while(!c.empty())
271+
if(resolved_call.is_valid())
268272
{
269-
exprt method=get_method(c, component_name);
270-
if(method.is_not_nil())
271-
{
272-
root_function.class_id=c;
273-
root_function.symbol_expr=to_symbol_expr(method);
274-
root_function.symbol_expr.set(ID_C_class, c);
275-
break; // abort
276-
}
273+
root_function.class_id=resolved_call.get_class_identifier();
277274

278-
const class_hierarchyt::idst &parents=
279-
class_hierarchy.class_map[c].parents;
275+
const symbolt &called_symbol=
276+
symbol_table.lookup(resolved_call.get_virtual_method_name());
280277

281-
if(parents.empty())
282-
break;
283-
c=parents.front();
278+
root_function.symbol_expr=called_symbol.symbol_expr();
279+
root_function.symbol_expr.set(
280+
ID_C_class, resolved_call.get_class_identifier());
284281
}
285-
286-
if(root_function.class_id.empty())
282+
else
287283
{
288284
// No definition here; this is an abstract function.
289285
root_function.class_id=class_id;
@@ -306,8 +302,9 @@ exprt remove_virtual_functionst::get_method(
306302
const irep_idt &class_id,
307303
const irep_idt &component_name) const
308304
{
309-
irep_idt id=id2string(class_id)+"."+
310-
id2string(component_name);
305+
const irep_idt &id=
306+
resolve_concrete_function_callt::build_virtual_method_name(
307+
class_id, component_name);
311308

312309
const symbolt *symbol;
313310
if(ns.lookup(id, symbol))

0 commit comments

Comments
 (0)