@@ -22,6 +22,8 @@ Author: Daniel Kroening, kroening@kroening.com
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
320- // 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);
322+ namespacet ns (symbol_table);
323+
324+ // Generate code to allocate and non-deterministicaly initialize the
325+ // argument, if the argument has different possible object types (e.g., from
326+ // casts in the function body), then 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);
0 commit comments