summaryrefslogtreecommitdiff
path: root/Test/dafny0/TailCalls.dfy
diff options
context:
space:
mode:
authorGravatar Rustan Leino <leino@microsoft.com>2013-05-21 19:04:09 -0700
committerGravatar Rustan Leino <leino@microsoft.com>2013-05-21 19:04:09 -0700
commite7422dc4757674758684c0e48f160eb37f42386a (patch)
tree9798a99bd5fef7b3fd3fc1f0411cee4bdf719d57 /Test/dafny0/TailCalls.dfy
parent9f87e7b7121a8003ae863dbe55b32a4118c578a3 (diff)
Allow more tail calls, on account of considering non-loop aggregate statements with only ghost sub-statements to be ghost
Diffstat (limited to 'Test/dafny0/TailCalls.dfy')
-rw-r--r--Test/dafny0/TailCalls.dfy26
1 files changed, 26 insertions, 0 deletions
diff --git a/Test/dafny0/TailCalls.dfy b/Test/dafny0/TailCalls.dfy
index 0aa46348..41a8c49b 100644
--- a/Test/dafny0/TailCalls.dfy
+++ b/Test/dafny0/TailCalls.dfy
@@ -72,3 +72,29 @@ method {:tailrecursion} H1(q: int) returns (x: int)
decreases *; // fine, but no 'decreases' spec is needed at all here
method H2(q: int) returns (x: int)
decreases 5; // fine, but no 'decreases' spec is needed at all here
+
+class {:autocontracts} MyAutoContractClass {
+ var left: MyAutoContractClass;
+
+ predicate Valid() { true }
+
+ method {:tailrecursion} VisitLeft(val: int)
+ {
+ if left != null {
+ left.VisitLeft(val); // this is a tail call, because what :autocontracts appends is ghost
+ }
+ }
+}
+
+method {:tailrecursion} OtherTailCall(n: int) {
+ ghost var x := 12;
+ if n > 0 {
+ OtherTailCall(n-1); // tail call
+ }
+ x := 14;
+ { x := 13; }
+ ghost var h := 15;
+ if n < h*30 { } // this is a ghost statement as well
+ if n < 230 { } // and this can be (and is) considered ghost as well
+ if (*) { x := x + 1; } // this, too
+}