Search code examples
verifiable-c

How to use retval-postcondition on a variable holding the return value?


My simple program is vars.c:

int pure0 ()
{
    return 0;
}

int get0(int* arr)
{
    int z = pure0();
    return z;
}

I started proof (file verif_vars.c):

Require Import floyd.proofauto.
Require Import vars.

Local Open Scope logic.
Local Open Scope Z.

Definition get0_spec :=
  DECLARE _get0
    WITH sh : share, arr : Z->val, varr : val
    PRE [_arr OF (tptr tint)]
        PROP ()
        LOCAL (`(eq varr) (eval_id _arr);
               `isptr (eval_id _arr))
        SEP (`(array_at tint sh arr 0 100) (eval_id _arr))
    POST [tint] `(array_at tint sh arr 0 100 varr) &&
                 local(`(eq (Vint (Int.repr 0))) retval).

Definition pure0_spec :=
  DECLARE _pure0
    WITH sh : share
    PRE []
        PROP ()
        LOCAL ()
        SEP ()
    POST [tint] local(`(eq (Vint (Int.repr 0))) retval).

Definition Vprog : varspecs := nil.
Definition Gprog : funspecs := get0_spec :: pure0_spec ::nil.

Lemma body_pure0: semax_body Vprog Gprog f_pure0 pure0_spec.
Proof.
  start_function.
  forward.
Qed.


Lemma body_get0: semax_body Vprog Gprog f_get0 get0_spec.
Proof.
  start_function.
  name arrarg _arr.
  name zloc _z.
  name zloc' _z'.
  forward_call (sh).
  entailer!.
  auto with closed.
  after_call.
  forward.
  entailer!.

And ended up with two subgoals:

  Espec : OracleKind
  sh : share
  arr : Z -> val
  Struct_env := abbreviate : type_id_env.type_id_env
  Delta := abbreviate : tycontext
  zloc0 : val
  arrarg : val
  zloc : int
  TC : is_pointer_or_null arrarg
  Parrarg : isptr arrarg
  ============================
   Int.repr 0 = zloc

subgoal 2 (ID 1273) is:
 !!(Int.repr 0 = zloc) |-- emp
  • First one follows directly from pure0_spec postcondition. But how can I tell it to Coq?
  • The second goal can be simplified (by admit. entailer.) to TT |-- emp. Which seems again trivial, and still how could one prove it (SearchAbout derives and SearchAbout emp don't show any general lemmas)?

I use: VST 1.5 (6834P at 2014-10-02), CompCert 2.4, Coq 8.4pl3(Jan'14) with OCaml 4.01.0.


Solution

  • First: offhand, without attempting to reproduce this myself-- is it possible that using entailer! is too "risky", because (as documented) entailer! can sometimes turn a provable goal into an unprovable one. Try with entailer without the bang, and see if it looks better.

    Second, TT |-- emp is not true. TT applies to any heap, and emp applies only to empty heaps. You can fix this by changing the postcondition the pure function to,

    POST [tint] local(`(eq (Vint (Int.repr 0))) retval) && emp.