Skip to content

Commit f7ff4bf

Browse files
committed
Check frame conditions before __CPROVER_havoc_object
Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent c67c340 commit f7ff4bf

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int x = 0;
5+
6+
void foo(int *y) __CPROVER_assigns()
7+
{
8+
__CPROVER_havoc_object(y);
9+
x = 2;
10+
}
11+
12+
int main()
13+
{
14+
int *y = malloc(sizeof(*y));
15+
*y = 0;
16+
foo(y);
17+
assert(x == 2);
18+
return 0;
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[foo.\d+\] line \d+ Check that \*y is assignable: FAILURE$
7+
^\[foo.\d+\] line \d+ Check that x is assignable: FAILURE$
8+
^VERIFICATION FAILED$
9+
--
10+
--
11+
Checks whether contract enforcement works with __CPROVER_havoc_object.

src/goto-instrument/contracts/contracts.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ void code_contractst::instrument_call_statement(
748748
called_name =
749749
to_symbol_expr(instruction_iterator->call_function()).get_identifier();
750750
}
751-
751+
log.warning() << "called function: " << id2string(called_name)
752+
<< messaget::eom;
752753
if(called_name == "malloc")
753754
{
754755
// malloc statments return a void pointer, which is then cast and assigned
@@ -972,6 +973,23 @@ void code_contractst::check_frame_conditions(
972973
{
973974
assigns.remove_from_local_write_set(instruction_it->get_dead().symbol());
974975
}
976+
else if(
977+
instruction_it->is_other() &&
978+
instruction_it->get_other().get_statement() == ID_havoc_object)
979+
{
980+
goto_programt alias_assertion;
981+
const exprt &havoc_argument = dereference_exprt(
982+
to_typecast_expr(instruction_it->get_other().operands().front()).op());
983+
alias_assertion.add(goto_programt::make_assertion(
984+
assigns.generate_containment_check(havoc_argument),
985+
instruction_it->source_location));
986+
alias_assertion.instructions.back().source_location.set_comment(
987+
"Check that " + from_expr(ns, havoc_argument.id(), havoc_argument) +
988+
" is assignable");
989+
assigns.remove_from_local_write_set(havoc_argument);
990+
assigns.remove_from_global_write_set(havoc_argument);
991+
insert_before_swap_and_advance(program, instruction_it, alias_assertion);
992+
}
975993
}
976994
}
977995

0 commit comments

Comments
 (0)