We investigate the decidability of automatic program verification for programs that manipulate heaps, and in particular, decision procedures for proving memory safety for them. We extend recent work that identified a decidable subclass of uninterpreted programs to a class of alias-aware programs that can update maps. We apply this theory to develop verification algorithms for memory safetyÐ determining if a heap-manipulating program that allocates and frees memory locations and manipulates heap pointers does not dereference an unallocated memory location. We show that this problem is decidable when the initial allocated heap forms a forest data-structure and when programs are streaming-coherent, which intuitively restricts programs to make a single pass over a data-structure. Our experimental evaluation on a set of library routines that manipulate forest data-structures shows that common single-pass algorithms on data-structures often fall in the decidable class, and that our decision procedure is efficient in verifying them.Deciding Memory Safety for Single-Pass Heap-Manipulating Programs 35:3 must either be the case that x is different from z in any data-model/heap or it must be the case that x is equal to z in all data-models/heaps.We show that alias-awareness is a panacea for our problems. For alias-aware programs (programs whose executions are all alias-aware), we show we can associate terms with variables after a computation that updates maps, and further show that the notion of coherence extends naturally to programs that update maps. We then show that for coherent alias-aware programs, the verification problem becomes decidable. These results constitute the first main contribution of the paper.
Application to Verifying Memory SafetyWe then study the application of our framework to verifying memory safety. Our key observation is that for programs that manipulate forest data-structures (data-structures consisting of disjoint tree-like structures), programs are naturally alias-aware. Intuitively, when traversing forest datastructures, aliasing information is implicitly present. For instance, if x points to a location of a forest data-structure, we know that the location pointed to by x, the one pointed to by the left child x·left, and the one pointed to by the right child x·right are all different.In this paper, we define memory safety as follows. A heap-manipulating program starts with a set of allocated heap locations. During its execution, it dereferences pointers on heap locations, and allocates and frees locations. A program is memory safe if it never dereferences a location that is not in the allocated set. The above definition of memory safety captures the usual categories of memory safety errors such as null-pointer dereferences, use after free, use of uninitialized memory, illegal freeing of memory, etc. [Hicks 2014]. However, in this paper, we do not consider allocation of contiguous blocks of arbitrary size of memory (and hence do not handle arrays and buffer overflows of arrays in languages like ...