forked from dafny-lang/dafny
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgit-issue-1112.dfy
More file actions
109 lines (98 loc) · 2.72 KB
/
git-issue-1112.dfy
File metadata and controls
109 lines (98 loc) · 2.72 KB
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// RUN: %testDafnyForEachResolver --expect-exit-code=4 "%s"
class C {
var d: D?
const k: int
}
class D {
var b: bool
}
method Field(c: C)
modifies c
requires c.d != null
{
c.d := null;
label L:
assert c.d == old@L(c.d) == null != old(c.d);
// The following errors were once not properly checked
if
case true =>
ghost var x := old@L(c.d.b); // error: null dereference error
case true =>
assert old@L(c.d.b) || !old@L(c.d.b); // error (x2): null dereference error
}
method Array(arr: array<D?>, i: nat)
requires i < arr.Length && arr[i] != null
modifies arr
{
arr[i] := null;
label L:
assert arr[i] == old@L(arr[i]) == null != old(arr[i]);
// The following errors were once not properly checked
if * {
ghost var x := old@L(arr[i].b); // error: null dereference error
} else {
assert old@L(arr[i].b) || !old@L(arr[i].b); // error (x2): null dereference error
}
}
method MultiArray(m: array2<D?>, i: nat, j: nat)
requires i < m.Length0 && j < m.Length1 && m[i, j] != null
modifies m
{
m[i, j] := null;
label L:
assert m[i, j] == old@L(m[i, j]) == null != old(m[i, j]);
// The following errors were once not properly checked
if * {
ghost var x := old@L(m[i, j].b); // error: null dereference error
} else {
assert old@L(m[i, j].b) || !old@L(m[i, j].b); // error (x2): null dereference error
}
}
method AllocField(c: C)
modifies c
{
c.d := null;
label L:
var nd := new D;
if * {
ghost var x := old(nd.b); // error: receiver must be allocated in old state
} else {
ghost var x := old@L(nd.b); // error: receiver must be allocated in state L
}
}
method AllocArray(c: C)
modifies c
{
c.d := null;
label L:
var arr := new real[5];
if * {
ghost var x := old(arr[2]); // error: array must be allocated in old state
} else {
ghost var x := old@L(arr[2]); // error: array must be allocated in state L
}
}
method AllocMatrix(c: C)
modifies c
{
c.d := null;
label L:
var m := new real[5, 5];
if * {
ghost var x := old(m[2, 0]); // error: array must be allocated in old state
} else {
ghost var x := old@L(m[2, 0]); // error: array must be allocated in state L
}
}
method ArrayNullCheckRegression0(arr: array?<real>, m: array2?<real>, a10: Array10, m1010: Matrix1010)
{
var x := arr[2]; // error (x2): array may be null, index out of bounds
var y := m[2, 3]; // error (x3): array may be null, indices out of bounds
}
type Array10 = a: array?<real> | a == null || a.Length == 10
type Matrix1010 = a: array2?<real> | a == null || (a.Length0 == a.Length1 == 10)
method ArrayNullCheckRegression1(arr: Array10, m: Matrix1010)
{
var x := arr[2]; // error: array may be null
var y := m[2, 3]; // error: array may be null
}