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. --- Source/Dafny/Translator.cs | 7 +++++-- Test/dafny4/Bug132.dfy | 45 +++++++++++++++++++++++++++++++++++++++++++ Test/dafny4/Bug132.dfy.expect | 18 +++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 Test/dafny4/Bug132.dfy create mode 100644 Test/dafny4/Bug132.dfy.expect diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs index 0314344d..52f52abf 100644 --- a/Source/Dafny/Translator.cs +++ b/Source/Dafny/Translator.cs @@ -5045,8 +5045,11 @@ namespace Microsoft.Dafny { CheckSubrange(ee.tok, etran.TrExpr(ee), et, builder); Bpl.Cmd cmd = Bpl.Cmd.SimpleAssign(p.tok, lhs, CondApplyBox(p.tok, etran.TrExpr(ee), cce.NonNull(ee.Type), et)); builder.Add(cmd); - builder.Add(new Bpl.CommentCmd("assume allocatedness for argument to function")); - builder.Add(new Bpl.AssumeCmd(e.Args[i].tok, MkIsAlloc(lhs, et, etran.HeapExpr))); + if (!etran.UsesOldHeap) { + // the argument can't be assumed to be allocated for the old heap + builder.Add(new Bpl.CommentCmd("assume allocatedness for argument to function")); + builder.Add(new Bpl.AssumeCmd(e.Args[i].tok, MkIsAlloc(lhs, et, etran.HeapExpr))); + } } // Check that every parameter is available in the state in which the function is invoked; this means checking that it has // the right type and is allocated. These checks usually hold trivially, on account of that the Dafny language only gives 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 + } + } +} + diff --git a/Test/dafny4/Bug132.dfy.expect b/Test/dafny4/Bug132.dfy.expect new file mode 100644 index 00000000..0452f42d --- /dev/null +++ b/Test/dafny4/Bug132.dfy.expect @@ -0,0 +1,18 @@ +Bug132.dfy(33,29): Error: receiver argument must be allocated in the state in which the function is invoked +Execution trace: + (0,0): anon0 + (0,0): anon24_Then +Bug132.dfy(34,29): Error: receiver argument must be allocated in the state in which the function is invoked +Execution trace: + (0,0): anon0 + (0,0): anon25_Then +Bug132.dfy(37,36): Error: argument must be allocated in the state in which the function is invoked +Execution trace: + (0,0): anon0 + (0,0): anon26_Then +Bug132.dfy(41,29): Error: receiver argument must be allocated in the state in which the function is invoked +Execution trace: + (0,0): anon0 + (0,0): anon27_Then + +Dafny program verifier finished with 3 verified, 4 errors -- cgit v1.2.3