Skip to content

Commit bce472f

Browse files
Merge pull request diffblue#7699 from remi-delmas-3000/contracts-check-side-effects-in-assigns-frees-clauses
CONTRACTS: re-enable side effect checking in assigns/frees clauses (HOTFIX)
2 parents fa60087 + 445527d commit bce472f

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <stdbool.h>
2+
#include <stdlib.h>
3+
4+
// A function defining an assignable target
5+
void foo_assigns(char *ptr, const size_t size)
6+
{
7+
__CPROVER_object_upto(ptr, size);
8+
9+
// an unauthorized side effect that must be detected
10+
if(ptr && size > 0)
11+
ptr[0] = 0;
12+
}
13+
14+
// A function defining an freeable target
15+
void foo_frees(char *ptr, const size_t size)
16+
{
17+
__CPROVER_freeable(ptr);
18+
19+
// an unauthorized side effect that must be detected
20+
if(ptr && size > 0)
21+
ptr[0] = 0;
22+
}
23+
24+
char *foo(char *ptr, const size_t size, const size_t new_size)
25+
// clang-format off
26+
__CPROVER_requires(__CPROVER_is_fresh(ptr, size))
27+
__CPROVER_assigns(foo_assigns(ptr, size))
28+
__CPROVER_frees(foo_frees(ptr, size))
29+
// clang-format on
30+
{
31+
if(ptr && new_size > size)
32+
{
33+
free(ptr);
34+
ptr = malloc(new_size);
35+
return ptr;
36+
}
37+
else
38+
{
39+
if(size > 0)
40+
{
41+
ptr[0] = 0;
42+
}
43+
return ptr;
44+
}
45+
}
46+
47+
int main()
48+
{
49+
size_t size;
50+
size_t new_size;
51+
char *ptr;
52+
ptr = foo(ptr, size, new_size);
53+
return 0;
54+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE dfcc-only
2+
main.c
3+
--dfcc main --enforce-contract foo --malloc-may-fail --malloc-fail-null
4+
^\[foo_assigns.assigns.\d+\] line \d+ Check that ptr\[\(.* int\)0\] is assignable: FAILURE$
5+
^\[foo_frees.assigns.\d+\] line \d+ Check that ptr\[\(.* int\)0\] is assignable: FAILURE$
6+
^VERIFICATION FAILED$
7+
^EXIT=10$
8+
^SIGNAL=0$
9+
--
10+
--
11+
This test checks that side effects in functions called from the assigns clause
12+
or the frees clause are detected and make the analysis fail.

src/goto-instrument/contracts/dynamic-frames/dfcc_spec_functions.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ void dfcc_spec_functionst::to_spec_assigns_function(
272272

273273
goto_model.goto_functions.update();
274274

275+
// instrument for side-effects checking
276+
std::set<irep_idt> function_pointer_contracts;
277+
instrument.instrument_function(function_id, function_pointer_contracts);
278+
INVARIANT(
279+
function_pointer_contracts.empty(),
280+
"discovered function pointer contracts unexpectedly");
281+
275282
goto_model.goto_functions.function_map.at(function_id).make_hidden();
276283
}
277284

@@ -355,6 +362,13 @@ void dfcc_spec_functionst::to_spec_frees_function(
355362

356363
goto_model.goto_functions.update();
357364

365+
// instrument for side-effects checking
366+
std::set<irep_idt> function_pointer_contracts;
367+
instrument.instrument_function(function_id, function_pointer_contracts);
368+
INVARIANT(
369+
function_pointer_contracts.empty(),
370+
"discovered function pointer contracts unexpectedly");
371+
358372
goto_model.goto_functions.function_map.at(function_id).make_hidden();
359373
}
360374

0 commit comments

Comments
 (0)