Reputation: 63
Trying to analyze some C programs with z3 in python, and got into trouble with pointers. I am working with terms like:
float * buffer = (float*)malloc(5*sizeof(float))
I interpret buffer as a BitVec(32)
value
so *buffer
should be Real()
.
That should be ok, but what assertions should I write for the terms like
*(buffer+3) or *(buffer+i)
How should be the assertions written if I am indexing out like
*(buffer-1) or *(buffer+10)
Upvotes: 0
Views: 421
Reputation: 12852
One solution is to encode the program heap as a map H
from locations to values. In Z3, the array theory can be used to encode maps.
Pointers/addresses are integer locations, integer arithmetic encodes pointer arithmetic; this would allow constraints such as H(buffer + i) > 0
in your encoding. If you were to encode an OO-language, you could use the pair (receiver, field name) to encode addresses. E.g. H(r, f) > 0
would correspond to r.f > 0
. Note that this map encoding naturally accounts for aliasing, e.g. if buffer1 == buffer2
and i == 3
then H(buffer1 + i) == H(buffer + 3)
.
See the paper Heaps and Data Structures: A Challenge for Automated Provers for an interesting comparison of map-based heap encodings.
Map-based encodings are typically used by tools based on verification condition, such as Frama-C, Dafny and Boogie. Tools based on symbolic execution, such as Silicon (which is part of the Viper verification infrastructure) and VeriFast typically use a different encoding; see, e.g. Heap-Dependent expressions in separation logic .
Upvotes: 4