Skip to content

Commit 3789670

Browse files
kroeningtautschnig
authored andcommitted
enable nondeterministic pointers
This commit enables the use of nondeterministic pointers, to allow declarative modeling of states that include pointers.
1 parent 0d62ff5 commit 3789670

16 files changed

+144
-8
lines changed

regression/cbmc/Pointer14/main.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
typedef unsigned int size_t;
2-
3-
void *malloc(size_t size);
1+
void *malloc(__CPROVER_size_t);
42

53
enum blockstate
64
{

regression/cbmc/String_Abstraction14/pass-in-implicit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
void *malloc(unsigned);
1+
void *malloc(__CPROVER_size_t);
22

33
void use_str(char *s)
44
{

regression/cbmc/String_Abstraction20/structs2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
void *malloc(unsigned);
1+
void *malloc(__CPROVER_size_t);
22

33
typedef struct str_struct
44
{

regression/cbmc/double_deref/double_deref_with_pointer_arithmetic.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CORE
22
double_deref_with_pointer_arithmetic.c
33
--show-vcc
44
^\{-[0-9]+\} derefd_pointer::derefd_pointer!0#1 = \{ symex_dynamic::dynamic_object1#3\[\[0\]\], symex_dynamic::dynamic_object1#3\[\[1\]\] \}\[cast\(mod #source_location=""\(main::argc!0@1#1, 2\), signedbv\[64\]\)\]
5-
^\{1\} \(derefd_pointer::derefd_pointer!0#1 = address_of\(symex_dynamic::dynamic_object[23]\) \? main::argc!0@1#1 = 2 : \(derefd_pointer::derefd_pointer!0#1 = address_of\(symex_dynamic::dynamic_object[23]\) \? main::argc!0@1#1 = 1 : symex::invalid_object!0#0 = main::argc!0@1#1\)\)
5+
^\{1\} \(derefd_pointer::derefd_pointer!0#1 = address_of\(symex_dynamic::dynamic_object[23]\) \? main::argc!0@1#1 = 2 : main::argc!0@1#1 = 1
66
^EXIT=0$
77
^SIGNAL=0$
88
--

regression/cbmc/double_deref/double_deref_with_pointer_arithmetic_single_alias.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
double_deref_with_pointer_arithmetic_single_alias.c
33
--show-vcc
4-
\{1\} \(derefd_pointer::derefd_pointer!0#1 = address_of\(symex_dynamic::dynamic_object2\) \? main::argc!0@1#1 = 1 : symex::invalid_object!0#0 = main::argc!0@1#1\)
4+
\{1\} main::argc!0@1#1 = 1
55
^EXIT=0$
66
^SIGNAL=0$
77
--
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
int *nondet_pointer();
2+
3+
int main()
4+
{
5+
int x = 123;
6+
int *p = &x;
7+
int *q = nondet_pointer();
8+
9+
if(p == q)
10+
__CPROVER_assert(*q == 123, "value of *q");
11+
12+
return 0;
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
nondet-pointer1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
int *nondet_pointer();
2+
3+
int main()
4+
{
5+
int x = 123, y = 456;
6+
int *px = &x;
7+
int *py = &y;
8+
int *q = nondet_pointer();
9+
10+
if(q == px || q == py)
11+
__CPROVER_assert(*q == 123 || *q == 456, "value of *q");
12+
13+
return 0;
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
nondet-pointer1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
int *nondet_pointer();
2+
3+
int main()
4+
{
5+
int some_array[10];
6+
int *p = some_array;
7+
int *q = nondet_pointer();
8+
int index;
9+
10+
__CPROVER_assume(index >= 0 && index < 10);
11+
__CPROVER_assume(q == p);
12+
13+
q[index] = 123;
14+
15+
__CPROVER_assert(some_array[index] == 123, "value of array[index]");
16+
17+
return 0;
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
nondet-pointer1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
int *nondet_pointer();
2+
3+
int main()
4+
{
5+
int some_array[10];
6+
int *p = some_array;
7+
int *q = nondet_pointer();
8+
int index;
9+
10+
__CPROVER_assume(index >= 0 && index < 10);
11+
__CPROVER_assume(q == p + index);
12+
13+
*q = 123;
14+
15+
__CPROVER_assert(some_array[index] == 123, "value of array[index]");
16+
17+
return 0;
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
nondet-pointer1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
int *nondet_pointer();
2+
3+
int main()
4+
{
5+
int some_array[10];
6+
int *p = some_array;
7+
int *q = nondet_pointer();
8+
int index;
9+
10+
__CPROVER_assume(index >= 0 && index < 10);
11+
__CPROVER_assume(__CPROVER_same_object(p, q));
12+
__CPROVER_assume(__CPROVER_POINTER_OFFSET(q) == sizeof(int) * index);
13+
14+
*q = 123;
15+
16+
__CPROVER_assert(some_array[index] == 123, "value of array[index]");
17+
18+
return 0;
19+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
nondet-pointer1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/pointer-analysis/value_set.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,23 @@ void value_sett::get_value_set_rec(
505505
else
506506
insert(dest, exprt(ID_unknown, original_type));
507507
}
508+
else if(expr.id() == ID_nondet_symbol)
509+
{
510+
if(expr.type().id() == ID_pointer)
511+
{
512+
// we'll take the union of all objects we see, with unspecified offsets
513+
values.iterate([this, &dest](const irep_idt &key, const entryt &value) {
514+
for(const auto &object : value.object_map.read())
515+
insert(dest, object.first, offsett());
516+
});
517+
518+
// we'll add null, in case it's not there yet
519+
insert(
520+
dest,
521+
exprt(ID_null_object, to_pointer_type(expr_type).subtype()),
522+
offsett());
523+
}
524+
}
508525
else if(expr.id()==ID_if)
509526
{
510527
get_value_set_rec(
@@ -984,7 +1001,6 @@ void value_sett::get_value_set_rec(
9841001
}
9851002
else
9861003
{
987-
// for example: expr.id() == ID_nondet_symbol
9881004
insert(dest, exprt(ID_unknown, original_type));
9891005
}
9901006

0 commit comments

Comments
 (0)