Skip to content

Commit f18351b

Browse files
author
Matthias Güdemann
committed
Allow multi object type parameter in entry point function call
1 parent 6c09b3e commit f18351b

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

jbmc/src/java_bytecode/java_entry_point.cpp

+84-10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Author: Daniel Kroening, [email protected]
2222
#include "java_object_factory.h"
2323
#include "java_string_literals.h"
2424
#include "java_utils.h"
25+
#include "nondet.h"
26+
#include <util/fresh_symbol.h>
2527

2628
#define JAVA_MAIN_METHOD "main:([Ljava/lang/String;)V"
2729

@@ -317,17 +319,89 @@ exprt::operandst java_build_arguments(
317319

318320
parameters.function_id = goto_functionst::entry_point();
319321

322+
namespacet ns(symbol_table);
323+
320324
// generate code to allocate and non-deterministicaly initialize the
321-
// argument
322-
main_arguments[param_number] = object_factory(
323-
p.type(),
324-
base_name,
325-
init_code,
326-
symbol_table,
327-
parameters,
328-
allocation_typet::LOCAL,
329-
function.location,
330-
pointer_type_selector);
325+
// argument, if the argument has different possible object types (from casts
326+
// in the function body, choose one in a non-deterministic way)
327+
const auto alternatives =
328+
pointer_type_selector.get_parameter_alternative_types(
329+
function.name, p.get_identifier(), ns);
330+
if(!alternatives.has_value())
331+
{
332+
main_arguments[param_number] = object_factory(
333+
p.type(),
334+
base_name,
335+
init_code,
336+
symbol_table,
337+
parameters,
338+
allocation_typet::LOCAL,
339+
function.location,
340+
pointer_type_selector);
341+
}
342+
else
343+
{
344+
INVARIANT(!is_this, "We cannot have different types for `this` here");
345+
// create a non-deterministic switch between all possible values for the
346+
// type of the parameter.
347+
const auto alternative_object_types = alternatives.value();
348+
code_switcht code_switch;
349+
350+
// the idea is to get a new symbol for the parameter value `tmp`
351+
352+
// then add a non-deterministic switch over all possible input types,
353+
// construct the object type at hand and assign to `tmp`
354+
355+
// switch(...)
356+
// {
357+
// case obj1:
358+
// tmp_expr = object_factory(...)
359+
// param = tmp_expr
360+
// break
361+
// ...
362+
// }
363+
// method(..., param, ...)
364+
//
365+
366+
const symbolt result_symbol = get_fresh_aux_symbol(
367+
p.type(),
368+
"nondet_parameter_" + std::to_string(param_number),
369+
"nondet_parameter_" + std::to_string(param_number),
370+
function.location,
371+
ID_java,
372+
symbol_table);
373+
main_arguments[param_number] = result_symbol.symbol_expr();
374+
375+
std::vector<codet> cases;
376+
size_t alternative = 0;
377+
for(const auto &type : alternative_object_types)
378+
{
379+
code_blockt init_code_for_type;
380+
exprt init_expr_for_parameter = object_factory(
381+
java_reference_type(type),
382+
id2string(base_name) + "_alt_" + std::to_string(alternative),
383+
init_code_for_type,
384+
symbol_table,
385+
parameters,
386+
allocation_typet::DYNAMIC,
387+
function.location,
388+
pointer_type_selector);
389+
alternative++;
390+
init_code_for_type.add(
391+
code_assignt(
392+
result_symbol.symbol_expr(),
393+
typecast_exprt(init_expr_for_parameter, p.type())));
394+
cases.push_back(init_code_for_type);
395+
}
396+
397+
init_code.add(
398+
generate_nondet_switch(
399+
id2string(function.base_name) + "_" + std::to_string(param_number),
400+
cases,
401+
java_int_type(),
402+
function.location,
403+
symbol_table));
404+
}
331405

332406
// record as an input
333407
codet input(ID_input);

jbmc/src/java_bytecode/select_pointer_type.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,12 @@ select_pointer_typet::get_recursively_instantiated_type(
222222
visited.erase(parameter_name);
223223
return inst_val;
224224
}
225+
226+
optionalt<std::set<symbol_typet>>
227+
select_pointer_typet::get_parameter_alternative_types(
228+
const irep_idt &function_name,
229+
const irep_idt &parameter_name,
230+
const namespacet &ns) const
231+
{
232+
return {};
233+
}

jbmc/src/java_bytecode/select_pointer_type.h

+5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ class select_pointer_typet
4242
&generic_parameter_specialization_map,
4343
const namespacet &ns) const;
4444

45+
virtual optionalt<std::set<symbol_typet>> get_parameter_alternative_types(
46+
const irep_idt &function_name,
47+
const irep_idt &parameter_name,
48+
const namespacet &ns) const;
49+
4550
pointer_typet specialize_generics(
4651
const pointer_typet &pointer_type,
4752
const generic_parameter_specialization_mapt

0 commit comments

Comments
 (0)