Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*&p is not equivalent to p #85

Open
necto opened this issue May 8, 2017 · 2 comments
Open

*&p is not equivalent to p #85

necto opened this issue May 8, 2017 · 2 comments

Comments

@necto
Copy link
Contributor

necto commented May 8, 2017

Rather unexpected difference of two terms: p and *&p for a local variable void* p;. For some reason VeriFast does not allow direct use of p and prefers *&p |-> ?x; x instead. Here is the full code:

/*@ predicate myp(void* p); 
@*/

void init(void** pp);
//@ requires true;
//@ ensures *pp |-> ?p &*& myp(p);

int main()
//@ requires true;
//@ ensures true;
{
  void* p;
  init(&p);
  //@ assert *&p |-> ?x;
  //@ assert myp(x);//<-- this is fine
  //@ assert myp(p);//<-- Cannot perform dereference in this context.
}

Why is there a difference?

@btj
Copy link
Member

btj commented May 8, 2017

There is no difference. VeriFast does not allow //@ assert myp(*&p); either, for the same reason that it does not allow //@ assert myp(foo->bar);: VeriFast does not allow heap-dependent expressions (in the broad sense of "heap": addressable memory) in assertions (and neither does separation logic) as a way to make sure that an assertion depends only on memory whose presence it asserts.

Note that VeriFast does accept //@ assert p |-> ?x;.

@necto
Copy link
Contributor Author

necto commented May 8, 2017

I see. I guess my confusion arises actually from the fact that a seemingly side-effect free operation (&) breaks the following code. Here is a slightly different example:

/*@ predicate myp(void* p) = true;  @*/

void main()
//@ requires true;
//@ ensures myp(_);
{
  void* p;
  //@ close myp(p);
  // @ assert *&p |-> ?x; //<-- uncomment this, and you'll get
                          // "Cannot perform dereference in this context" on the next line
  //@ assert myp(p);
}

Here the last assert passes unless I take an address of p, which seems counterintuitive to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants