From 91a0cf94be3cdfaff29d65122c9ea031a1a4976b Mon Sep 17 00:00:00 2001 From: qunyanm Date: Fri, 12 Feb 2016 15:59:08 -0800 Subject: Fix issue 132. The formal argument can't be assume to be allocated when a function is invoked inside an "Old" expression. --- Test/dafny4/Bug132.dfy | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Test/dafny4/Bug132.dfy (limited to 'Test/dafny4/Bug132.dfy') diff --git a/Test/dafny4/Bug132.dfy b/Test/dafny4/Bug132.dfy new file mode 100644 index 00000000..b2a26876 --- /dev/null +++ b/Test/dafny4/Bug132.dfy @@ -0,0 +1,45 @@ +// RUN: %dafny /compile:0 "%s" > "%t" +// RUN: %diff "%s.expect" "%t" + +class Cell { + var data: int + + predicate P() + reads this + { data < 0 } + + predicate Q(e: Cell) + reads this, e + { e != null ==> e.data == data } + + method Test() { + ghost var b; + var c := new Cell; + if { + // In the current state, everything is allowed: + case true => b := this.P(); + case true => b := c.P(); + case true => b := this.Q(this); + case true => b := this.Q(c); + case true => b := c.Q(this); + case true => b := c.Q(c); + + // 'this' was allocated already in the 'old' state, so all of these are fine: + case true => b := old(this.P()); + case true => b := old(P()); // same as previous line, of course + case true => b := old(this.Q(this)); + + // 'c' is freshly allocaed in this method, so it cannot be used inside 'old' + case true => b := old(c.P()); // error: receiver argument must be allocated in the state in which the function is invoked + case true => b := old(c.Q(this)); // error: receiver argument must be allocated in the state in which the function is invoked + + // The same rule should apply if 'c' is a non-receiver argument + case true => b := old(this.Q(c)); // BOGUS: this should also generate an error + + // In the following, 'c' is used as both of the two arguments. It's not allowed as either argument. However, since the error + // about the receiver masks the error about the other parameter, only one error (about the receiver) should be reported. + case true => b := old(c.Q(c)); // BOGUS: this should generate an error about the receiver + } + } +} + -- cgit v1.2.3