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
225 Bytes
Binary file not shown.
218 Bytes
Binary file not shown.
204 Bytes
Binary file not shown.
172 Bytes
Binary file not shown.
343 Bytes
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)