svf-tools 1.0.724 → 1.0.725
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.725",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -270,7 +270,7 @@ public:
|
|
|
270
270
|
else if (rhs.is_infinite())
|
|
271
271
|
return ite(lhs.getExpr() >= 0, BoundedZ3Expr(0), BoundedZ3Expr(-1));
|
|
272
272
|
else
|
|
273
|
-
return ashr(lhs.getExpr(), rhs.getExpr());
|
|
273
|
+
return bv2int(ashr(int2bv(64, lhs.getExpr()), int2bv(64, rhs.getExpr())), true);
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
friend BoundedZ3Expr shl(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
@@ -282,12 +282,12 @@ public:
|
|
|
282
282
|
else if (rhs.is_infinite())
|
|
283
283
|
return ite(lhs.getExpr() >= 0, plus_infinity(), minus_infinity());
|
|
284
284
|
else
|
|
285
|
-
return shl(lhs.getExpr(), rhs.getExpr());
|
|
285
|
+
return bv2int(shl(int2bv(64, lhs.getExpr()), int2bv(64, rhs.getExpr())), true);
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
friend BoundedZ3Expr lshr(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
289
289
|
{
|
|
290
|
-
return lshr(lhs.getExpr(), rhs.getExpr());
|
|
290
|
+
return bv2int(lshr(int2bv(64, lhs.getExpr()), int2bv(64, rhs.getExpr())), true);
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
friend BoundedZ3Expr int2bv(u32_t n, const BoundedZ3Expr &e)
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Xiao and Jiawei on 2023/5/29.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#ifndef SVF_SINGLEABSVALUE_H
|
|
6
|
+
#define SVF_SINGLEABSVALUE_H
|
|
7
|
+
|
|
8
|
+
#include "AbstractExecution/BoundedZ3Expr.h"
|
|
9
|
+
|
|
10
|
+
namespace SVF
|
|
11
|
+
{
|
|
12
|
+
|
|
13
|
+
/*!
|
|
14
|
+
* Atom Z3 expr for constant execution state
|
|
15
|
+
*/
|
|
16
|
+
class SingleAbsValue : public BoundedZ3Expr
|
|
17
|
+
{
|
|
18
|
+
public:
|
|
19
|
+
|
|
20
|
+
SingleAbsValue() = default;
|
|
21
|
+
|
|
22
|
+
SingleAbsValue(const Z3Expr &z3Expr) : BoundedZ3Expr(z3Expr.getExpr()) {}
|
|
23
|
+
|
|
24
|
+
SingleAbsValue(const BoundedZ3Expr &z3Bound) : BoundedZ3Expr(z3Bound) {}
|
|
25
|
+
|
|
26
|
+
SingleAbsValue(const z3::expr &e) : BoundedZ3Expr(e) {}
|
|
27
|
+
|
|
28
|
+
SingleAbsValue(s32_t i) : BoundedZ3Expr(i) {}
|
|
29
|
+
|
|
30
|
+
SingleAbsValue(const SingleAbsValue &_z3Expr) : BoundedZ3Expr(_z3Expr) {}
|
|
31
|
+
|
|
32
|
+
inline SingleAbsValue &operator=(const SingleAbsValue &rhs)
|
|
33
|
+
{
|
|
34
|
+
BoundedZ3Expr::operator=(rhs);
|
|
35
|
+
return *this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
SingleAbsValue(SingleAbsValue &&_z3Expr) : BoundedZ3Expr(_z3Expr)
|
|
39
|
+
{
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
inline SingleAbsValue &operator=(SingleAbsValue &&rhs)
|
|
43
|
+
{
|
|
44
|
+
BoundedZ3Expr::operator=(rhs);
|
|
45
|
+
return *this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static z3::context &getContext()
|
|
49
|
+
{
|
|
50
|
+
return BoundedZ3Expr::getContext();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static SingleAbsValue topConstant()
|
|
54
|
+
{
|
|
55
|
+
return getContext().int_const("⊤");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static SingleAbsValue bottomConstant()
|
|
59
|
+
{
|
|
60
|
+
return getContext().int_const("⊥");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void join_with(const SingleAbsValue& other)
|
|
64
|
+
{
|
|
65
|
+
if (this->isBottom())
|
|
66
|
+
{
|
|
67
|
+
if (other.isBottom())
|
|
68
|
+
{
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
else
|
|
72
|
+
{
|
|
73
|
+
*this = other;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (other.isBottom())
|
|
77
|
+
{
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
{
|
|
82
|
+
if (!eq(*this, other))
|
|
83
|
+
{
|
|
84
|
+
set_to_top();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void set_to_top()
|
|
90
|
+
{
|
|
91
|
+
*this = topConstant();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static bool isTopAbsValue(const SingleAbsValue &expr)
|
|
95
|
+
{
|
|
96
|
+
return eq(expr, topConstant());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static bool isBottomAbsValue(const SingleAbsValue &expr)
|
|
100
|
+
{
|
|
101
|
+
return eq(expr, bottomConstant());
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
inline bool isBottom() const
|
|
105
|
+
{
|
|
106
|
+
return isBottomAbsValue(*this);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
inline bool isTop() const
|
|
110
|
+
{
|
|
111
|
+
return isTopAbsValue(*this);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
inline bool isSym() const
|
|
115
|
+
{
|
|
116
|
+
return isSymbolAbsValue(*this);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static bool isSymbolAbsValue(const SingleAbsValue &expr)
|
|
120
|
+
{
|
|
121
|
+
return !eq(expr, topConstant()) && !eq(expr, bottomConstant()) && !expr.is_numeral();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Less then or equal
|
|
125
|
+
bool leq(const SingleAbsValue &rhs) const
|
|
126
|
+
{
|
|
127
|
+
assert(is_numeral() && rhs.is_numeral());
|
|
128
|
+
return (getExpr() <= rhs.getExpr()).simplify().is_true();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Greater than or equal
|
|
132
|
+
bool geq(const SingleAbsValue &rhs) const
|
|
133
|
+
{
|
|
134
|
+
assert(is_numeral() && rhs.is_numeral());
|
|
135
|
+
return (getExpr() >= rhs.getExpr()).simplify().is_true();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
/// Reload operator
|
|
140
|
+
//{%
|
|
141
|
+
friend SingleAbsValue operator==(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
142
|
+
{
|
|
143
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
144
|
+
{
|
|
145
|
+
return bottomConstant();
|
|
146
|
+
}
|
|
147
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
148
|
+
{
|
|
149
|
+
return topConstant();
|
|
150
|
+
}
|
|
151
|
+
else
|
|
152
|
+
{
|
|
153
|
+
return static_cast<BoundedZ3Expr>(lhs) == static_cast<BoundedZ3Expr>(rhs);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
friend SingleAbsValue operator!=(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
158
|
+
{
|
|
159
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
160
|
+
{
|
|
161
|
+
return bottomConstant();
|
|
162
|
+
}
|
|
163
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
164
|
+
return topConstant();
|
|
165
|
+
else
|
|
166
|
+
return static_cast<BoundedZ3Expr>(lhs) != static_cast<BoundedZ3Expr>(rhs);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
friend SingleAbsValue operator>(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
170
|
+
{
|
|
171
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
172
|
+
{
|
|
173
|
+
return bottomConstant();
|
|
174
|
+
}
|
|
175
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
176
|
+
return topConstant();
|
|
177
|
+
else
|
|
178
|
+
return static_cast<BoundedZ3Expr>(lhs) > static_cast<BoundedZ3Expr>(rhs);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
friend SingleAbsValue operator<(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
182
|
+
{
|
|
183
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
184
|
+
{
|
|
185
|
+
return bottomConstant();
|
|
186
|
+
}
|
|
187
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
188
|
+
return topConstant();
|
|
189
|
+
else
|
|
190
|
+
return static_cast<BoundedZ3Expr>(lhs) < static_cast<BoundedZ3Expr>(rhs);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
friend SingleAbsValue operator<=(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
194
|
+
{
|
|
195
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
196
|
+
{
|
|
197
|
+
return bottomConstant();
|
|
198
|
+
}
|
|
199
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
200
|
+
return topConstant();
|
|
201
|
+
else
|
|
202
|
+
return static_cast<BoundedZ3Expr>(lhs) <= static_cast<BoundedZ3Expr>(rhs);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
friend SingleAbsValue operator>=(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
206
|
+
{
|
|
207
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
208
|
+
{
|
|
209
|
+
return bottomConstant();
|
|
210
|
+
}
|
|
211
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
212
|
+
return topConstant();
|
|
213
|
+
else
|
|
214
|
+
return static_cast<BoundedZ3Expr>(lhs) >= static_cast<BoundedZ3Expr>(rhs);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
friend SingleAbsValue operator+(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
218
|
+
{
|
|
219
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
220
|
+
{
|
|
221
|
+
return bottomConstant();
|
|
222
|
+
}
|
|
223
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
224
|
+
return topConstant();
|
|
225
|
+
else
|
|
226
|
+
return static_cast<BoundedZ3Expr>(lhs) + static_cast<BoundedZ3Expr>(rhs);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
friend SingleAbsValue operator-(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
230
|
+
{
|
|
231
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
232
|
+
{
|
|
233
|
+
return bottomConstant();
|
|
234
|
+
}
|
|
235
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
236
|
+
return topConstant();
|
|
237
|
+
else
|
|
238
|
+
return static_cast<BoundedZ3Expr>(lhs) - static_cast<BoundedZ3Expr>(rhs);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
friend SingleAbsValue operator*(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
242
|
+
{
|
|
243
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
244
|
+
{
|
|
245
|
+
return bottomConstant();
|
|
246
|
+
}
|
|
247
|
+
else if (isZero(lhs) || isZero(rhs))
|
|
248
|
+
return 0;
|
|
249
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
250
|
+
return topConstant();
|
|
251
|
+
else
|
|
252
|
+
return static_cast<BoundedZ3Expr>(lhs) * static_cast<BoundedZ3Expr>(rhs);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
friend SingleAbsValue operator/(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
256
|
+
{
|
|
257
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isZero(rhs))
|
|
258
|
+
{
|
|
259
|
+
return bottomConstant();
|
|
260
|
+
}
|
|
261
|
+
else if (isZero(lhs))
|
|
262
|
+
return 0;
|
|
263
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
264
|
+
return topConstant();
|
|
265
|
+
else
|
|
266
|
+
return static_cast<BoundedZ3Expr>(lhs) / static_cast<BoundedZ3Expr>(rhs);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
friend SingleAbsValue operator%(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
270
|
+
{
|
|
271
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isZero(rhs))
|
|
272
|
+
{
|
|
273
|
+
return bottomConstant();
|
|
274
|
+
}
|
|
275
|
+
else if (isZero(lhs))
|
|
276
|
+
return 0;
|
|
277
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
278
|
+
return topConstant();
|
|
279
|
+
else
|
|
280
|
+
return static_cast<BoundedZ3Expr>(lhs) % static_cast<BoundedZ3Expr>(rhs);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
friend SingleAbsValue operator^(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
284
|
+
{
|
|
285
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
286
|
+
return bottomConstant();
|
|
287
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
288
|
+
return topConstant();
|
|
289
|
+
else
|
|
290
|
+
return static_cast<BoundedZ3Expr>(lhs) ^ static_cast<BoundedZ3Expr>(rhs);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
friend SingleAbsValue operator&(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
294
|
+
{
|
|
295
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
296
|
+
{
|
|
297
|
+
return bottomConstant();
|
|
298
|
+
}
|
|
299
|
+
else if (isZero(lhs) || isZero(rhs))
|
|
300
|
+
return 0;
|
|
301
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
302
|
+
return topConstant();
|
|
303
|
+
else
|
|
304
|
+
return static_cast<BoundedZ3Expr>(lhs) & static_cast<BoundedZ3Expr>(rhs);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
friend SingleAbsValue operator|(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
308
|
+
{
|
|
309
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
310
|
+
{
|
|
311
|
+
return bottomConstant();
|
|
312
|
+
}
|
|
313
|
+
else if ((lhs.is_numeral() && eq(lhs, -1)) ||
|
|
314
|
+
(rhs.is_numeral() && eq(rhs, -1)))
|
|
315
|
+
return -1;
|
|
316
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
317
|
+
return topConstant();
|
|
318
|
+
else
|
|
319
|
+
return static_cast<BoundedZ3Expr>(lhs) | static_cast<BoundedZ3Expr>(rhs);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
friend SingleAbsValue ashr(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
323
|
+
{
|
|
324
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0)))
|
|
325
|
+
return bottomConstant();
|
|
326
|
+
else if (isZero(lhs))
|
|
327
|
+
return 0;
|
|
328
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
329
|
+
return topConstant();
|
|
330
|
+
else
|
|
331
|
+
return ashr(static_cast<BoundedZ3Expr>(lhs), static_cast<BoundedZ3Expr>(rhs));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
friend SingleAbsValue shl(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
335
|
+
{
|
|
336
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0)))
|
|
337
|
+
return bottomConstant();
|
|
338
|
+
else if (isZero(lhs))
|
|
339
|
+
return 0;
|
|
340
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
341
|
+
return topConstant();
|
|
342
|
+
else
|
|
343
|
+
return shl(static_cast<BoundedZ3Expr>(lhs), static_cast<BoundedZ3Expr>(rhs));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
friend SingleAbsValue lshr(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
347
|
+
{
|
|
348
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0)))
|
|
349
|
+
return bottomConstant();
|
|
350
|
+
else if (isZero(lhs))
|
|
351
|
+
return 0;
|
|
352
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
353
|
+
return topConstant();
|
|
354
|
+
else
|
|
355
|
+
return lshr(static_cast<BoundedZ3Expr>(lhs), static_cast<BoundedZ3Expr>(rhs));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
friend SingleAbsValue int2bv(u32_t n, const SingleAbsValue &e)
|
|
359
|
+
{
|
|
360
|
+
if (isBottomAbsValue(e))
|
|
361
|
+
{
|
|
362
|
+
return bottomConstant();
|
|
363
|
+
}
|
|
364
|
+
else if (isTopAbsValue(e))
|
|
365
|
+
return topConstant();
|
|
366
|
+
else
|
|
367
|
+
return int2bv(n, static_cast<BoundedZ3Expr>(e));
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
friend SingleAbsValue bv2int(const SingleAbsValue &e, bool isSigned)
|
|
371
|
+
{
|
|
372
|
+
if (isBottomAbsValue(e))
|
|
373
|
+
{
|
|
374
|
+
return bottomConstant();
|
|
375
|
+
}
|
|
376
|
+
else if (isTopAbsValue(e))
|
|
377
|
+
return topConstant();
|
|
378
|
+
else
|
|
379
|
+
return bv2int(static_cast<BoundedZ3Expr>(e), isSigned);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
friend SingleAbsValue operator&&(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
383
|
+
{
|
|
384
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
385
|
+
{
|
|
386
|
+
return bottomConstant();
|
|
387
|
+
}
|
|
388
|
+
else if (eq(lhs, getContext().bool_val(false)) || eq(rhs, getContext().bool_val(false)))
|
|
389
|
+
return getContext().bool_val(false);
|
|
390
|
+
else if (eq(lhs, getContext().bool_val(true)))
|
|
391
|
+
return rhs;
|
|
392
|
+
else if (eq(rhs, getContext().bool_val(true)))
|
|
393
|
+
return lhs;
|
|
394
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
395
|
+
return topConstant();
|
|
396
|
+
else
|
|
397
|
+
return static_cast<BoundedZ3Expr>(lhs) && static_cast<BoundedZ3Expr>(rhs);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
friend SingleAbsValue operator||(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
401
|
+
{
|
|
402
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs))
|
|
403
|
+
{
|
|
404
|
+
return bottomConstant();
|
|
405
|
+
}
|
|
406
|
+
else if (eq(lhs, getContext().bool_val(true)) || eq(rhs, getContext().bool_val(true)))
|
|
407
|
+
return getContext().bool_val(true);
|
|
408
|
+
else if (eq(lhs, getContext().bool_val(false)))
|
|
409
|
+
return rhs;
|
|
410
|
+
else if (eq(rhs, getContext().bool_val(false)))
|
|
411
|
+
return lhs;
|
|
412
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs))
|
|
413
|
+
return topConstant();
|
|
414
|
+
else
|
|
415
|
+
return static_cast<BoundedZ3Expr>(lhs) || static_cast<BoundedZ3Expr>(rhs);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
friend SingleAbsValue operator!(const SingleAbsValue &lhs)
|
|
419
|
+
{
|
|
420
|
+
if (isBottomAbsValue(lhs))
|
|
421
|
+
{
|
|
422
|
+
return bottomConstant();
|
|
423
|
+
}
|
|
424
|
+
else if (isTopAbsValue(lhs))
|
|
425
|
+
return topConstant();
|
|
426
|
+
else
|
|
427
|
+
return !static_cast<BoundedZ3Expr>(lhs);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
friend SingleAbsValue ite(const SingleAbsValue &cond, const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
431
|
+
{
|
|
432
|
+
if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isBottomAbsValue(cond))
|
|
433
|
+
{
|
|
434
|
+
return bottomConstant();
|
|
435
|
+
}
|
|
436
|
+
else if (eq(cond, getContext().bool_val(true)))
|
|
437
|
+
return lhs;
|
|
438
|
+
else if (eq(cond, getContext().bool_val(false)))
|
|
439
|
+
return rhs;
|
|
440
|
+
else if (isTopAbsValue(lhs) || isTopAbsValue(rhs) || isTopAbsValue(cond))
|
|
441
|
+
return topConstant();
|
|
442
|
+
else
|
|
443
|
+
return ite(static_cast<BoundedZ3Expr>(cond), static_cast<BoundedZ3Expr>(lhs),
|
|
444
|
+
static_cast<BoundedZ3Expr>(rhs));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
friend std::ostream &operator<<(std::ostream &out, const SingleAbsValue &expr)
|
|
448
|
+
{
|
|
449
|
+
out << static_cast<BoundedZ3Expr>(expr);
|
|
450
|
+
return out;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
friend bool eq(const SingleAbsValue &lhs, const SingleAbsValue &rhs)
|
|
454
|
+
{
|
|
455
|
+
return eq(static_cast<BoundedZ3Expr>(lhs), static_cast<BoundedZ3Expr>(rhs));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
inline SingleAbsValue simplify() const
|
|
459
|
+
{
|
|
460
|
+
return getExpr().simplify();
|
|
461
|
+
}
|
|
462
|
+
//%}
|
|
463
|
+
}; // end class ConZ3Expr
|
|
464
|
+
} // end namespace SVF
|
|
465
|
+
|
|
466
|
+
/// Specialise hash for ConZ3Expr
|
|
467
|
+
template<>
|
|
468
|
+
struct std::hash<SVF::SingleAbsValue>
|
|
469
|
+
{
|
|
470
|
+
size_t operator()(const SVF::SingleAbsValue &z3Expr) const
|
|
471
|
+
{
|
|
472
|
+
return z3Expr.hash();
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
#endif //SVF_SINGLEABSVALUE_H
|