-
Notifications
You must be signed in to change notification settings - Fork 267
/
Copy pathgit-issue-1163.dfy
66 lines (58 loc) · 1.66 KB
/
git-issue-1163.dfy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// RUN: %testDafnyForEachResolver --expect-exit-code=4 "%s"
ghost function F(i: int): int
method M() {
ghost var f := old(i => F(i)); // the translation of this once had crashed the verifier (warning: old has no effect)
}
class MyClass {
var y: int
method N()
modifies this
{
y := 8;
label L:
var p := new MyClass;
label K:
if * {
ghost var g := old@L((x: int) reads p.R(this) => x); // error, because p is not allocated in L
} else if * {
ghost var g := old@L((x: int) reads R(p) => x); // error, because p is not allocated in L
} else if * {
ghost var g := old@K((x: int) reads p.R(p) => x);
} else {
ghost var g := old((x: int) reads p.R(p) => x); // error, because p is not allocated in old state
}
}
method O()
modifies this
{
y := 8;
label L:
ghost var h :=
old@L(
(p: MyClass) requires p.y == 10 reads p =>
assert p.y == 10; 5 // this assert once didn't work, because of a mismatch of heap variables in the translator
);
}
method Q()
modifies this
{
// The following uses of p in R(p) should be allowed. In particular, they should not
// produce "p not allocated in function state" errors.
if * {
ghost var h := old((p: MyClass) reads R(p) => 5);
} else if * {
ghost var s := old(iset p: MyClass | R(p) == p);
} else if * {
ghost var m := old(imap p: MyClass | R(p) == p :: 12);
} else if * {
ghost var m := old(var p: MyClass :| R(p) == p; p.y);
} else {
ghost var m := old(forall p: MyClass :: R(p) == p);
}
}
ghost function R(c: MyClass): MyClass
reads this
{
this
}
}