@@ -47,7 +47,10 @@ mathematical_function_typet state_predicate_type()
47
47
class state_encodingt
48
48
{
49
49
public:
50
- void operator ()(const goto_functiont &, encoding_targett &);
50
+ void operator ()(
51
+ const goto_functionst &,
52
+ const goto_functiont &,
53
+ encoding_targett &);
51
54
52
55
protected:
53
56
using loct = goto_programt::const_targett;
@@ -245,6 +248,7 @@ void state_encodingt::setup_incoming(const goto_functiont &goto_function)
245
248
}
246
249
247
250
void state_encodingt::operator ()(
251
+ const goto_functionst &goto_functions,
248
252
const goto_functiont &goto_function,
249
253
encoding_targett &dest)
250
254
{
@@ -353,63 +357,103 @@ void state_encodingt::operator()(
353
357
}
354
358
else if (loc->is_function_call ())
355
359
{
356
- // Evaluate the arguments of the call in the 'in state'
357
- multi_ary_exprt arguments_evaluated (ID_tuple, {}, typet (ID_tuple));
358
- arguments_evaluated.reserve_operands (loc->call_arguments ().size ());
359
-
360
- const auto in_state = in_state_expr (loc);
361
-
362
- for (auto &argument : loc->call_arguments ())
363
- arguments_evaluated.add_to_operands (evaluate_expr (loc, in_state, argument));
364
-
365
- auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
366
-
367
- dest << forall_states_expr (loc,
368
- function_application_exprt (function_entry_state, {state_expr ()}));
369
-
370
- // Function return state (suffix PostReturn).
371
- // This is the state after exiting the function but prior to
372
- // assigning the LHS of the function call.
373
- auto return_state = state_expr_with_suffix (loc, " PostReturn" );
374
-
375
- /*
376
- constraints.push_back(
377
- multi_ary_exprt(
378
- ID_goto_contract,
379
- {loc->call_function(), in_state, return_state, arguments_evaluated},
380
- bool_typet()));
381
- */
382
-
383
- // assign the return value, if any
384
- if (loc->call_lhs ().is_not_nil ())
360
+ // Function pointer?
361
+ const auto &function = loc->call_function ();
362
+ if (function.id () == ID_dereference)
385
363
{
386
- exprt equality_rhs = return_state;
387
-
388
- /*
389
- auto &return_type = loc->call_lhs().type();
390
- auto rhs_evaluated =
391
- evaluate_expr(
392
- loc,
393
- return_state,
394
- symbol_exprt("return_value", return_type));
364
+ // TBD.
365
+ PRECONDITION (false );
366
+ }
367
+ else if (function.id () == ID_symbol)
368
+ {
369
+ // Do we have a function body?
370
+ auto identifier = to_symbol_expr (function).get_identifier ();
371
+ auto f = goto_functions.function_map .find (identifier);
372
+ if (f == goto_functions.function_map .end ())
373
+ DATA_INVARIANT (false , " failed find function in function_map" );
374
+ if (f->second .body_available ())
375
+ {
376
+ // Evaluate the arguments of the call in the 'in state'
377
+ multi_ary_exprt arguments_evaluated (ID_tuple, {}, typet (ID_tuple));
378
+ arguments_evaluated.reserve_operands (loc->call_arguments ().size ());
395
379
396
- multi_ary_exprt designator(ID_designator, { loc->call_lhs() }, typet() );
380
+ const auto in_state = in_state_expr (loc );
397
381
398
- auto lhs = out_state_expr(source);
382
+ for (auto &argument : loc->call_arguments ())
383
+ arguments_evaluated.add_to_operands (
384
+ evaluate_expr (loc, in_state, argument));
399
385
400
- auto rhs = update_exprt(
401
- return_state,
402
- designator,
403
- rhs_evaluated);
386
+ auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
404
387
405
- // 'out state' equality
406
- constraints.push_back(equal_exprt(lhs, rhs));
407
- */
388
+ dest << forall_states_expr (
389
+ loc,
390
+ function_application_exprt (function_entry_state, {state_expr ()}));
391
+
392
+ // Function return state (suffix PostReturn).
393
+ // This is the state after exiting the function but prior to
394
+ // assigning the LHS of the function call.
395
+ auto return_state = state_expr_with_suffix (loc, " PostReturn" );
396
+
397
+ /*
398
+ constraints.push_back(
399
+ multi_ary_exprt(
400
+ ID_goto_contract,
401
+ {loc->call_function(), in_state, return_state, arguments_evaluated},
402
+ bool_typet()));
403
+ */
404
+
405
+ // assign the return value, if any
406
+ if (loc->call_lhs ().is_not_nil ())
407
+ {
408
+ exprt equality_rhs = return_state;
409
+
410
+ /*
411
+ auto &return_type = loc->call_lhs().type();
412
+ auto rhs_evaluated =
413
+ evaluate_expr(
414
+ loc,
415
+ return_state,
416
+ symbol_exprt("return_value", return_type));
417
+
418
+ multi_ary_exprt designator(ID_designator, { loc->call_lhs() }, typet());
419
+
420
+ auto lhs = out_state_expr(source);
421
+
422
+ auto rhs = update_exprt(
423
+ return_state,
424
+ designator,
425
+ rhs_evaluated);
426
+
427
+ // 'out state' equality
428
+ constraints.push_back(equal_exprt(lhs, rhs));
429
+ */
430
+ }
431
+ else
432
+ {
433
+ // 'out state' equality
434
+ dest << equal_exprt (out_state_expr (loc), return_state);
435
+ }
436
+ }
437
+ else
438
+ {
439
+ // no function body -- do LHS assignment nondeterministically, if any
440
+ if (loc->call_lhs ().is_not_nil ())
441
+ {
442
+ auto rhs = side_effect_expr_nondett (
443
+ loc->call_lhs ().type (), loc->source_location ());
444
+ dest << assignment_constraint (loc, loc->call_lhs (), std::move (rhs));
445
+ }
446
+ else
447
+ {
448
+ // This is a SKIP.
449
+ dest << equal_exprt (out_state_expr (loc), in_state_expr (loc));
450
+ }
451
+ }
408
452
}
409
453
else
410
454
{
411
- // 'out state' equality
412
- dest << equal_exprt ( out_state_expr (loc), return_state );
455
+ DATA_INVARIANT (
456
+ false , " got function that's neither a symbol nor a function pointer " );
413
457
}
414
458
}
415
459
else if (loc->is_set_return_value ())
@@ -433,7 +477,7 @@ void state_encoding(
433
477
goto_functionst::entry_point ());
434
478
PRECONDITION (f_entry != goto_model.goto_functions .function_map .end ());
435
479
436
- state_encodingt{}(f_entry->second , dest);
480
+ state_encodingt{}(goto_model. goto_functions , f_entry->second , dest);
437
481
}
438
482
else
439
483
{
@@ -445,7 +489,7 @@ void state_encoding(
445
489
if (f->second .body_available ())
446
490
{
447
491
dest.annotation (" function " + id2string (f->first ));
448
- state_encodingt{}(f->second , dest);
492
+ state_encodingt{}(goto_model. goto_functions , f->second , dest);
449
493
}
450
494
}
451
495
}
0 commit comments