The contracts specification of CIVL-C is based on ACSL, with additional primitives and constructs for various purposes, such as function guard, function dependency, MPI function behavior, etc.
overview
The grammar for the contract specification of a function is as follows:
contract: requires* terminates? decreases? simple* behavior* completeness* ;
requires: 'requires' e ';' ;
...
simple: ensures | assumes | assigns | reads | guards | depends | ... ;
ensures: 'ensures' e ';' ;
assumes: 'assumes' e ';' ;
assigns: 'assigns' e (',' e)* ';' ;
reads: 'reads' e (',' e)* ';' ;
depends: 'depends' e (',' e)* ';' ;
...
behavior: 'begin behavior' id ':' behaviorBody 'end behavior';
behaviorBody: behaviorClause+;
behaviorClause: assumes | requires | simple ;
completeness: 'complete' (id (',' id)*)?
| 'disjoint' (id (',' id)*)?
;
Example
fun[atomic] sendRecv(Int cmd, Pointer buf): Integer
reads deref(buf);
begin behavior send:
depends writes(buf);
assigns nothing;
end behavior
begin behavior receive:
depends access(deref(buf));
assigns deref(buf);
end behavior
{
begin choose
when eq(cmd, 0)
do CALL send, <buf, ...>; goto L1;
when eq(cmd, 1)
do CALL recv, <buf, ...>; goto L1;
when and(neq(cmd, 0), neq(cmd, 1))
do NOOP; goto L1;
end choose
L1:
}
contract clauses
requires e;: precondition,ehasBooltype and should hold at the entry of the functionterminates e;:ehasBooltype and ifeholds then the function should terminate eventuallydecreases e ;ordecreases e for r;: decreases clause, whereeis an expression of typeTandris an relation overT- simple clauses:
ensures e;: postcondition,ehasBooltype and should hold when the function terminatesassumes e;: assumption,ehasBooltypeassigns e0, e1, ...;: side-effects,e0, e1, ...haveMemtype- absence of
Assignsclause does NOT mean that the function has no side-effects assigns nothing: means that the function has no side-effects
- absence of
allocates e0, e1, ...;: memory units allocated by the function,e0, e1, ...haveMemtypefrees e0, e1, ...;: memory units deallocated by the function,e0, e1, ...haveMemtypeguards e;: guard of the function, whereehasBooltypereads e0, e1, ...;: memory access, wheree0, e1, ...haveMemtype- similar to
assigns - absence of
Readsclause does NOT mean that the function does NOT read anything reads nothing: means that the function does NOT read the memory
- similar to
depends e0, e1, ...;: dependency relation, wheree0, e1, ...haveMemtype- Note:
guards,dependsandreadsare CIVL extension for ACSL
- named behavior:
begin behavior id : c0; c1; c2; ... end behavior, whereidis the name of this behavior,c0, c1, c2, ...are behavior clauses- behavior clause: a clause that can be used in the body of a behavior, and could be one of the following:
- assumes clause
- requires clause
- simple clause
- completeness clause
complete;orcomplete (id0, id1, ...);:disjoint;ordisjoint (id0, id1, ...);
depends clause and actions
- action expressions:
read(e):ehas typeMem. The function reads the memory units specified bye.write(e):ehas typeMem. The function writes the memory units specified bye.call(f, <e1, ...>):fhas typeFunction. The function callsfwith parameterse1, ....noaction: no actionanyaction: all actionsact_union(ma0, ma1): the union of the two memory set actionsma0andma1.act_comp(ma0, ma1): action complement (everything not inma1)act_isect(ma0, ma1): action intersection
- depends clause:
depends action0, action1, action2, ...- Example:
depends act_union(act_comp(read(n), call(inc, <x>))), call(dec, <y>)) - absence of depends clause: there is no information about the dependency of the function, which means that the analysis needs to figure it out by itself.
- Example:
- some facts about assigns-or-reads clause
- absence of
reads/assignsclause: there is no assumption about the read/assign access of the function, i.e., the function could read/assign anything- absence of
assignsclause: similar to the absence ofreadsclause
- absence of
reads/assigns nothingdoesn’t necessarily means that the function never reads or assigns any variable. The function could still reads/assigns its “local” variables, including function parameters and any variable declared inside the function body. check it
- absence of
- For an independent function which has
depends coaction, usually we also need to specifyreads nothing, for the purpose of reachability analysis.
e.g.,
/* Returns the size of the given bundle b. */ bundle_size(Bundle b): Integer depends nothing reads b ;
- Example of a function declaration with contracts:
fun[atomic] sendRecv(Int cmd, Pointer buf): Integer reads deref(buf); begin behavior send: depends writes(buf); assigns nothing; end behavior begin behavior receive: depends access(deref(buf)); assigns deref(buf); end behavior { begin choose when eq(cmd, 0) do CALL send, <buf, ...>; goto L1; when eq(cmd, 1) do CALL recv, <buf, ...>; goto L1; when and(neq(cmd, 0), neq(cmd, 1)) do NOOP; goto L1; end choose L1: }
Last modified
10 years ago
Last modified on 01/18/16 20:36:18
Note:
See TracWiki
for help on using the wiki.
