File tree Expand file tree Collapse file tree 3 files changed +80
-0
lines changed
regression/contracts-dfcc/assigns-frees-clauses-check-side-effects
src/goto-instrument/contracts/dynamic-frames Expand file tree Collapse file tree 3 files changed +80
-0
lines changed Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change
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.
Original file line number Diff line number Diff line change @@ -272,6 +272,13 @@ void dfcc_spec_functionst::to_spec_assigns_function(
272
272
273
273
goto_model.goto_functions .update ();
274
274
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
+
275
282
goto_model.goto_functions .function_map .at (function_id).make_hidden ();
276
283
}
277
284
@@ -355,6 +362,13 @@ void dfcc_spec_functionst::to_spec_frees_function(
355
362
356
363
goto_model.goto_functions .update ();
357
364
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
+
358
372
goto_model.goto_functions .function_map .at (function_id).make_hidden ();
359
373
}
360
374
You can’t perform that action at this time.
0 commit comments