@@ -17,6 +17,7 @@ Date: February 2016
1717
1818#include < analyses/local_may_alias.h>
1919
20+ #include < goto-programs/goto_convert_class.h>
2021#include < goto-programs/remove_skip.h>
2122
2223#include < linking/static_lifetime_init.h>
@@ -157,6 +158,15 @@ static void check_apply_invariants(
157158 loop_end->set_condition (boolean_negate (loop_end->get_condition ()));
158159}
159160
161+ void code_contractst::convert_to_goto (
162+ const codet &code,
163+ const irep_idt &mode,
164+ goto_programt &program)
165+ {
166+ goto_convertt converter (symbol_table, log.get_message_handler ());
167+ converter.goto_convert (code, program, mode);
168+ }
169+
160170bool code_contractst::has_contract (const irep_idt fun_name)
161171{
162172 const symbolt &function_symbol = ns.lookup (fun_name);
@@ -327,11 +337,14 @@ bool code_contractst::apply_function_contract(
327337 // Insert assertion of the precondition immediately before the call site.
328338 if (requires .is_not_nil ())
329339 {
330- goto_programt::instructiont a =
331- goto_programt::make_assertion (requires , target->source_location );
332-
333- goto_program.insert_before_swap (target, a);
334- ++target;
340+ goto_programt assertion;
341+ convert_to_goto (
342+ code_assertt (requires ),
343+ symbol_table.lookup_ref (function).mode ,
344+ assertion);
345+ auto lines_to_iterate = assertion.instructions .size ();
346+ goto_program.insert_before_swap (target, assertion);
347+ std::advance (target, lines_to_iterate);
335348 }
336349
337350 // Create a series of non-deterministic assignments to havoc the variables
@@ -353,12 +366,16 @@ bool code_contractst::apply_function_contract(
353366 // function call with a SKIP statement.
354367 if (ensures.is_not_nil ())
355368 {
356- *target = goto_programt::make_assumption (ensures, target->source_location );
357- }
358- else
359- {
360- *target = goto_programt::make_skip ();
369+ goto_programt assumption;
370+ convert_to_goto (
371+ code_assumet (ensures),
372+ symbol_table.lookup_ref (function).mode ,
373+ assumption);
374+ auto lines_to_iterate = assumption.instructions .size ();
375+ goto_program.insert_before_swap (target, assumption);
376+ std::advance (target, lines_to_iterate);
361377 }
378+ *target = goto_programt::make_skip ();
362379
363380 // Add this function to the set of replaced functions.
364381 summarized.insert (function);
@@ -419,14 +436,6 @@ void code_contractst::instrument_assign_statement(
419436
420437 const exprt &lhs = instruction_iterator->get_assign ().lhs ();
421438
422- if (
423- lhs.id () == ID_symbol &&
424- freely_assignable_symbols.find (to_symbol_expr (lhs).get_identifier ()) !=
425- freely_assignable_symbols.end ())
426- {
427- return ;
428- }
429-
430439 goto_programt alias_assertion;
431440 alias_assertion.add (goto_programt::make_assertion (
432441 assigns_clause.alias_expression (lhs),
@@ -838,7 +847,6 @@ void code_contractst::add_contract_check(
838847 {
839848 PRECONDITION (!parameter.empty ());
840849 const symbolt ¶meter_symbol = ns.lookup (parameter);
841-
842850 symbol_exprt p = new_tmp_symbol (
843851 parameter_symbol.type ,
844852 skip->source_location ,
@@ -867,8 +875,10 @@ void code_contractst::add_contract_check(
867875 exprt requires_cond = requires ;
868876 replace (requires_cond);
869877
870- check.add (goto_programt::make_assumption (
871- requires_cond, requires .source_location ()));
878+ goto_programt assumption;
879+ convert_to_goto (
880+ code_assumet (requires_cond), function_symbol.mode , assumption);
881+ check.destructive_append (assumption);
872882 }
873883
874884 // ret=mangled_fun(parameter1, ...)
@@ -881,8 +891,10 @@ void code_contractst::add_contract_check(
881891 // assert(ensures)
882892 if (ensures.is_not_nil ())
883893 {
884- check.add (
885- goto_programt::make_assertion (ensures_cond, ensures.source_location ()));
894+ goto_programt assertion;
895+ convert_to_goto (
896+ code_assertt (ensures_cond), function_symbol.mode , assertion);
897+ check.destructive_append (assertion);
886898 }
887899
888900 if (code_type.return_type () != empty_typet ())
@@ -921,8 +933,6 @@ bool code_contractst::replace_calls(
921933 {
922934 const code_function_callt &call = ins->get_function_call ();
923935
924- PRECONDITION (call.function ().id () != ID_dereference);
925-
926936 if (call.function ().id () != ID_symbol)
927937 continue ;
928938
0 commit comments