| 264 | | * Example: to determine whether it is safe to read `*(p+i)`, assert `$summable(p, i) && $valid(p+i) && $defined(*(p+i))`. You must check (1) you can sum `p` and `i`, (2) `p+i` points to an object of the base type, so dereference is safe, and (3) the object is defined (has been assigned a value). If you aren't sure `p` and `i` have been defined, you can add `$defined(p) && $defined(i)` to the assertion. |
| | 264 | * Example: to determine whether it is safe to read `*(p+i)`, assert `$summable(p, i) && $valid(p+i) && $defined(*(p+i))`. You must check (1) you can sum `p` and `i`, (2) `p+i` points to an object of the base type, so dereference is safe, and (3) the object is defined (has been assigned a value). If you aren't sure `p` and `i` have been defined, you can add `$defined(p) && $defined(i)` to the assertion. It may be more efficient to use temporary variables and break this up into multiple assertions. |
| | 265 | |
| | 266 | === How to implement `$defined` using symbolic execution === |
| | 267 | |
| | 268 | Create a symbolic constant named `UNDEF` for each type T. These can be created on-the-fly, as they are needed. |
| | 269 | |
| | 270 | Every variable is initialized to the `UNDEF` of its type. The exception is a struct, which may be initialized to a concrete struct in which each field is `UNDEF`. (Either way will work, but the latter will probably be more effective.) |
| | 271 | |
| | 272 | For a complete type T, the "undef-initializer" for T is defined as follows: if T is not an array type, the undef-initializer is defined exactly as above: either the symbolic constant `UNDEF` or a concrete struct of `UNDEF`s. If T is the complete array type S[n], the undef-initializer is the array-lambda expression with length n and defining expression the undef-initializer for S. |
| | 273 | |
| | 274 | `$new_array(n,T)` returns the undef-initializer for T[n]. |
| | 275 | |
| | 276 | `$alloc(h,n,T)` creates a new object in the heap h with value the undef-initializer for T[n], and returns a pointer to element 0 of that object. |
| | 277 | |
| | 278 | Evaluation of `$defined(expr)` returns `!FORALL UNDEF:T . expr == UNDEF`, where `T` is the type of `expr`. |