File tree 10 files changed +82
-2
lines changed
10 files changed +82
-2
lines changed Original file line number Diff line number Diff line change @@ -59,6 +59,34 @@ for(i=0; i<100; i++)
59
59
assert(a[i]==0);
60
60
```
61
61
62
+ CPROVER also supports writing function pre and postconditions, using
63
+ the built-in functions ` __CPROVER_precondition ` and
64
+ ` __CPROVER_postcondition ` . They can be used to express intent, and at
65
+ the moment they are just transformed to assertions in the goto
66
+ program. As such, they can be used as simple assertions in
67
+ code. However, it is advised to use ` __CPROVER_precondition ` at the
68
+ beginning of a function's body, and ` __CPROVER_postcondition ` before
69
+ the exit points in a function (either the return statements, or the
70
+ end of the body if the function returns void). The following is an
71
+ example usage:
72
+
73
+ ``` C
74
+ int foo (int a, int b) {
75
+ __ CPROVER_precondition(a >= 0);
76
+ __ CPROVER_precondition(b > 0);
77
+
78
+ int rval = a / b;
79
+
80
+ __ CPROVER_postcondition(rval >= 0);
81
+ return rval;
82
+ }
83
+ ```
84
+
85
+ A future release of CPROVER will support using these pre and
86
+ postconditions to create a function contract, which can be used for
87
+ modular verification.
88
+
89
+
62
90
Future CPROVER releases will support explicit quantifiers with a syntax
63
91
that resembles Spec\#:
64
92
Original file line number Diff line number Diff line change
1
+ int func (int a )
2
+ {
3
+ __CPROVER_precondition (a > 10 , "Argument should be larger than 10" );
4
+ int rval = a - 10 ;
5
+ __CPROVER_postcondition (rval > 1 , "Return value should be positive" );
6
+ return rval ;
7
+ }
8
+
9
+ int main ()
10
+ {
11
+ int a = 11 ;
12
+ int rval = func (a );
13
+ return 0 ;
14
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+
4
+ ^EXIT=10$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION FAILED$
7
+ --
Original file line number Diff line number Diff line change
1
+ void func (int a )
2
+ {
3
+ __CPROVER_precondition (a > 10 , "Argument should be larger than 10." );
4
+ }
5
+
6
+ int main ()
7
+ {
8
+ int a = 10 ;
9
+
10
+ func (a );
11
+
12
+ return 0 ;
13
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+
4
+ ^EXIT=10$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION FAILED$
7
+ --
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ void __CPROVER_assume(__CPROVER_bool assumption);
2
2
void __VERIFIER_assume (__CPROVER_bool assumption );
3
3
void __CPROVER_assert (__CPROVER_bool assertion , const char * description );
4
4
void __CPROVER_precondition (__CPROVER_bool precondition , const char * description );
5
+ void __CPROVER_postcondition (__CPROVER_bool assertion , const char * description );
5
6
void __CPROVER_havoc_object (void * );
6
7
__CPROVER_bool __CPROVER_equal ();
7
8
__CPROVER_bool __CPROVER_same_object (const void * , const void * );
Original file line number Diff line number Diff line change @@ -20,6 +20,7 @@ extern const void *__CPROVER_memory_leak;
20
20
void __CPROVER_assume (__CPROVER_bool assumption ) __attribute__((__noreturn__ ));
21
21
void __CPROVER_assert (__CPROVER_bool assertion , const char * description );
22
22
void __CPROVER_precondition (__CPROVER_bool assertion , const char * description );
23
+ void __CPROVER_postcondition (__CPROVER_bool assertion , const char * description );
23
24
24
25
__CPROVER_bool __CPROVER_is_zero_string (const void * );
25
26
__CPROVER_size_t __CPROVER_zero_string_length (const void * );
Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ extern const void *__CPROVER_memory_leak;
21
21
void __CPROVER_assume (__CPROVER_bool assumption ) __attribute__((__noreturn__ ));
22
22
void __CPROVER_assert (__CPROVER_bool assertion , const char * description );
23
23
void __CPROVER_precondition (__CPROVER_bool assertion , const char * description );
24
+ void __CPROVER_postcondition (__CPROVER_bool assertion , const char * description );
24
25
25
26
void __CPROVER_input (const char * description , ...);
26
27
void __CPROVER_output (const char * description , ...);
Original file line number Diff line number Diff line change @@ -735,8 +735,10 @@ void goto_convertt::do_function_call_symbol(
735
735
throw 0 ;
736
736
}
737
737
}
738
- else if (identifier==CPROVER_PREFIX " assert" ||
739
- identifier==CPROVER_PREFIX " precondition" )
738
+ else if (
739
+ identifier == CPROVER_PREFIX " assert" ||
740
+ identifier == CPROVER_PREFIX " precondition" ||
741
+ identifier == CPROVER_PREFIX " postcondition" )
740
742
{
741
743
if (arguments.size ()!=2 )
742
744
{
@@ -747,6 +749,7 @@ void goto_convertt::do_function_call_symbol(
747
749
748
750
bool is_precondition=
749
751
identifier==CPROVER_PREFIX " precondition" ;
752
+ bool is_postcondition = identifier == CPROVER_PREFIX " postcondition" ;
750
753
751
754
const irep_idt description=
752
755
get_string_constant (arguments[1 ]);
@@ -760,6 +763,10 @@ void goto_convertt::do_function_call_symbol(
760
763
{
761
764
t->source_location .set_property_class (ID_precondition);
762
765
}
766
+ else if (is_postcondition)
767
+ {
768
+ t->source_location .set_property_class (ID_postcondition);
769
+ }
763
770
else
764
771
{
765
772
t->source_location .set (
Original file line number Diff line number Diff line change @@ -89,6 +89,7 @@ IREP_ID_ONE(assume)
89
89
IREP_ID_ONE(assert)
90
90
IREP_ID_ONE(assertion)
91
91
IREP_ID_ONE(precondition)
92
+ IREP_ID_ONE(postcondition)
92
93
IREP_ID_ONE(precondition_instance)
93
94
IREP_ID_ONE(goto)
94
95
IREP_ID_ONE(gcc_computed_goto)
You can’t perform that action at this time.
0 commit comments