@@ -715,14 +715,7 @@ void code_contractst::instrument_assign_statement(
715715 assigns_clause.add_to_local_write_set (lhs);
716716 }
717717
718- goto_programt alias_assertion;
719- alias_assertion.add (goto_programt::make_assertion (
720- assigns_clause.generate_containment_check (lhs),
721- instruction_iterator->source_location ));
722- alias_assertion.instructions .back ().source_location .set_comment (
723- " Check that " + from_expr (ns, lhs.id (), lhs) + " is assignable" );
724- insert_before_swap_and_advance (
725- program, instruction_iterator, alias_assertion);
718+ add_containment_check (program, assigns_clause, instruction_iterator, lhs);
726719}
727720
728721void code_contractst::instrument_call_statement (
@@ -766,37 +759,24 @@ void code_contractst::instrument_call_statement(
766759 }
767760 else if (called_name == " free" )
768761 {
769- goto_programt alias_assertion;
770762 const exprt &lhs_dereference = dereference_exprt (
771763 to_typecast_expr (instruction_iterator->call_arguments ().front ()).op ());
772- alias_assertion.add (goto_programt::make_assertion (
773- assigns_clause.generate_containment_check (lhs_dereference),
774- instruction_iterator->source_location ));
775- alias_assertion.instructions .back ().source_location .set_comment (
776- " Check that " + from_expr (ns, lhs_dereference.id (), lhs_dereference) +
777- " is assignable" );
764+ add_containment_check (
765+ program, assigns_clause, instruction_iterator, lhs_dereference);
778766 assigns_clause.remove_from_local_write_set (lhs_dereference);
779767 assigns_clause.remove_from_global_write_set (lhs_dereference);
780- insert_before_swap_and_advance (
781- program, instruction_iterator, alias_assertion);
782768 return ;
783769 }
784770
785771 if (
786772 instruction_iterator->call_lhs ().is_not_nil () &&
787773 instruction_iterator->call_lhs ().id () == ID_symbol)
788774 {
789- const auto alias_expr = assigns_clause.generate_containment_check (
775+ add_containment_check (
776+ program,
777+ assigns_clause,
778+ instruction_iterator,
790779 instruction_iterator->call_lhs ());
791-
792- goto_programt alias_assertion;
793- alias_assertion.add (goto_programt::make_assertion (
794- alias_expr, instruction_iterator->source_location ));
795- alias_assertion.instructions .back ().source_location .set_comment (
796- " Check that " + from_expr (ns, alias_expr.id (), alias_expr) +
797- " is assignable" );
798- insert_before_swap_and_advance (
799- program, instruction_iterator, alias_assertion);
800780 }
801781
802782 const symbolt &called_symbol = ns.lookup (called_name);
@@ -972,9 +952,33 @@ void code_contractst::check_frame_conditions(
972952 {
973953 assigns.remove_from_local_write_set (instruction_it->get_dead ().symbol ());
974954 }
955+ else if (
956+ instruction_it->is_other () &&
957+ instruction_it->get_other ().get_statement () == ID_havoc_object)
958+ {
959+ const exprt &havoc_argument = dereference_exprt (
960+ to_typecast_expr (instruction_it->get_other ().operands ().front ()).op ());
961+ add_containment_check (program, assigns, instruction_it, havoc_argument);
962+ assigns.remove_from_local_write_set (havoc_argument);
963+ assigns.remove_from_global_write_set (havoc_argument);
964+ }
975965 }
976966}
977967
968+ void code_contractst::add_containment_check (
969+ goto_programt &program,
970+ const assigns_clauset &assigns,
971+ goto_programt::instructionst::iterator &instruction_it,
972+ const exprt &expr)
973+ {
974+ goto_programt assertion;
975+ assertion.add (goto_programt::make_assertion (
976+ assigns.generate_containment_check (expr), instruction_it->source_location ));
977+ assertion.instructions .back ().source_location .set_comment (
978+ " Check that " + from_expr (ns, expr.id (), expr) + " is assignable" );
979+ insert_before_swap_and_advance (program, instruction_it, assertion);
980+ }
981+
978982bool code_contractst::enforce_contract (const irep_idt &function)
979983{
980984 // Add statements to the source function
0 commit comments