Skip to content

Commit 2ec8f88

Browse files
author
klaas
committed
Fixes initialization for code contracts
Because code contracts should be checked in an environment constrained only by the preconditions, we want to check contracts before initializing the dead and deallocated objects --- otherwise, we fail to check the cases where a pointer argument to a function points to a dead or deallocated object but is not NULL. This commit resolves these issues by temporarily initializing dead and deallocated objects to be the same fixed object before checking contracts, and then performing the standard initialization to NULL.
1 parent 63b2af3 commit 2ec8f88

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

src/goto-instrument/code_contracts.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Date: February 2016
1313

1414
#include "code_contracts.h"
1515

16+
#include <util/arith_tools.h>
17+
#include <util/c_types.h>
18+
#include <util/expr_iterator.h>
1619
#include <util/fresh_symbol.h>
1720
#include <util/replace_symbol.h>
1821

@@ -507,6 +510,7 @@ void code_contractst::check_code_contracts()
507510
goto_functionst::function_mapt::iterator i_it=
508511
goto_functions.function_map.find(INITIALIZE_FUNCTION);
509512
assert(i_it!=goto_functions.function_map.end());
513+
goto_programt &init_function = i_it->second.body;
510514

511515
Forall_goto_functions(it, goto_functions)
512516
{
@@ -535,10 +539,52 @@ void code_contractst::check_code_contracts()
535539

536540
Forall_goto_functions(it, goto_functions)
537541
{
538-
check_contract(it->first, it->second, i_it->second.body);
542+
check_contract(it->first, it->second, init_function);
539543
}
540544

541-
remove_skip(i_it->second.body);
545+
// Partially initialize state
546+
goto_programt init_code;
547+
548+
goto_programt::targett d = init_code.add_instruction(DECL);
549+
d->function = i_it->first;
550+
// TODO add source location
551+
// d->source_location =
552+
553+
symbol_exprt tmp_var =
554+
new_tmp_symbol(void_typet(), d->source_location).symbol_expr();
555+
d->code = code_declt(tmp_var);
556+
d->code.add_source_location() = d->source_location;
557+
558+
{
559+
const symbol_exprt &deallocated_expr =
560+
ns.lookup(CPROVER_PREFIX "deallocated").symbol_expr();
561+
562+
goto_programt::targett a = init_code.add_instruction(ASSIGN);
563+
a->function = i_it->first;
564+
// TODO add source location
565+
// a->source_location =
566+
address_of_exprt rhs(tmp_var, to_pointer_type(deallocated_expr.type()));
567+
a->code = code_assignt(deallocated_expr, rhs);
568+
a->code.add_source_location() = a->source_location;
569+
}
570+
571+
{
572+
const symbol_exprt &dead_expr =
573+
ns.lookup(CPROVER_PREFIX "dead_object").symbol_expr();
574+
575+
goto_programt::targett a = init_code.add_instruction(ASSIGN);
576+
a->function = i_it->first;
577+
// TODO add source location
578+
// a->source_location =
579+
address_of_exprt rhs(tmp_var, to_pointer_type(dead_expr.type()));
580+
a->code = code_assignt(dead_expr, rhs);
581+
a->code.add_source_location() = a->source_location;
582+
}
583+
584+
init_function.destructive_insert(init_function.instructions.begin(),
585+
init_code);
586+
587+
remove_skip(init_function);
542588

543589
goto_functions.update();
544590
}

0 commit comments

Comments
 (0)