Skip to content

Commit d508a3a

Browse files
committed
Skip checking frame conditions for local variables
It avoids unnecessary assertions (improving performance) and it prevents cases where memory primitives are invoked with dead objects. Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent 61fd24d commit d508a3a

File tree

11 files changed

+41
-32
lines changed

11 files changed

+41
-32
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
void foo(int *xp) __CPROVER_assigns(*xp)
2+
{
3+
{
4+
int y;
5+
y = 2;
6+
}
7+
int z = 3;
8+
*xp = 1;
9+
}
10+
11+
int main()
12+
{
13+
int *xp = malloc(sizeof(*xp));
14+
foo(xp);
15+
return 0;
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether verification fails when enforcing a contract
10+
for functions, without assigns clauses, that modify an input.

regression/contracts/assigns_enforce_scoping_01/test.desc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ main.c
33
--enforce-all-contracts
44
^EXIT=10$
55
^SIGNAL=0$
6-
^\[f1.\d+\] line \d+ Check that f1\$\$1\$\$1\$\$b is assignable: SUCCESS$
76
^\[f1.\d+\] line \d+ Check that \*f1\$\$1\$\$1\$\$b is assignable: SUCCESS$
87
^\[f1.\d+\] line \d+ Check that \*b is assignable: FAILURE$
98
^VERIFICATION FAILED$

regression/contracts/assigns_type_checking_valid_cases/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ main.c
55
^SIGNAL=0$
66
^\[foo1.\d+\] line \d+ Check that a is assignable: SUCCESS$
77
^\[foo10.\d+\] line \d+ Check that buffer\-\>len is assignable: SUCCESS$
8+
^\[foo10.\d+\] line \d+ Check that buffer\-\>aux\.allocated is assignable: SUCCESS$
89
^\[foo2.\d+\] line \d+ Check that b is assignable: SUCCESS$
910
^\[foo3.\d+\] line \d+ Check that b is assignable: SUCCESS$
1011
^\[foo3.\d+\] line \d+ Check that y is assignable: SUCCESS$
@@ -27,7 +28,6 @@ main.c
2728
^\[foo8.\d+\] line \d+ Check that array\[\(.* int\)7\] is assignable: SUCCESS$
2829
^\[foo8.\d+\] line \d+ Check that array\[\(.* int\)8\] is assignable: SUCCESS$
2930
^\[foo8.\d+\] line \d+ Check that array\[\(.* int\)9\] is assignable: SUCCESS$
30-
^\[foo9.\d+\] line \d+ Check that new_array is assignable: SUCCESS$
3131
^\[foo9.\d+\] line \d+ Check that array is assignable: SUCCESS$
3232
^VERIFICATION SUCCESSFUL$
3333
--

regression/contracts/function-calls-05/test.desc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ main.c
44
^EXIT=0$
55
^SIGNAL=0$
66
\[postcondition.\d+\] file main.c line \d+ Check ensures clause: SUCCESS
7-
\[foo.\d+\] line \d+ Check that sum is assignable: SUCCESS
87
\[main.assertion.\d+\] line \d+ assertion foo\(\&x, \&y\) \=\= 10: SUCCESS
98
^VERIFICATION SUCCESSFUL$
109
--

regression/contracts/history-pointer-enforce-10/test.desc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ main.c
77
^\[postcondition.\d+\] file main.c line \d+ Check ensures clause\: SUCCESS$
88
^\[postcondition.\d+\] file main.c line \d+ Check ensures clause\: SUCCESS$
99
^\[bar.\d+\] line \d+ Check that p\-\>y is assignable\: SUCCESS$
10-
^\[baz.\d+\] line \d+ Check that pp is assignable\: SUCCESS$
11-
^\[baz.\d+\] line \d+ Check that empty is assignable\: SUCCESS$
1210
^\[baz.\d+\] line \d+ Check that p is assignable\: SUCCESS$
1311
^\[baz.\d+\] line \d+ Check that p is assignable\: SUCCESS$
1412
^\[foo.\d+\] line \d+ Check that \*p\-\>y is assignable\: SUCCESS$

regression/contracts/quantifiers-exists-requires-enforce/test.desc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ main.c
44
^EXIT=0$
55
^SIGNAL=0$
66
^\[postcondition.\d+\] file main.c line \d+ Check ensures clause: SUCCESS$
7-
^\[f1.\d+\] line \d+ Check that found\_four is assignable: SUCCESS$
8-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
9-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
10-
^\[f1.\d+\] line \d+ Check that found\_four is assignable: SUCCESS$
117
^VERIFICATION SUCCESSFUL$
128
--
139
^warning: ignoring

regression/contracts/quantifiers-forall-ensures-enforce/test.desc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ main.c
44
^EXIT=0$
55
^SIGNAL=0$
66
^\[postcondition.\d+\] file main.c line \d+ Check ensures clause: SUCCESS$
7-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
8-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
97
^\[f1.\d+\] line \d+ Check that arr\[\(.*\)i\] is assignable: SUCCESS$
108
^VERIFICATION SUCCESSFUL$
119
--

regression/contracts/quantifiers-forall-requires-enforce/test.desc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ main.c
44
^EXIT=0$
55
^SIGNAL=0$
66
^\[postcondition.\d+\] file main.c line \d+ Check ensures clause: SUCCESS$
7-
^\[f1.\d+\] line \d+ Check that is\_identity is assignable: SUCCESS$
8-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
9-
^\[f1.\d+\] line \d+ Check that i is assignable: SUCCESS$
10-
^\[f1.\d+\] line \d+ Check that is\_identity is assignable: SUCCESS$
117
^VERIFICATION SUCCESSFUL$
128
--
139
^warning: ignoring

regression/contracts/test_array_memory_enforce/test.desc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ main.c
77
\[foo.\d+\] line \d+ Check that \*x is assignable: SUCCESS
88
\[foo.\d+\] line \d+ Check that x\[\(.* int\)5\] is assignable: SUCCESS
99
\[foo.\d+\] line \d+ Check that x\[\(.* int\)9\] is assignable: SUCCESS
10-
\[foo.\d+\] line \d+ Check that y is assignable: SUCCESS
1110
^VERIFICATION SUCCESSFUL$
1211
--
1312
--

src/goto-instrument/contracts/contracts.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -675,14 +675,19 @@ void code_contractst::instrument_assign_statement(
675675

676676
const exprt &lhs = instruction_iterator->assign_lhs();
677677

678-
goto_programt alias_assertion;
679-
alias_assertion.add(goto_programt::make_assertion(
680-
assigns_clause.alias_expression(lhs),
681-
instruction_iterator->source_location));
682-
alias_assertion.instructions.back().source_location.set_comment(
683-
"Check that " + from_expr(ns, lhs.id(), lhs) + " is assignable");
684-
insert_before_swap_and_advance(
685-
program, instruction_iterator, alias_assertion);
678+
if(
679+
freely_assignable_symbols.find(lhs.get(ID_identifier)) ==
680+
freely_assignable_symbols.end())
681+
{
682+
goto_programt alias_assertion;
683+
alias_assertion.add(goto_programt::make_assertion(
684+
assigns_clause.alias_expression(lhs),
685+
instruction_iterator->source_location));
686+
alias_assertion.instructions.back().source_location.set_comment(
687+
"Check that " + from_expr(ns, lhs.id(), lhs) + " is assignable");
688+
insert_before_swap_and_advance(
689+
program, instruction_iterator, alias_assertion);
690+
}
686691
}
687692

688693
void code_contractst::instrument_call_statement(
@@ -894,14 +899,6 @@ void code_contractst::check_frame_conditions(
894899

895900
// Create a list of variables that are okay to assign.
896901
std::set<irep_idt> freely_assignable_symbols;
897-
// Add all parameters that are not pointers to the freely assignable set
898-
for(code_typet::parametert param : type.parameters())
899-
{
900-
if(param.type().id() != ID_pointer)
901-
{
902-
freely_assignable_symbols.insert(param.get_identifier());
903-
}
904-
}
905902

906903
// Create temporary variables to hold the assigns
907904
// clause targets before they can be modified.
@@ -917,6 +914,7 @@ void code_contractst::check_frame_conditions(
917914
{
918915
if(instruction_it->is_decl())
919916
{
917+
// Local variables are always freely assignable
920918
freely_assignable_symbols.insert(
921919
instruction_it->get_decl().symbol().get_identifier());
922920

0 commit comments

Comments
 (0)