File tree Expand file tree Collapse file tree 16 files changed +192
-21
lines changed
history-pointer-replace-03
loop-history-variables-01
loop-history-variables-02
loop-history-variables-03
goto-instrument/contracts Expand file tree Collapse file tree 16 files changed +192
-21
lines changed Original file line number Diff line number Diff line change 4
4
^EXIT=(1|64)$
5
5
^SIGNAL=0$
6
6
^CONVERSION ERROR$
7
- error: __CPROVER_old expressions are not allowed in __CPROVER_requires clauses
7
+ error: __CPROVER_old expressions are not allowed
8
8
--
9
9
--
10
10
Verification:
Original file line number Diff line number Diff line change
1
+ #include <assert.h>
2
+
3
+ typedef struct
4
+ {
5
+ int * n ;
6
+ } s ;
7
+
8
+ void main ()
9
+ {
10
+ int * x1 , y1 , z1 ;
11
+ * x1 = & z1 ;
12
+
13
+ while (y1 > 0 )
14
+ __CPROVER_loop_invariant (* x1 == __CPROVER_loop_entry (* x1 ))
15
+ {
16
+ -- y1 ;
17
+ * x1 = * x1 + 1 ;
18
+ * x1 = * x1 - 1 ;
19
+ }
20
+ assert (* x1 == & z1 );
21
+
22
+ int x2 , y2 , z2 ;
23
+ x2 = z2 ;
24
+
25
+ while (y2 > 0 )
26
+ __CPROVER_loop_invariant (x2 == __CPROVER_loop_entry (x2 ))
27
+ {
28
+ -- y2 ;
29
+ x2 = x2 + 1 ;
30
+ x2 = x2 - 1 ;
31
+ }
32
+ assert (x2 == z2 );
33
+
34
+ int y3 ;
35
+ s * s1 , * s2 ;
36
+ s2 -> n = malloc (sizeof (int ));
37
+ s1 -> n = s2 -> n ;
38
+
39
+ while (y3 > 0 )
40
+ __CPROVER_loop_invariant (* s1 == __CPROVER_loop_entry (* s1 ))
41
+ {
42
+ -- y3 ;
43
+ s1 -> n = s1 -> n + 1 ;
44
+ s1 -> n = s1 -> n - 1 ;
45
+ }
46
+
47
+ assert (s1 -> n == s2 -> n );
48
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --apply-loop-contracts
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^\[main.1\] .* Check loop invariant before entry: SUCCESS$
7
+ ^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
8
+ ^\[main.assertion.1\] .* assertion \*x1 == &z1: SUCCESS$
9
+ ^\[main.3\] .* Check loop invariant before entry: SUCCESS$
10
+ ^\[main.4\] .* Check that loop invariant is preserved: SUCCESS$
11
+ ^\[main.assertion.2\] .* assertion x2 == z2: SUCCESS$
12
+ ^\[main.5\] .* Check loop invariant before entry: SUCCESS$
13
+ ^\[main.6\] .* Check that loop invariant is preserved: SUCCESS$
14
+ ^\[main.assertion.3\] .* assertion s1->n == s2->n: SUCCESS$
15
+ ^VERIFICATION SUCCESSFUL$
16
+ --
17
+ --
18
+ This test checks that __CPROVER_loop_entry is supported.
Original file line number Diff line number Diff line change
1
+ #include <assert.h>
2
+
3
+ void main ()
4
+ {
5
+ int * x , y , z ;
6
+
7
+ * x = & z ;
8
+
9
+ while (y > 0 )
10
+ __CPROVER_loop_invariant (* x == __CPROVER_old (* x ))
11
+ {
12
+ -- y ;
13
+ * x = * x + 1 ;
14
+ * x = * x - 1 ;
15
+ }
16
+ assert (* x == & z );
17
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --apply-loop-contracts
4
+ ^CONVERSION ERROR$
5
+ ^EXIT=1$
6
+ ^SIGNAL=0$
7
+ --
8
+ --
9
+ This test ensures that __CPROVER_old cannot be used for loop contracts.
Original file line number Diff line number Diff line change
1
+ void foo (int * x ) __CPROVER_assigns (* x )
2
+ __CPROVER_ensures (* x == __CPROVER_loop_entry (* x ) + 5 )
3
+ {
4
+ * x = * x + 5 ;
5
+ }
6
+
7
+ int main ()
8
+ {
9
+ int n ;
10
+ foo (& n );
11
+
12
+ return 0 ;
13
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+ --enforce-all-contracts
4
+ ^CONVERSION ERROR$
5
+ ^EXIT=1$
6
+ ^SIGNAL=0$
7
+ --
8
+ --
9
+ This test ensures that __CPROVER_loop_entry cannot be
10
+ used for function contracts.
Original file line number Diff line number Diff line change @@ -202,10 +202,11 @@ inline side_effect_expr_overflowt &to_side_effect_expr_overflow(exprt &expr)
202
202
203
203
// / \brief A class for an expression that indicates the pre-function-call
204
204
// / value of an expression passed as a parameter to a function
205
- class old_exprt : public unary_exprt
205
+ class history_exprt : public unary_exprt
206
206
{
207
207
public:
208
- explicit old_exprt (exprt variable) : unary_exprt(ID_old, std::move(variable))
208
+ explicit history_exprt (exprt variable, const irep_idt &id)
209
+ : unary_exprt(id, std::move(variable))
209
210
{
210
211
}
211
212
@@ -215,10 +216,12 @@ class old_exprt : public unary_exprt
215
216
}
216
217
};
217
218
218
- inline const old_exprt &to_old_expr (const exprt &expr)
219
+ inline const history_exprt &
220
+ to_history_expr (const exprt &expr, const irep_idt &id)
219
221
{
220
- PRECONDITION (expr.id () == ID_old);
221
- auto &ret = static_cast <const old_exprt &>(expr);
222
+ PRECONDITION (id == ID_old || id == ID_loop_entry);
223
+ PRECONDITION (expr.id () == id);
224
+ auto &ret = static_cast <const history_exprt &>(expr);
222
225
validate_expr (ret);
223
226
return ret;
224
227
}
Original file line number Diff line number Diff line change @@ -731,6 +731,7 @@ void c_typecheck_baset::typecheck_declaration(
731
731
typecheck_expr (requires );
732
732
implicit_typecast_bool (requires );
733
733
disallow_history_variables (requires );
734
+ disallow_loop_history_variables (requires );
734
735
}
735
736
}
736
737
@@ -751,6 +752,7 @@ void c_typecheck_baset::typecheck_declaration(
751
752
{
752
753
typecheck_expr (ensures);
753
754
implicit_typecast_bool (ensures);
755
+ disallow_loop_history_variables (ensures);
754
756
}
755
757
756
758
if (return_type.id () != ID_empty)
Original file line number Diff line number Diff line change @@ -207,6 +207,7 @@ class c_typecheck_baset:
207
207
virtual exprt
208
208
typecheck_shuffle_vector (const side_effect_expr_function_callt &expr);
209
209
void disallow_history_variables (const exprt &) const ;
210
+ void disallow_loop_history_variables (const exprt &) const ;
210
211
211
212
virtual void make_index_type (exprt &expr);
212
213
virtual void make_constant (exprt &expr);
You can’t perform that action at this time.
0 commit comments