Skip to content

Commit c9cb4c1

Browse files
committed
Add regression tests for simplification of singleton intervals
1 parent ecd2656 commit c9cb4c1

File tree

6 files changed

+163
-0
lines changed

6 files changed

+163
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
--trace
3+
singleton_interval_simp_neg.c
4+
^VERIFICATION FAILED$
5+
^\[main\.assertion\.1\] line \d expected failure: paths where x is unbounded explored: FAILURE$
6+
^\[main\.assertion\.2\] line \d+ expected failure: paths where 0 \<= x \<= 15 explored: FAILURE$
7+
^\[main\.assertion\.3\] line \d+ expected success: paths where x \<= 15 explored: SUCCESS$
8+
y=-6 \(11111111 11111111 11111111 11111010\)
9+
x=14 \(00000000 00000000 00000000 00001110\)
10+
y=34 \(00000000 00000000 00000000 00100010\)
11+
^EXIT=10$
12+
^SIGNAL=0$
13+
--
14+
--
15+
This tests the negative case of the simplification of the singleton interval
16+
(i.e when the presented interval *is* the *not* the singleton interval -
17+
the set of possible values that the bounded variable can take has cardinality
18+
> 1).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
--trace
3+
singleton_interval_simp.c
4+
^VERIFICATION FAILED$
5+
^\[main\.assertion\.1\] line \d+ expected failure: only paths where x == 15 explored: FAILURE$
6+
^\[main\.assertion\.2\] line \d+ expected failure: only paths where x == 15 explored: FAILURE$
7+
x=15 \(00000000 00000000 00000000 00001111\)
8+
y=35 \(00000000 00000000 00000000 00100011\)
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
--
13+
This tests the positive and
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Code presented in https://github.com/diffblue/cbmc/issues/7690
2+
3+
// clang-format off
4+
5+
#include <stdlib.h>
6+
#include <stdint.h>
7+
8+
extern size_t __CPROVER_max_malloc_size;
9+
int __builtin_clzll(unsigned long long);
10+
11+
#define __nof_symex_objects \
12+
((size_t)(1ULL << __builtin_clzll(__CPROVER_max_malloc_size)))
13+
14+
typedef struct {
15+
size_t k;
16+
void **ptrs;
17+
} smap_t;
18+
19+
void smap_init(smap_t *smap, size_t k) {
20+
*smap = (smap_t){
21+
.k = k, .ptrs = __CPROVER_allocate(__nof_symex_objects * sizeof(void *), 1)};
22+
}
23+
24+
void *smap_get(smap_t *smap, void *ptr) {
25+
size_t id = __CPROVER_POINTER_OBJECT(ptr);
26+
void *sptr = smap->ptrs[id];
27+
if (!sptr) {
28+
sptr = __CPROVER_allocate(smap->k * __CPROVER_OBJECT_SIZE(ptr), 1);
29+
smap->ptrs[id] = sptr;
30+
}
31+
return sptr + smap->k * __CPROVER_POINTER_OFFSET(ptr);
32+
}
33+
34+
typedef struct {
35+
uint8_t key;
36+
uint8_t value;
37+
} stk_elem_t;
38+
39+
typedef struct {
40+
int8_t top;
41+
stk_elem_t *elems;
42+
} stk_t;
43+
44+
size_t nondet_size_t();
45+
46+
// Creates a fresh borrow stack
47+
stk_t *stk_new() {
48+
stk_t *stk = __CPROVER_allocate(sizeof(stk_t), 1);
49+
size_t stk_size = nondet_size_t();
50+
__CPROVER_assume(UINT8_MAX <= stk_size && stk_size <= UINT8_MAX);
51+
// works with
52+
// __CPROVER_assume(stk_size == UINT8_MAX);
53+
*stk = (stk_t){
54+
.top = 0,
55+
.elems = __CPROVER_allocate(sizeof(stk_elem_t) * stk_size, 1)};
56+
return stk;
57+
}
58+
59+
void stk_push(stk_t *stk, uint8_t key, uint8_t value) {
60+
assert(stk->top < UINT8_MAX);
61+
stk->elems[stk->top] = (stk_elem_t){.key = key, .value = value};
62+
stk->top++;
63+
}
64+
65+
stk_t *get_stk(smap_t *smap, void *ptr) {
66+
stk_t **stk_ptr = (stk_t **) smap_get(smap, ptr);
67+
if (!(*stk_ptr)) {
68+
*stk_ptr = stk_new();
69+
}
70+
return *stk_ptr;
71+
}
72+
73+
typedef struct {
74+
int a;
75+
int b;
76+
} my_struct_t;
77+
78+
int main() {
79+
smap_t smap;
80+
smap_init(&smap, sizeof(stk_t*));
81+
my_struct_t my_struct;
82+
stk_t *stk_a = get_stk(&smap, &(my_struct.a));
83+
stk_push(stk_a, 1, 1);
84+
stk_t *stk_b = get_stk(&smap, &(my_struct.b));
85+
assert(stk_b);
86+
stk_push(stk_b, 1, 1);
87+
}
88+
89+
// clang-format on
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Positive test for singleton interval simplification.
2+
// Notice that the sequence of the inequalities in this
3+
// expression is different to the one in
4+
// `singleton_interval_in_assume_7690.c`.
5+
6+
int main() {
7+
int x;
8+
__CPROVER_assume(x >= 15 && x <= 15);
9+
int y = x + 20;
10+
11+
__CPROVER_assert(y != 35, "expected failure: only paths where x == 15 explored");
12+
__CPROVER_assert(y == 34, "expected failure: only paths where x == 15 explored");
13+
return 0;
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Negative test for singleton interval simplification.
2+
3+
int main() {
4+
int x;
5+
int y = x + 20;
6+
7+
__CPROVER_assert(y != -6, "expected failure: paths where x is unbounded explored");
8+
9+
__CPROVER_assume(x >= 0 && x <= 15);
10+
__CPROVER_assert(y != 34, "expected failure: paths where 0 <= x <= 15 explored");
11+
12+
int z = x + 20;
13+
__CPROVER_assert(z != 36, "expected success: paths where x <= 15 explored");
14+
return 0;
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE smt-backend new-smt-backend
2+
singleton_interval_in_assume_7690.c
3+
--pointer-check
4+
^\[stk_push\.pointer_dereference\.17] line \d+ dereference failure: pointer outside object bounds in stk-\>elems\[\(signed long int\)stk-\>top\]: SUCCESS$
5+
^VERIFICATION SUCCESSFUL$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Without the singleton interval simplification implemented in
11+
https://github.com/diffblue/cbmc/pull/7761 this would fail in
12+
the (old) SMT backend in /src/solvers/smt2, because some constraints
13+
would not be propagated correctly, leaving the value of `stk_size`
14+
in `stk_new` as nondet.

0 commit comments

Comments
 (0)