Skip to content

Commit 6b37803

Browse files
committed
Adds regression test to cover code contracts support
Code contracts now supports assigns clause with structs and array ranges. It also supports contracts specified across multiple source files. So, we added regression tests to cover these capabilites. Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent a0437ab commit 6b37803

File tree

31 files changed

+448
-20
lines changed

31 files changed

+448
-20
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
void f1(int a[], int len) __CPROVER_assigns(a)
2+
{
3+
int b[10];
4+
a = b;
5+
int *indr = a + 2;
6+
*indr = 5;
7+
}
8+
9+
int main()
10+
{
11+
int arr[10];
12+
f1(arr, 10);
13+
14+
return 0;
15+
}
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 their assigns clause behavior when it reasons (indirectly)
10+
over a freshly-allocated variable.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <assert.h>
2+
3+
int idx = 4;
4+
5+
int nextIdx() __CPROVER_assigns(idx)
6+
{
7+
idx++;
8+
return idx;
9+
}
10+
11+
void f1(int a[], int len)
12+
{
13+
a[nextIdx()] = 5;
14+
}
15+
16+
int main()
17+
{
18+
int arr[10];
19+
f1(arr, 10);
20+
21+
assert(idx == 5);
22+
23+
return 0;
24+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether the instrumentation process does not duplicate function calls
10+
used as part of array-index operations, i.e., if a function call is used in
11+
the computation of the index of an array assignment, then instrumenting that
12+
statement with an assigns clause will not result in multiple function calls.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
void assign_out_under(int a[], int len) __CPROVER_assigns(a)
2+
{
3+
a[1] = 5;
4+
}
5+
6+
int main()
7+
{
8+
int arr[10];
9+
assign_out_under(arr, 10);
10+
11+
return 0;
12+
}
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=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
--
9+
Checks whether verification fails when an array is assigned at an index
10+
below its lower bound.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
void assigns_single(int a[], int len) __CPROVER_assigns(a)
2+
{
3+
}
4+
5+
void assigns_range(int a[], int len) __CPROVER_assigns(a)
6+
{
7+
}
8+
9+
void assigns_big_range(int a[], int len) __CPROVER_assigns(a)
10+
{
11+
assigns_single(a, len);
12+
assigns_range(a, len);
13+
}
14+
15+
int main()
16+
{
17+
int arr[10];
18+
assigns_big_range(arr, 10);
19+
20+
return 0;
21+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether verification succeeds when an array is assigned through
10+
calls to functions with array assigns clauses which are compatible with
11+
that of the caller.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
void assigns_ptr(int *x) __CPROVER_assigns(*x)
2+
{
3+
*x = 200;
4+
}
5+
6+
void assigns_range(int a[], int len) __CPROVER_assigns(a)
7+
{
8+
int *ptr = &(a[7]);
9+
assigns_ptr(ptr);
10+
}
11+
12+
int main()
13+
{
14+
int arr[10];
15+
assigns_range(arr, 10);
16+
17+
return 0;
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
--
9+
Checks whether verification fails when an array is assigned via a
10+
function call which assigns a pointer to an element out of the
11+
allowable range.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
void f1(int *x1, int *y1, int *z1);
2+
3+
void f2(int *x2, int *y2, int *z2);
4+
5+
void f3(int *x3, int *y3, int *z3);
6+
7+
void f1(int *x1, int *y1, int *z1) __CPROVER_assigns(*x1, *y1, *z1)
8+
{
9+
f2(x1, y1, z1);
10+
}
11+
12+
void f2(int *x2, int *y2, int *z2) __CPROVER_assigns(*x2, *y2, *z2)
13+
{
14+
f3(x2, y2, z2);
15+
}
16+
17+
void f3(int *x3, int *y3, int *z3) __CPROVER_assigns(*y3, *z3)
18+
{
19+
*x3 = *x3 + 1;
20+
*y3 = *y3 + 1;
21+
*z3 = *z3 + 1;
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "header.h"
2+
3+
int main()
4+
{
5+
int p = 1;
6+
int q = 2;
7+
int r = 3;
8+
f1(&p, &q, &r);
9+
10+
return 0;
11+
}
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=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
--
9+
This test replicates the behavior of assigns_enforce_04, but separates
10+
the function headers and contracts into a separate file header.h.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdlib.h>
2+
3+
struct pair
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
struct pair_of_pairs
10+
{
11+
struct pair p1;
12+
struct pair p2;
13+
};
14+
15+
int f1(int *a, struct pair *b);
16+
17+
int f1(int *a, struct pair *b) __CPROVER_assigns(*a)
18+
{
19+
struct pair_of_pairs *pop =
20+
(struct pair_of_pairs *)malloc(sizeof(struct pair_of_pairs));
21+
b = &(pop->p2);
22+
b->y = 5;
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "header.h"
2+
3+
int main()
4+
{
5+
int m = 4;
6+
struct pair n;
7+
f1(&m, &n);
8+
9+
return 0;
10+
}
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+
This test replicates the behavior of assigns_enforce_structs_03, but separates
10+
the structs, function headers, and contracts into a separate file header.h.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdlib.h>
2+
3+
struct pair
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
int f1(int *a, int *b) __CPROVER_assigns(*a)
10+
{
11+
struct pair *p = (struct pair *)malloc(sizeof(struct pair));
12+
b = &(p->y);
13+
*b = 5;
14+
}
15+
16+
int main()
17+
{
18+
int m = 4;
19+
int n = 3;
20+
f1(&m, &n);
21+
22+
return 0;
23+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether verification succeeds when a formal parameter pointer outside
10+
of the assigns clause is instead pointed at the location of a member of a
11+
freshly allocated struct before being assigned.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <stdlib.h>
2+
3+
struct pair
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
struct pair_of_pairs
10+
{
11+
struct pair p1;
12+
struct pair p2;
13+
};
14+
15+
int f1(int *a, int *b) __CPROVER_assigns(*a)
16+
{
17+
struct pair_of_pairs *pop =
18+
(struct pair_of_pairs *)malloc(sizeof(struct pair_of_pairs));
19+
b = &(pop->p2.x);
20+
*b = 5;
21+
}
22+
23+
int main()
24+
{
25+
int m = 4;
26+
int n = 3;
27+
f1(&m, &n);
28+
29+
return 0;
30+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether verification succeeds when a formal parameter pointer outside
10+
of the assigns clause is assigned after being pointed at the location of a
11+
member of a sub-struct of a freshly allocated struct before being assigned.
12+
This is meant to show that all contained members (and their contained members)
13+
of assignable structs are valid to assign.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <stdlib.h>
2+
3+
struct pair
4+
{
5+
int x;
6+
int y;
7+
};
8+
9+
struct pair_of_pairs
10+
{
11+
struct pair p1;
12+
struct pair p2;
13+
};
14+
15+
int f1(int *a, struct pair *b) __CPROVER_assigns(*a)
16+
{
17+
struct pair_of_pairs *pop =
18+
(struct pair_of_pairs *)malloc(sizeof(struct pair_of_pairs));
19+
b = &(pop->p2);
20+
b->y = 5;
21+
}
22+
23+
int main()
24+
{
25+
int m = 4;
26+
struct pair n;
27+
f1(&m, &n);
28+
29+
return 0;
30+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether verification succeeds when a member of formal parameter
10+
(with type of pointer to struct) outside of the assigns clause is assigned
11+
after being pointed at the location of a member sub-struct of a freshly
12+
allocated struct before being assigned. This is meant to show that all
13+
contained members (and their contained members) of assignable structs
14+
are valid to assign.

0 commit comments

Comments
 (0)