| | 8 | === Definitions === |
| | 9 | * `obj(p)`: the set of objects that `p` may reference to; |
| | 10 | * `obj(e)`: the set of objects that `e` may represent, where `e` has pointer type, or composite type of pointer type (e.g., array of pointers); |
| | 11 | |
| | 12 | * `Conditional Object Set` of a pointer `p`: |
| | 13 | * `cobj(p)={c0->O0, c1->O1, c2->O2, ...}` where `O1, O2, ...` are all set of objects |
| | 14 | * `c0->O0` denotes that when `c0` is satisfied the objects set that p could refer to is `O0` |
| | 17 | ==== Expressions ==== |
| | 18 | let `e` be an expression, let `le` be an left-hand-side expression, let `impact(e)` be the set of impact memory units of `e`. |
| | 19 | let`mu(e)` be a function to convert an expression, of pointer type or being a left-hand-side expression, to a memory unit. |
| | 20 | |
| | 21 | 1. abstract function call: `f(e0,e1, ...)` |
| | 22 | **???** |
| | 23 | 2. address-of: `&le` |
| | 24 | `obj(&le)={le}` |
| | 25 | 3. array literal: `{e0, e1, ...}` where `e0`, .. `e1` all have pointer types |
| | 26 | `obj({e0, e1, ...}) = obj(e0) U obj(e1) ...` |
| | 27 | 4. pointer addition: `e0 + e1` |
| | 28 | `obj(e0 + e1) = offset(e0, e1)` |
| | 29 | 5. cast expression: `(T)e` (where `T` is pointer type) |
| | 30 | `obj((T)e)=obj(e)` |
| | 31 | 6. conditional expression: `e0 ? e1 : e2` |
| | 32 | `obj(e0 ? e1 : e2) = e0 ? obj(e1) : obj(e2)` |
| | 33 | 7. dereference expression: `*e` where `e` has type pointer-to-pointer of `T` |
| | 34 | `obj(*e) = **???**` |
| | 35 | the impact memory units of `*e` include the memory unit refers to by `e`, and the impact memory units of the sub-expressions of `e`. |
| | 36 | e.g., the impact memory units of `*(p+i)` is `{mu(p+5), impact(i)}`, because `p` is of pointer type and `sub(p+i)` is `{i}`. |
| | 37 | 8. dot expression: `e.k` where `e.k` has pointer type |
| | 38 | `obj(e.k) = {e.k}` |
| | 39 | 9. subscript expression: `ea[ei]` |
| | 40 | `obj(ea[ei])={ea[ei]}` |
| | 41 | |
| | 42 | ==== Sub-expressions ==== |
| | 43 | let `e` be an expression, let `sub(e)` be the set of sub-expressions of `e`. |
| | 44 | |
| | 45 | 1. abstract function call: `f(e0,e1, ...)` |
| | 46 | `sub(f(e0,e1, ...)) = {e0, e1, ...}` |
| | 47 | 2. address-of: `&le` |
| | 48 | `sub(&le)={le} U sub(le)` |
| | 49 | 3. array literal: `{e0, e1, ...}` |
| | 50 | `sub({e0, e1, ...}) = {e0, e1, ...}`` |
| | 51 | 4. binary expression: `e0 op e1` |
| | 52 | `sub(e0 op e1) = e0.type== pointer ? {e1} : {e0, e1}` |
| | 53 | 5. bound variable expression: `eb` |
| | 54 | `sub(eb)=\empty` |
| | 55 | 6. cast expression: `(T)e` |
| | 56 | `sub((T)e)={e}` |
| | 57 | |
| | 58 | |
| | 59 | |
| | 60 | |
| | 61 | |
| | 62 | |