@@ -22,6 +22,8 @@ Author: Daniel Kroening, kroening@kroening.com
22
22
#include " java_object_factory.h"
23
23
#include " java_string_literals.h"
24
24
#include " java_utils.h"
25
+ #include " nondet.h"
26
+ #include < util/fresh_symbol.h>
25
27
26
28
#define JAVA_MAIN_METHOD " main:([Ljava/lang/String;)V"
27
29
@@ -317,17 +319,89 @@ exprt::operandst java_build_arguments(
317
319
318
320
parameters.function_id = goto_functionst::entry_point ();
319
321
322
+ namespacet ns (symbol_table);
323
+
320
324
// 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
+ }
331
405
332
406
// record as an input
333
407
codet input (ID_input);
0 commit comments