| Version 6 (modified by , 10 years ago) ( diff ) |
|---|
Memory Analysis
Definitions
- memory unit:
mu = (dyscopeID, variableID, reference, access)A memory unitmuis referring to a certain region of a variable, which is defined by a dyscopeID and a variable ID. Amuhas an access attribute which denotes whether the it is writable by a given process.
- impact memory unit: a memory unit being accessed at the current location by a given process.
- reachable impact memory unit: a memory unit being accessed at the current location or any reachable future location of a given process.
- variable addressed-of: a variable that's used as the operand of the address-of operator
&.
Impact memory unit analysis
The analysis below is an over approximation.
Given a location L, which has outgoing statements s1, s2, ... sn, the impact memory units of L is:
impact(L) = impact(s1) U impact(s2) U ... U impact(sn).
Reachable memory units analysis:
reach(L) = U L --> L' reach(L') U impact(L).
Expressions
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.
letmu(e) be a function to convert an expression, of pointer type or being a left-hand-side expression, to a memory unit.
- abstract function call:
f(e0,e1, ...)
impact(f(e0,e1, ...)) = impact(e0) U impact(e1) ...
- address-of:
&le
impact($le)=impact(sub(le))
- array literal:
{e0, e1, ...}
impact({e0, e1, ...}) = impact(e0) U impact(e1) ...
- binary expression:
e0 op e1
impact(e0 op e1) = impact(e0) U impact(e1)
- bound variable expression:
eb
impact(eb)=\empty
- cast expression:
(T)e
impact((T)e)=impact(e)
- char literal:
{e0, e1, ...}
similar to array literal
- conditional expression:
e0 ? e1 : e2
impact(e0 ? e1 : e2) = impact(e0) U impact(e1) U impact(e2)
- dereference expression:
*e
impact(*e) = mu(e) U impact(sub(e))the impact memory units of*einclude the memory unit refers to bye, and the impact memory units of the sub-expressions ofe. e.g., the impact memory units of*(p+i)is{mu(p+5), impact(i)}, becausepis of pointer type andsub(p+i)is{i}.
- derivative call expression:
de
impact(de) = \empty
- domain guard expression:
(int i0, i1, ... : e)
impact((int i0, i1, ... : e)) = impact(e)
- dot expression:
e.k
impact(e.k) = mu(e.k) U impact(sub(e))the impact memory units of
e.kinclude the memory unit refers to bye, and the impact memory units of the sub-expressions ofe. e.g., the impact memory units ofpoints[k].xis{mu(points[k]+x), impact(k)}, becausesub(points[k])is{k}.
- quantified expression:
quantifier er: ewhereeris the restriction expression
impact(quantifier er: e) = impact(er) U impact(e)
- rectangular domain expression:
{e0, e1, ...}
similar to array literal
- regular range expression:
{el, eh#es}
impact({el, eh#es}) = impact(el) U impact(eh) U impact(es)
- scope-of expression:
scopeof(e)
impact(scopeof(e))=\empty
- sizeof expression:
sizeof(e)
impact(sizeof(e))=\empty
- struct or union literal:
{e0, e1, ...}
similar to array literal
- subscript expression:
ea[ei]
impact(ea[ei])=mu(ea[ei]) U impact(sub(ea)) U impact(ei)for example, the impact units of
(a[i])[j]ismu(a[i][j]) U impact(i) U impact(j)becausesub(a[i])is{i}.
Sub-expressions
let e be an expression, let sub(e) be the set of sub-expressions of e.
- abstract function call:
f(e0,e1, ...)
sub(f(e0,e1, ...)) = {e0, e1, ...}
- address-of:
&le
sub(&le)={le} U sub(le)
- array literal:
{e0, e1, ...}
sub({e0, e1, ...}) = {e0, e1, ...}`
- binary expression:
e0 op e1sub(e0 op e1) = e0.type== pointer ? {e1} : {e0, e1}
- bound variable expression:
eb
sub(eb)=\empty
- cast expression:
(T)e
sub((T)e)={e}
statements
- assignment:
l := eimpact(l := e) = impact(l) U impact(e);
- call:
l := f(e0, e1, e2, ...)- f is atomic specified (
$atomic_f) and f has contracts:
TBC - otherwise:
impact(l := f(e0, e1, e2, ...)) = impact(l) U impact(e0) U impact(e1) ... U impact(f), whereimpact(f)is the impact memory unit set of the functionf.
- f is atomic specified (
- guarded statement:
[e]s
impact([e]s) = impact(e) U impact(s)
