@@ -57,6 +57,10 @@ class state_encodingt
57
57
const goto_functionst &,
58
58
goto_programt::const_targett,
59
59
encoding_targett &);
60
+ void function_call_symbol (
61
+ const goto_functionst &,
62
+ goto_programt::const_targett,
63
+ encoding_targett &);
60
64
61
65
loct first_loc;
62
66
using incomingt = std::map<loct, std::vector<loct>>;
@@ -354,121 +358,130 @@ static exprt simplifying_not(exprt src)
354
358
return not_exprt (src);
355
359
}
356
360
357
- void state_encodingt::function_call (
361
+ void state_encodingt::function_call_symbol (
358
362
const goto_functionst &goto_functions,
359
363
goto_programt::const_targett loc,
360
364
encoding_targett &dest)
361
365
{
362
- // Function pointer?
363
366
const auto &function = loc->call_function ();
364
- if (function.id () == ID_dereference)
367
+ auto identifier = to_symbol_expr (function).get_identifier ();
368
+
369
+ // malloc is special-cased
370
+ if (identifier == " malloc" )
365
371
{
366
- // TBD.
367
- throw incorrect_goto_program_exceptiont (
368
- " can't do function pointers" , loc->source_location ());
372
+ auto state = state_expr ();
373
+ PRECONDITION (loc->call_arguments ().size () == 1 );
374
+ auto size_evaluated = evaluate_expr (loc, state, loc->call_arguments ()[0 ]);
375
+
376
+ auto lhs_address = address_rec (loc, state, loc->call_lhs ());
377
+ exprt new_state = ternary_exprt (
378
+ ID_allocate, state, lhs_address, size_evaluated, state_typet ());
379
+ dest << forall_states_expr (
380
+ loc, function_application_exprt (out_state_expr (loc), {new_state}));
381
+ return ;
369
382
}
370
- else if (function.id () == ID_symbol)
371
- {
372
- auto identifier = to_symbol_expr (function).get_identifier ();
373
383
374
- // malloc is special-cased
375
- if (identifier == " malloc" )
376
- {
377
- auto state = state_expr ();
378
- PRECONDITION (loc->call_arguments ().size () == 1 );
379
- auto size_evaluated = evaluate_expr (loc, state, loc->call_arguments ()[0 ]);
384
+ // Do we have a function body?
385
+ auto f = goto_functions.function_map .find (identifier);
386
+ if (f == goto_functions.function_map .end ())
387
+ DATA_INVARIANT (false , " failed find function in function_map" );
380
388
381
- auto lhs_address = address_rec (loc, state, loc->call_lhs ());
382
- exprt new_state = ternary_exprt (
383
- ID_allocate, state, lhs_address, size_evaluated, state_typet ());
384
- dest << forall_states_expr (
385
- loc, function_application_exprt (out_state_expr (loc), {new_state}));
389
+ if (!f->second .body_available ())
390
+ {
391
+ // no function body -- do LHS assignment nondeterministically, if any
392
+ if (loc->call_lhs ().is_not_nil ())
393
+ {
394
+ auto rhs = side_effect_expr_nondett (
395
+ loc->call_lhs ().type (), loc->source_location ());
396
+ dest << assignment_constraint (loc, loc->call_lhs (), std::move (rhs));
386
397
}
387
398
else
388
399
{
389
- // Do we have a function body?
390
- auto f = goto_functions.function_map .find (identifier);
391
- if (f == goto_functions.function_map .end ())
392
- DATA_INVARIANT (false , " failed find function in function_map" );
393
- if (f->second .body_available ())
394
- {
395
- // Evaluate the arguments of the call in the 'in state'
396
- multi_ary_exprt arguments_evaluated (ID_tuple, {}, typet (ID_tuple));
397
- arguments_evaluated.reserve_operands (loc->call_arguments ().size ());
400
+ // This is a SKIP.
401
+ dest << equal_exprt (out_state_expr (loc), in_state_expr (loc));
402
+ }
403
+ }
398
404
399
- const auto in_state = in_state_expr (loc);
405
+ // Evaluate the arguments of the call in the 'in state'
406
+ multi_ary_exprt arguments_evaluated (ID_tuple, {}, typet (ID_tuple));
407
+ arguments_evaluated.reserve_operands (loc->call_arguments ().size ());
400
408
401
- for (auto &argument : loc->call_arguments ())
402
- arguments_evaluated.add_to_operands (
403
- evaluate_expr (loc, in_state, argument));
409
+ const auto in_state = in_state_expr (loc);
404
410
405
- auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
411
+ for (auto &argument : loc->call_arguments ())
412
+ arguments_evaluated.add_to_operands (
413
+ evaluate_expr (loc, in_state, argument));
406
414
407
- dest << forall_states_expr (
408
- loc,
409
- function_application_exprt (function_entry_state, {state_expr ()}));
410
-
411
- // Function return state (suffix PostReturn).
412
- // This is the state after exiting the function but prior to
413
- // assigning the LHS of the function call.
414
- auto return_state = state_expr_with_suffix (loc, " PostReturn" );
415
-
416
- /*
417
- constraints.push_back(
418
- multi_ary_exprt(
419
- ID_goto_contract,
420
- {loc->call_function(), in_state, return_state, arguments_evaluated},
421
- bool_typet()));
422
- */
423
-
424
- // assign the return value, if any
425
- if (loc->call_lhs ().is_not_nil ())
426
- {
427
- exprt equality_rhs = return_state;
415
+ auto function_entry_state = state_expr_with_suffix (loc, " Entry" );
428
416
429
- /*
430
- auto &return_type = loc->call_lhs().type();
431
- auto rhs_evaluated =
432
- evaluate_expr(
433
- loc,
434
- return_state,
435
- symbol_exprt("return_value", return_type));
417
+ dest << forall_states_expr (
418
+ loc,
419
+ function_application_exprt (function_entry_state, {state_expr ()}));
436
420
437
- multi_ary_exprt designator(ID_designator, { loc->call_lhs() }, typet());
421
+ // Function return state (suffix PostReturn).
422
+ // This is the state after exiting the function but prior to
423
+ // assigning the LHS of the function call.
424
+ auto return_state = state_expr_with_suffix (loc, " PostReturn" );
438
425
439
- auto lhs = out_state_expr(source);
426
+ /*
427
+ constraints.push_back(
428
+ multi_ary_exprt(
429
+ ID_goto_contract,
430
+ {loc->call_function(), in_state, return_state, arguments_evaluated},
431
+ bool_typet()));
432
+ */
440
433
441
- auto rhs = update_exprt(
442
- return_state,
443
- designator,
444
- rhs_evaluated) ;
434
+ // assign the return value, if any
435
+ if (loc-> call_lhs (). is_not_nil ())
436
+ {
437
+ exprt equality_rhs = return_state ;
445
438
446
- // 'out state' equality
447
- constraints.push_back(equal_exprt(lhs, rhs));
448
- */
449
- }
450
- else
451
- {
452
- // 'out state' equality
453
- dest << equal_exprt (out_state_expr (loc), return_state);
454
- }
455
- }
456
- else
457
- {
458
- // no function body -- do LHS assignment nondeterministically, if any
459
- if (loc->call_lhs ().is_not_nil ())
460
- {
461
- auto rhs = side_effect_expr_nondett (
462
- loc->call_lhs ().type (), loc->source_location ());
463
- dest << assignment_constraint (loc, loc->call_lhs (), std::move (rhs));
464
- }
465
- else
466
- {
467
- // This is a SKIP.
468
- dest << equal_exprt (out_state_expr (loc), in_state_expr (loc));
469
- }
470
- }
471
- }
439
+ /*
440
+ auto &return_type = loc->call_lhs().type();
441
+ auto rhs_evaluated =
442
+ evaluate_expr(
443
+ loc,
444
+ return_state,
445
+ symbol_exprt("return_value", return_type));
446
+
447
+ multi_ary_exprt designator(ID_designator, { loc->call_lhs() }, typet());
448
+
449
+ auto lhs = out_state_expr(source);
450
+
451
+ auto rhs = update_exprt(
452
+ return_state,
453
+ designator,
454
+ rhs_evaluated);
455
+
456
+ // 'out state' equality
457
+ constraints.push_back(equal_exprt(lhs, rhs));
458
+ */
459
+ }
460
+ /*
461
+ else
462
+ {
463
+ // 'out state' equality
464
+ dest << equal_exprt(out_state_expr(loc), return_state);
465
+ }
466
+ */
467
+ }
468
+
469
+ void state_encodingt::function_call (
470
+ const goto_functionst &goto_functions,
471
+ goto_programt::const_targett loc,
472
+ encoding_targett &dest)
473
+ {
474
+ // Function pointer?
475
+ const auto &function = loc->call_function ();
476
+ if (function.id () == ID_dereference)
477
+ {
478
+ // TBD.
479
+ throw incorrect_goto_program_exceptiont (
480
+ " can't do function pointers" , loc->source_location ());
481
+ }
482
+ else if (function.id () == ID_symbol)
483
+ {
484
+ function_call_symbol (goto_functions, loc, dest);
472
485
}
473
486
else
474
487
{
0 commit comments