Search code examples
frama-c

How to prove this assign clause?


/*@
  @ requires \valid(p);
  @ assigns \nothing;
*/
void foo(int *p)
{
    int *pb;
    pb = p;
    *pb = 1;
    return;
}

void main(){
    int a = 0;
    foo(&a);
    return;
}

As I understand the assigns clause for a function contract only works with the function's input variables. So I make the assigns clause to nothing but then get yellow status with -wp.

frama-c -wp test1.c
[kernel] Parsing test1.c (with preprocessing)
[wp] Warning: Missing RTE guards
[wp] 3 goals scheduled
[wp] [Alt-Ergo] Goal typed_foo_assign_part2 : Unknown (Qed:4ms) (51ms)
[wp] Proved goals:    2 / 3
Qed:             2 
Alt-Ergo:        0  (unknown: 1)

How to prove foo() if assigns \nothing is not working?


Solution

  • I'm unsure of what you mean by "assigns [...] only works with the function's input variable". An assigns clause is supposed to give a superset of all memory locations that are allocated in both the pre- and post- states of the contract (there are specific clauses for handling dynamic (de)allocation) and that might be modified during the execution of the function (or the statement for a statement contract).

    In particular, your function foo can't have an assigns \nothing; clause since it modifies the value of the location pointed to by p: you must have something like assigns *p;, which is easily proved by frama-c -wp.