rapx/analysis/senryx/contracts/
state_lattice.rs1use super::abstract_state::*;
3
4pub trait Lattice {
5 fn join(&self, other: Self) -> Self;
6 fn meet(&self, other: Self) -> Self;
7 fn less_than(&self, other: Self) -> bool;
8 fn equal(&self, other: Self) -> bool;
9 fn check(&self) -> bool;
10}
11
12impl<'tcx> Lattice for StateType<'tcx> {
13 fn join(&self, other: Self) -> Self {
14 match &self {
15 &StateType::AllocatedState(a) => match other {
16 StateType::AllocatedState(b) => StateType::AllocatedState(a.join(b)),
17 _ => panic!("Incompatible types"),
18 },
19 &StateType::AlignState(a) => match other {
20 StateType::AlignState(b) => StateType::AlignState(a.join(b)),
21 _ => panic!("Incompatible types"),
22 },
23 }
24 }
25
26 fn meet(&self, other: Self) -> Self {
27 match &self {
28 &StateType::AllocatedState(a) => match other {
29 StateType::AllocatedState(b) => StateType::AllocatedState(a.meet(b)),
30 _ => panic!("Incompatible types"),
31 },
32 &StateType::AlignState(a) => match other {
33 StateType::AlignState(b) => StateType::AlignState(a.meet(b)),
34 _ => panic!("Incompatible types"),
35 },
36 }
37 }
38
39 fn less_than(&self, other: Self) -> bool {
40 match &self {
41 &StateType::AllocatedState(a) => match other {
42 StateType::AllocatedState(b) => a.less_than(b),
43 _ => panic!("Incompatible types"),
44 },
45 &StateType::AlignState(a) => match other {
46 StateType::AlignState(b) => a.less_than(b),
47 _ => panic!("Incompatible types"),
48 },
49 }
50 }
51
52 fn equal(&self, other: Self) -> bool {
53 match &self {
54 &StateType::AllocatedState(a) => match other {
55 StateType::AllocatedState(b) => a.equal(b),
56 _ => panic!("Incompatible types"),
57 },
58 &StateType::AlignState(a) => match other {
59 StateType::AlignState(b) => a.equal(b),
60 _ => panic!("Incompatible types"),
61 },
62 }
63 }
64
65 fn check(&self) -> bool {
66 match &self {
67 &StateType::AllocatedState(a) => a.check(),
68 &StateType::AlignState(a) => a.check(),
69 }
70 }
71}
72
73impl Lattice for AllocatedState {
74 fn join(&self, other: Self) -> Self {
75 match (*self, other) {
76 (AllocatedState::Bottom, _) => other,
77 (_, AllocatedState::Bottom) => *self,
78 (AllocatedState::Top, _) | (_, AllocatedState::Top) => AllocatedState::Top,
79 (AllocatedState::Borrowed, AllocatedState::Moved)
80 | (AllocatedState::Moved, AllocatedState::Borrowed) => AllocatedState::Top,
81 (AllocatedState::Alloc, AllocatedState::SpecificAlloc)
82 | (AllocatedState::SpecificAlloc, AllocatedState::Alloc) => {
83 AllocatedState::SpecificAlloc
84 }
85 (state1, state2) if state1 == state2 => state1,
86 (AllocatedState::Alloc, AllocatedState::Borrowed)
87 | (AllocatedState::Borrowed, AllocatedState::Alloc) => AllocatedState::Borrowed,
88 (AllocatedState::Alloc, AllocatedState::Moved)
89 | (AllocatedState::Moved, AllocatedState::Alloc) => AllocatedState::Moved,
90 (AllocatedState::SpecificAlloc, AllocatedState::Borrowed)
91 | (AllocatedState::Borrowed, AllocatedState::SpecificAlloc) => AllocatedState::Borrowed,
92 (AllocatedState::Moved, AllocatedState::SpecificAlloc)
93 | (AllocatedState::SpecificAlloc, AllocatedState::Moved) => AllocatedState::Moved,
94 _ => AllocatedState::Top,
95 }
96 }
97
98 fn meet(&self, other: Self) -> Self {
99 match (*self, other) {
100 (AllocatedState::Top, _) => other,
101 (_, AllocatedState::Top) => *self,
102 (AllocatedState::Bottom, _) | (_, AllocatedState::Bottom) => AllocatedState::Bottom,
103 (AllocatedState::Borrowed, AllocatedState::Moved)
104 | (AllocatedState::Moved, AllocatedState::Borrowed) => AllocatedState::Bottom,
105 (AllocatedState::Alloc, AllocatedState::SpecificAlloc)
106 | (AllocatedState::SpecificAlloc, AllocatedState::Alloc) => AllocatedState::Alloc,
107 (state1, state2) if state1 == state2 => state1,
108 (AllocatedState::Alloc, AllocatedState::Borrowed)
109 | (AllocatedState::Borrowed, AllocatedState::Alloc) => AllocatedState::Alloc,
110 (AllocatedState::SpecificAlloc, AllocatedState::Borrowed)
111 | (AllocatedState::Borrowed, AllocatedState::SpecificAlloc) => {
112 AllocatedState::SpecificAlloc
113 }
114 (AllocatedState::Moved, AllocatedState::SpecificAlloc)
115 | (AllocatedState::SpecificAlloc, AllocatedState::Moved) => {
116 AllocatedState::SpecificAlloc
117 }
118 _ => AllocatedState::Bottom,
119 }
120 }
121
122 fn less_than(&self, other: Self) -> bool {
123 match (*self, other) {
124 (AllocatedState::Bottom, _) | (_, AllocatedState::Top) => true,
125 (AllocatedState::Alloc, AllocatedState::Borrowed) => true,
126 (AllocatedState::Alloc, AllocatedState::SpecificAlloc) => true,
127 (AllocatedState::Alloc, AllocatedState::Moved) => true,
128 (AllocatedState::SpecificAlloc, AllocatedState::Borrowed) => true,
129 (AllocatedState::SpecificAlloc, AllocatedState::Moved) => true,
130 _ => false,
131 }
132 }
133
134 fn equal(&self, other: Self) -> bool {
135 *self == other
136 }
137
138 fn check(&self) -> bool {
139 true
140 }
141}
142
143impl<'tcx> Lattice for AlignState<'tcx> {
144 fn join(&self, other: Self) -> Self {
145 match (self, other.clone()) {
146 (AlignState::Aligned, _) => AlignState::Aligned,
147 (AlignState::Cast(_, _), AlignState::Cast(_, _)) => AlignState::Unaligned,
148 (AlignState::Unaligned, _) => AlignState::Unaligned,
149 (_, AlignState::Unaligned) => AlignState::Unaligned,
150 _ => other.clone(),
151 }
152 }
153
154 fn meet(&self, other: Self) -> Self {
155 other
156 }
164
165 fn less_than(&self, other: Self) -> bool {
166 match (self, other) {
167 (_, AlignState::Aligned) => true,
168 (AlignState::Cast(_, _), AlignState::Cast(_, _)) => true,
169 _ => false,
170 }
171 }
172
173 fn equal(&self, other: Self) -> bool {
174 *self == other
175 }
176
177 fn check(&self) -> bool {
178 match self {
179 AlignState::Aligned => true,
180 AlignState::Unaligned => false,
181 AlignState::Cast(src, dest) => {
182 let src_aligns = src.possible_aligns();
184 let dest_aligns = dest.possible_aligns();
185 if dest_aligns.len() == 0 && src != dest {
186 return false;
188 }
189
190 for &d_align in &dest_aligns {
191 if d_align != 1 && src_aligns.len() == 0 {
192 return false;
194 }
195 for &s_align in &src_aligns {
196 if s_align < d_align {
197 return false;
198 }
199 }
200 }
201 true
202 }
203 }
204 }
205}
206
207impl Lattice for InitState {
208 fn join(&self, other: Self) -> Self {
209 match (self, other) {
210 (InitState::FullyInitialized, _) => InitState::FullyInitialized,
211 (_, InitState::FullyInitialized) => InitState::FullyInitialized,
212 _ => InitState::PartlyInitialized,
213 }
214 }
215
216 fn meet(&self, other: Self) -> Self {
217 match (self, other) {
218 (InitState::FullyInitialized, _) => other,
219 (_, InitState::FullyInitialized) => *self,
220 _ => InitState::PartlyInitialized,
221 }
222 }
223
224 fn less_than(&self, other: Self) -> bool {
225 match (self, other) {
226 (InitState::FullyInitialized, InitState::FullyInitialized) => true,
227 (InitState::PartlyInitialized, _) => true,
228 _ => false,
229 }
230 }
231
232 fn equal(&self, other: Self) -> bool {
233 *self == other
234 }
235
236 fn check(&self) -> bool {
237 true
238 }
239}