svf-tools 1.0.682 → 1.0.683
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.683",
|
|
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": {
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
//===- AddressValue.h ----Address Value Sets-------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU Affero General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
/*
|
|
23
|
+
* BoundedZ3Expr.h
|
|
24
|
+
*
|
|
25
|
+
* Created on: Mar 20, 2023
|
|
26
|
+
* Author: Xiao Cheng
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#ifndef SVF_BOUNDEDZ3EXPR_H
|
|
31
|
+
#define SVF_BOUNDEDZ3EXPR_H
|
|
32
|
+
|
|
33
|
+
#include "Util/Z3Expr.h"
|
|
34
|
+
|
|
35
|
+
namespace SVF
|
|
36
|
+
{
|
|
37
|
+
|
|
38
|
+
/*!
|
|
39
|
+
* Atom Z3 expr for unlimited precision integers
|
|
40
|
+
*/
|
|
41
|
+
class BoundedZ3Expr : public Z3Expr
|
|
42
|
+
{
|
|
43
|
+
|
|
44
|
+
public:
|
|
45
|
+
BoundedZ3Expr() = default;
|
|
46
|
+
|
|
47
|
+
BoundedZ3Expr(const Z3Expr &z3Expr) : Z3Expr(z3Expr) {}
|
|
48
|
+
|
|
49
|
+
BoundedZ3Expr(const z3::expr &e) : Z3Expr(e) {}
|
|
50
|
+
|
|
51
|
+
BoundedZ3Expr(s32_t i) : Z3Expr(i) {}
|
|
52
|
+
|
|
53
|
+
BoundedZ3Expr(int64_t i) : Z3Expr(getContext().int_val(i)) {}
|
|
54
|
+
|
|
55
|
+
BoundedZ3Expr(const BoundedZ3Expr &z3Expr) : Z3Expr(z3Expr) {}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
inline BoundedZ3Expr &operator=(const BoundedZ3Expr &rhs)
|
|
59
|
+
{
|
|
60
|
+
Z3Expr::operator=(rhs);
|
|
61
|
+
return *this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
BoundedZ3Expr(BoundedZ3Expr &&z3Expr) : Z3Expr(z3Expr) {}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
inline BoundedZ3Expr &operator=(BoundedZ3Expr &&rhs)
|
|
68
|
+
{
|
|
69
|
+
Z3Expr::operator=(rhs);
|
|
70
|
+
return *this;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
bool is_plus_infinite() const
|
|
74
|
+
{
|
|
75
|
+
return eq(*this, getContext().int_const("+oo"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
bool is_minus_infinite() const
|
|
79
|
+
{
|
|
80
|
+
return eq(*this, getContext().int_const("-oo"));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
bool is_infinite() const
|
|
84
|
+
{
|
|
85
|
+
return is_plus_infinite() || is_minus_infinite();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
void set_plus_infinite()
|
|
89
|
+
{
|
|
90
|
+
*this = plus_infinity();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
void set_minus_infinite()
|
|
94
|
+
{
|
|
95
|
+
*this = minus_infinity();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static BoundedZ3Expr plus_infinity()
|
|
99
|
+
{
|
|
100
|
+
return getContext().int_const("+oo");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static BoundedZ3Expr minus_infinity()
|
|
104
|
+
{
|
|
105
|
+
return getContext().int_const("-oo");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static z3::context &getContext()
|
|
109
|
+
{
|
|
110
|
+
return Z3Expr::getContext();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
bool is_zero() const
|
|
114
|
+
{
|
|
115
|
+
return getExpr().is_numeral() && getExpr().get_numeral_int64() == 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static bool isZero(const BoundedZ3Expr &expr)
|
|
119
|
+
{
|
|
120
|
+
return expr.is_numeral() && expr.get_numeral_int64() == 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
BoundedZ3Expr equal(const BoundedZ3Expr &rhs) const
|
|
124
|
+
{
|
|
125
|
+
return getExpr() == rhs.getExpr();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
BoundedZ3Expr leq(const BoundedZ3Expr &rhs) const
|
|
129
|
+
{
|
|
130
|
+
return getExpr() <= rhs.getExpr();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
BoundedZ3Expr geq(const BoundedZ3Expr &rhs) const
|
|
134
|
+
{
|
|
135
|
+
return getExpr() >= rhs.getExpr();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// Reload operator
|
|
139
|
+
//{%
|
|
140
|
+
friend BoundedZ3Expr operator==(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
141
|
+
{
|
|
142
|
+
return lhs.equal(rhs);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
friend BoundedZ3Expr operator!=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
146
|
+
{
|
|
147
|
+
return !lhs.equal(rhs);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
friend BoundedZ3Expr operator>(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
151
|
+
{
|
|
152
|
+
return !lhs.leq(rhs);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
friend BoundedZ3Expr operator<(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
156
|
+
{
|
|
157
|
+
return !lhs.geq(rhs);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
friend BoundedZ3Expr operator<=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
161
|
+
{
|
|
162
|
+
return lhs.leq(rhs);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
friend BoundedZ3Expr operator>=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
166
|
+
{
|
|
167
|
+
return lhs.geq(rhs);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
friend BoundedZ3Expr operator+(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
171
|
+
{
|
|
172
|
+
if (!lhs.is_infinite() && !rhs.is_infinite())
|
|
173
|
+
return lhs.getExpr() + rhs.getExpr();
|
|
174
|
+
else if (!lhs.is_infinite() && rhs.is_infinite())
|
|
175
|
+
return rhs;
|
|
176
|
+
else if (lhs.is_infinite() && !rhs.is_infinite())
|
|
177
|
+
return lhs;
|
|
178
|
+
else if (eq(lhs, rhs))
|
|
179
|
+
return lhs;
|
|
180
|
+
else
|
|
181
|
+
assert(false && "undefined operation +oo + -oo");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
friend BoundedZ3Expr operator-(const BoundedZ3Expr &lhs)
|
|
185
|
+
{
|
|
186
|
+
return -lhs.getExpr();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
friend BoundedZ3Expr operator-(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
190
|
+
{
|
|
191
|
+
if (!lhs.is_infinite() && !rhs.is_infinite())
|
|
192
|
+
return lhs.getExpr() - rhs.getExpr();
|
|
193
|
+
else if (!lhs.is_infinite() && rhs.is_infinite())
|
|
194
|
+
return -rhs;
|
|
195
|
+
else if (lhs.is_infinite() && !rhs.is_infinite())
|
|
196
|
+
return lhs;
|
|
197
|
+
else if (!eq(lhs, rhs))
|
|
198
|
+
return lhs;
|
|
199
|
+
else
|
|
200
|
+
assert(false && "undefined operation +oo - +oo");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
friend BoundedZ3Expr operator*(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
204
|
+
{
|
|
205
|
+
if (lhs.is_zero() || rhs.is_zero()) return 0;
|
|
206
|
+
else if (lhs.is_infinite() && rhs.is_infinite())
|
|
207
|
+
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
208
|
+
else if (lhs.is_infinite())
|
|
209
|
+
return ite(rhs.getExpr() > 0, lhs, -lhs);
|
|
210
|
+
else if (rhs.is_infinite())
|
|
211
|
+
return ite(lhs.getExpr() > 0, rhs, -rhs);
|
|
212
|
+
else
|
|
213
|
+
return lhs.getExpr() * rhs.getExpr();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
friend BoundedZ3Expr operator/(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
217
|
+
{
|
|
218
|
+
if (rhs.is_zero()) assert(false && "divide by zero");
|
|
219
|
+
else if (!lhs.is_infinite() && !rhs.is_infinite())
|
|
220
|
+
return lhs.getExpr() / rhs.getExpr();
|
|
221
|
+
else if (!lhs.is_infinite() && rhs.is_infinite())
|
|
222
|
+
return 0;
|
|
223
|
+
else if (lhs.is_infinite() && !rhs.is_infinite())
|
|
224
|
+
return ite(rhs.getExpr() > 0, lhs, -lhs);
|
|
225
|
+
else
|
|
226
|
+
// TODO: +oo/-oo L'Hôpital's rule?
|
|
227
|
+
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
friend BoundedZ3Expr operator%(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
232
|
+
{
|
|
233
|
+
if (rhs.is_zero()) assert(false && "divide by zero");
|
|
234
|
+
else if (!lhs.is_infinite() && !rhs.is_infinite())
|
|
235
|
+
return lhs.getExpr() % rhs.getExpr();
|
|
236
|
+
else if (!lhs.is_infinite() && rhs.is_infinite())
|
|
237
|
+
return 0;
|
|
238
|
+
// TODO: not sure
|
|
239
|
+
else if (lhs.is_infinite() && !rhs.is_infinite())
|
|
240
|
+
return ite(rhs.getExpr() > 0, lhs, -lhs);
|
|
241
|
+
else
|
|
242
|
+
// TODO: +oo/-oo L'Hôpital's rule?
|
|
243
|
+
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
friend BoundedZ3Expr operator^(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
247
|
+
{
|
|
248
|
+
return bv2int(int2bv(64, lhs.getExpr()) ^ int2bv(64, rhs.getExpr()), true);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
friend BoundedZ3Expr operator&(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
252
|
+
{
|
|
253
|
+
return bv2int(int2bv(64, lhs.getExpr()) & int2bv(64, rhs.getExpr()), true);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
friend BoundedZ3Expr operator|(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
257
|
+
{
|
|
258
|
+
return bv2int(int2bv(64, lhs.getExpr()) | int2bv(64, rhs.getExpr()), true);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
friend BoundedZ3Expr ashr(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
262
|
+
{
|
|
263
|
+
if (lhs.is_zero())
|
|
264
|
+
return lhs;
|
|
265
|
+
else if (lhs.is_infinite())
|
|
266
|
+
return lhs;
|
|
267
|
+
else if (rhs.is_infinite())
|
|
268
|
+
return ite(lhs.getExpr() >= 0, BoundedZ3Expr(0), BoundedZ3Expr(-1));
|
|
269
|
+
else
|
|
270
|
+
return ashr(lhs.getExpr(), rhs.getExpr());
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
friend BoundedZ3Expr shl(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
274
|
+
{
|
|
275
|
+
if (lhs.is_zero())
|
|
276
|
+
return lhs;
|
|
277
|
+
else if (lhs.is_infinite())
|
|
278
|
+
return lhs;
|
|
279
|
+
else if (rhs.is_infinite())
|
|
280
|
+
return ite(lhs.getExpr() >= 0, plus_infinity(), minus_infinity());
|
|
281
|
+
else
|
|
282
|
+
return shl(lhs.getExpr(), rhs.getExpr());
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
friend BoundedZ3Expr lshr(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
286
|
+
{
|
|
287
|
+
return lshr(lhs.getExpr(), rhs.getExpr());
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
friend BoundedZ3Expr int2bv(u32_t n, const BoundedZ3Expr &e)
|
|
291
|
+
{
|
|
292
|
+
return int2bv(n, e.getExpr());
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
friend BoundedZ3Expr bv2int(const BoundedZ3Expr &e, bool isSigned)
|
|
296
|
+
{
|
|
297
|
+
return bv2int(e.getExpr(), isSigned);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
friend BoundedZ3Expr operator&&(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
301
|
+
{
|
|
302
|
+
return lhs.getExpr() && rhs.getExpr();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
friend BoundedZ3Expr operator||(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
306
|
+
{
|
|
307
|
+
return lhs.getExpr() || rhs.getExpr();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
friend BoundedZ3Expr operator!(const BoundedZ3Expr &lhs)
|
|
311
|
+
{
|
|
312
|
+
return !lhs.getExpr();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
friend BoundedZ3Expr ite(const BoundedZ3Expr &cond, const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
316
|
+
{
|
|
317
|
+
return ite(cond.getExpr(), lhs.getExpr(), rhs.getExpr());
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
friend std::ostream &operator<<(std::ostream &out, const BoundedZ3Expr &expr)
|
|
321
|
+
{
|
|
322
|
+
out << expr.getExpr();
|
|
323
|
+
return out;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
friend bool eq(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
|
|
327
|
+
{
|
|
328
|
+
return eq(lhs.getExpr(), rhs.getExpr());
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
inline BoundedZ3Expr simplify() const
|
|
332
|
+
{
|
|
333
|
+
return getExpr().simplify();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
inline bool is_true() const
|
|
337
|
+
{
|
|
338
|
+
return getExpr().is_true();
|
|
339
|
+
}
|
|
340
|
+
//%}
|
|
341
|
+
}; // end class ConZ3Expr
|
|
342
|
+
} // end namespace SVF
|
|
343
|
+
|
|
344
|
+
/// Specialise hash for ConZ3Expr
|
|
345
|
+
template<>
|
|
346
|
+
struct std::hash<SVF::BoundedZ3Expr>
|
|
347
|
+
{
|
|
348
|
+
size_t operator()(const SVF::BoundedZ3Expr &z3Expr) const
|
|
349
|
+
{
|
|
350
|
+
return z3Expr.hash();
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
#endif //SVF_BOUNDEDZ3EXPR_H
|
|
@@ -82,7 +82,7 @@ public:
|
|
|
82
82
|
/// Create the IntervalValue [-oo, +oo]
|
|
83
83
|
static IntervalValue top()
|
|
84
84
|
{
|
|
85
|
-
return IntervalValue(
|
|
85
|
+
return IntervalValue(minus_infinity(), plus_infinity());
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/// Create the bottom IntervalValue
|
|
@@ -92,37 +92,41 @@ public:
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/// Create default IntervalValue
|
|
95
|
-
explicit IntervalValue() : AbstractValue(AbstractValue::IntervalK), _lb(
|
|
95
|
+
explicit IntervalValue() : AbstractValue(AbstractValue::IntervalK), _lb(minus_infinity()), _ub(plus_infinity()) {}
|
|
96
96
|
|
|
97
97
|
/// Create the IntervalValue [n, n]
|
|
98
|
-
explicit IntervalValue(
|
|
98
|
+
explicit IntervalValue(int64_t n) : AbstractValue(AbstractValue::IntervalK), _lb(n), _ub(n) {}
|
|
99
99
|
|
|
100
|
-
explicit IntervalValue(s32_t n) : IntervalValue((
|
|
100
|
+
explicit IntervalValue(s32_t n) : IntervalValue((int64_t) n) {}
|
|
101
101
|
|
|
102
|
-
explicit IntervalValue(u32_t n) : IntervalValue((
|
|
102
|
+
explicit IntervalValue(u32_t n) : IntervalValue((int64_t) n) {}
|
|
103
|
+
|
|
104
|
+
explicit IntervalValue(double n) : IntervalValue((int64_t) n) {}
|
|
105
|
+
|
|
106
|
+
explicit IntervalValue(NumericLiteral n) : IntervalValue(n, n) {}
|
|
103
107
|
|
|
104
108
|
/// Create the IntervalValue [lb, ub]
|
|
105
109
|
explicit IntervalValue(NumericLiteral lb, NumericLiteral ub) : AbstractValue(AbstractValue::IntervalK),
|
|
106
110
|
_lb(std::move(lb)), _ub(std::move(ub)) {}
|
|
107
111
|
|
|
108
|
-
explicit IntervalValue(
|
|
112
|
+
explicit IntervalValue(int64_t lb, int64_t ub) : IntervalValue(NumericLiteral(lb), NumericLiteral(ub)) {}
|
|
109
113
|
|
|
110
|
-
explicit IntervalValue(
|
|
114
|
+
explicit IntervalValue(double lb, double ub) : IntervalValue(NumericLiteral((int64_t) lb), NumericLiteral((int64_t) ub)) {}
|
|
111
115
|
|
|
112
|
-
explicit IntervalValue(
|
|
116
|
+
explicit IntervalValue(s32_t lb, s32_t ub) : IntervalValue((int64_t) lb, (int64_t) ub) {}
|
|
113
117
|
|
|
114
|
-
explicit IntervalValue(
|
|
118
|
+
explicit IntervalValue(u32_t lb, u32_t ub) : IntervalValue((int64_t) lb, (int64_t) ub) {}
|
|
115
119
|
|
|
116
|
-
explicit IntervalValue(u64_t lb, u64_t ub) : IntervalValue((
|
|
120
|
+
explicit IntervalValue(u64_t lb, u64_t ub) : IntervalValue((int64_t) lb, (int64_t) ub) {}
|
|
117
121
|
|
|
118
122
|
/// Copy constructor
|
|
119
123
|
IntervalValue(const IntervalValue &) = default;
|
|
120
124
|
|
|
121
125
|
/// Move constructor
|
|
122
|
-
IntervalValue(IntervalValue &&)
|
|
126
|
+
IntervalValue(IntervalValue &&) = default;
|
|
123
127
|
|
|
124
128
|
/// Copy assignment operator
|
|
125
|
-
IntervalValue &operator=(const IntervalValue &a)
|
|
129
|
+
IntervalValue &operator=(const IntervalValue &a) = default;
|
|
126
130
|
|
|
127
131
|
/// Move assignment operator
|
|
128
132
|
IntervalValue &operator=(IntervalValue &&) = default;
|
|
@@ -256,7 +260,7 @@ public:
|
|
|
256
260
|
}
|
|
257
261
|
|
|
258
262
|
/// Return
|
|
259
|
-
|
|
263
|
+
int64_t getNumeral() const
|
|
260
264
|
{
|
|
261
265
|
assert(is_numeral() && "this IntervalValue is not numeral");
|
|
262
266
|
return _lb.getNumeral();
|
|
@@ -419,7 +423,7 @@ public:
|
|
|
419
423
|
/// Return true if the IntervalValue contains n
|
|
420
424
|
bool contains(int n) const
|
|
421
425
|
{
|
|
422
|
-
return this->_lb.
|
|
426
|
+
return this->_lb.leq(n) && this->_ub.geq(n);
|
|
423
427
|
}
|
|
424
428
|
|
|
425
429
|
void dump(std::ostream &o) const
|
|
@@ -436,7 +440,7 @@ public:
|
|
|
436
440
|
|
|
437
441
|
std::string toString() const
|
|
438
442
|
{
|
|
439
|
-
return "[" +
|
|
443
|
+
return "[" + lb().to_string() + ", " + ub().to_string() + "]";
|
|
440
444
|
}
|
|
441
445
|
|
|
442
446
|
}; // end class IntervalValue
|
|
@@ -491,8 +495,9 @@ inline IntervalValue operator*(const IntervalValue &lhs,
|
|
|
491
495
|
NumericLiteral lu = lhs.lb() * rhs.ub();
|
|
492
496
|
NumericLiteral ul = lhs.ub() * rhs.lb();
|
|
493
497
|
NumericLiteral uu = lhs.ub() * rhs.ub();
|
|
494
|
-
|
|
495
|
-
|
|
498
|
+
std::vector<NumericLiteral> vec{ll, lu, ul, uu};
|
|
499
|
+
return IntervalValue(NumericLiteral::min(vec),
|
|
500
|
+
NumericLiteral::max(vec));
|
|
496
501
|
}
|
|
497
502
|
}
|
|
498
503
|
|
|
@@ -515,8 +520,10 @@ inline IntervalValue operator/(const IntervalValue &lhs,
|
|
|
515
520
|
NumericLiteral lu = lhs.lb() / rhs.ub();
|
|
516
521
|
NumericLiteral ul = lhs.ub() / rhs.lb();
|
|
517
522
|
NumericLiteral uu = lhs.ub() / rhs.ub();
|
|
518
|
-
|
|
519
|
-
|
|
523
|
+
std::vector<NumericLiteral> vec{ll, lu, ul, uu};
|
|
524
|
+
|
|
525
|
+
return IntervalValue(NumericLiteral::min(vec),
|
|
526
|
+
NumericLiteral::max(vec));
|
|
520
527
|
}
|
|
521
528
|
}
|
|
522
529
|
|
|
@@ -538,9 +545,9 @@ inline IntervalValue operator%(const IntervalValue &lhs,
|
|
|
538
545
|
}
|
|
539
546
|
else
|
|
540
547
|
{
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
548
|
+
NumericLiteral n_ub = max(abs(lhs.lb()), abs(lhs.ub()));
|
|
549
|
+
NumericLiteral d_ub = max(abs(rhs.lb()), rhs.ub() - 1);
|
|
550
|
+
NumericLiteral ub = min(n_ub, d_ub);
|
|
544
551
|
|
|
545
552
|
if (lhs.lb().getNumeral() < 0)
|
|
546
553
|
{
|
|
@@ -550,12 +557,12 @@ inline IntervalValue operator%(const IntervalValue &lhs,
|
|
|
550
557
|
}
|
|
551
558
|
else
|
|
552
559
|
{
|
|
553
|
-
return IntervalValue(-ub,
|
|
560
|
+
return IntervalValue(-ub, 0);
|
|
554
561
|
}
|
|
555
562
|
}
|
|
556
563
|
else
|
|
557
564
|
{
|
|
558
|
-
return IntervalValue(
|
|
565
|
+
return IntervalValue(0, ub);
|
|
559
566
|
}
|
|
560
567
|
}
|
|
561
568
|
}
|
|
@@ -580,12 +587,12 @@ inline IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
580
587
|
else
|
|
581
588
|
{
|
|
582
589
|
// lhs[3,4] rhs[1,2]
|
|
583
|
-
if (lhs.lb().
|
|
590
|
+
if (!lhs.lb().leq(rhs.ub()))
|
|
584
591
|
{
|
|
585
592
|
return IntervalValue(1, 1);
|
|
586
593
|
// lhs[1,2] rhs[3,4]
|
|
587
594
|
}
|
|
588
|
-
else if (lhs.ub().
|
|
595
|
+
else if (lhs.ub().geq(rhs.lb()))
|
|
589
596
|
{
|
|
590
597
|
return IntervalValue(0, 0);
|
|
591
598
|
}
|
|
@@ -618,12 +625,12 @@ inline IntervalValue operator<(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
618
625
|
else
|
|
619
626
|
{
|
|
620
627
|
// lhs [1,2] rhs [3,4]
|
|
621
|
-
if (lhs.ub().
|
|
628
|
+
if (!lhs.ub().geq(rhs.lb()))
|
|
622
629
|
{
|
|
623
630
|
return IntervalValue(1, 1);
|
|
624
631
|
// lhs [3,4] rhs [1,2]
|
|
625
632
|
}
|
|
626
|
-
else if (lhs.lb().
|
|
633
|
+
else if (!lhs.lb().leq(rhs.ub()))
|
|
627
634
|
{
|
|
628
635
|
return IntervalValue(0, 0);
|
|
629
636
|
// lhs [1,3] rhs [2,4]
|
|
@@ -657,12 +664,12 @@ inline IntervalValue operator>=(const IntervalValue &lhs, const IntervalValue &r
|
|
|
657
664
|
else
|
|
658
665
|
{
|
|
659
666
|
// lhs [2,3] rhs [1,2]
|
|
660
|
-
if (lhs.lb().
|
|
667
|
+
if (lhs.lb().geq(rhs.ub()))
|
|
661
668
|
{
|
|
662
669
|
return IntervalValue(1, 1);
|
|
663
670
|
// lhs [1,2] rhs[3,4]
|
|
664
671
|
}
|
|
665
|
-
else if (lhs.ub().
|
|
672
|
+
else if (!lhs.ub().geq(rhs.lb()))
|
|
666
673
|
{
|
|
667
674
|
return IntervalValue(0, 0);
|
|
668
675
|
// lhs [1,3] rhs [2,4]
|
|
@@ -696,12 +703,12 @@ inline IntervalValue operator<=(const IntervalValue &lhs, const IntervalValue &r
|
|
|
696
703
|
else
|
|
697
704
|
{
|
|
698
705
|
// lhs [1,2] rhs [2,3]
|
|
699
|
-
if (lhs.ub().
|
|
706
|
+
if (lhs.ub().leq(rhs.lb()))
|
|
700
707
|
{
|
|
701
708
|
return IntervalValue(1, 1);
|
|
702
709
|
// lhs [3,4] rhs[1,2]
|
|
703
710
|
}
|
|
704
|
-
else if (lhs.lb().
|
|
711
|
+
else if (!lhs.lb().leq(rhs.ub()))
|
|
705
712
|
{
|
|
706
713
|
return IntervalValue(0, 0);
|
|
707
714
|
// lhs [1,3] rhs [2,4]
|
|
@@ -765,8 +772,9 @@ inline IntervalValue operator>>(const IntervalValue &lhs, const IntervalValue &r
|
|
|
765
772
|
NumericLiteral lu = lhs.lb() >> shift.ub();
|
|
766
773
|
NumericLiteral ul = lhs.ub() >> shift.lb();
|
|
767
774
|
NumericLiteral uu = lhs.ub() >> shift.ub();
|
|
768
|
-
|
|
769
|
-
|
|
775
|
+
std::vector<NumericLiteral> vec{ll, lu, ul, uu};
|
|
776
|
+
return IntervalValue(NumericLiteral::min(vec),
|
|
777
|
+
NumericLiteral::max(vec));
|
|
770
778
|
}
|
|
771
779
|
}
|
|
772
780
|
}
|
|
@@ -778,19 +786,19 @@ inline IntervalValue operator&(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
778
786
|
return IntervalValue::bottom();
|
|
779
787
|
else if (lhs.is_numeral() && rhs.is_numeral())
|
|
780
788
|
{
|
|
781
|
-
return IntervalValue(
|
|
789
|
+
return IntervalValue(lhs.lb() & rhs.lb());
|
|
782
790
|
}
|
|
783
791
|
else if (lhs.lb().getNumeral() >= 0 && rhs.lb().getNumeral() >= 0)
|
|
784
792
|
{
|
|
785
|
-
return IntervalValue(0
|
|
793
|
+
return IntervalValue((int64_t) 0, min(lhs.ub(), rhs.ub()));
|
|
786
794
|
}
|
|
787
795
|
else if (lhs.lb().getNumeral() >= 0)
|
|
788
796
|
{
|
|
789
|
-
return IntervalValue(0
|
|
797
|
+
return IntervalValue((int64_t) 0, lhs.ub());
|
|
790
798
|
}
|
|
791
799
|
else if (rhs.lb().getNumeral() >= 0)
|
|
792
800
|
{
|
|
793
|
-
return IntervalValue(0
|
|
801
|
+
return IntervalValue((int64_t) 0, rhs.ub());
|
|
794
802
|
}
|
|
795
803
|
else
|
|
796
804
|
{
|
|
@@ -813,13 +821,13 @@ inline IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
813
821
|
if (lhs.isBottom() || rhs.isBottom())
|
|
814
822
|
return IntervalValue::bottom();
|
|
815
823
|
else if (lhs.is_numeral() && rhs.is_numeral())
|
|
816
|
-
return IntervalValue(
|
|
824
|
+
return IntervalValue(lhs.lb() | rhs.lb());
|
|
817
825
|
else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() &&
|
|
818
826
|
rhs.lb().getNumeral() >= 0 && !rhs.ub().is_infinity())
|
|
819
827
|
{
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
return IntervalValue(0
|
|
828
|
+
int64_t m = std::max(lhs.ub().getNumeral(), rhs.ub().getNumeral());
|
|
829
|
+
int64_t ub = next_power_of_2(s64_t(m+1));
|
|
830
|
+
return IntervalValue((int64_t) 0, (int64_t) ub);
|
|
823
831
|
}
|
|
824
832
|
else
|
|
825
833
|
{
|
|
@@ -842,13 +850,13 @@ inline IntervalValue operator^(const IntervalValue &lhs, const IntervalValue &rh
|
|
|
842
850
|
if (lhs.isBottom() || rhs.isBottom())
|
|
843
851
|
return IntervalValue::bottom();
|
|
844
852
|
else if (lhs.is_numeral() && rhs.is_numeral())
|
|
845
|
-
return IntervalValue(
|
|
853
|
+
return IntervalValue(lhs.lb() ^ rhs.lb());
|
|
846
854
|
else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() &&
|
|
847
855
|
rhs.lb().getNumeral() >= 0 && !rhs.ub().is_infinity())
|
|
848
856
|
{
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
return IntervalValue(0
|
|
857
|
+
int64_t m = std::max(lhs.ub().getNumeral(), rhs.ub().getNumeral());
|
|
858
|
+
int64_t ub = next_power_of_2(s64_t(m+1));
|
|
859
|
+
return IntervalValue((int64_t) 0, (int64_t) ub);
|
|
852
860
|
}
|
|
853
861
|
else
|
|
854
862
|
{
|
|
@@ -30,70 +30,78 @@
|
|
|
30
30
|
#ifndef Z3_EXAMPLE_Number_H
|
|
31
31
|
#define Z3_EXAMPLE_Number_H
|
|
32
32
|
|
|
33
|
+
#include <utility>
|
|
34
|
+
|
|
33
35
|
#include "SVFIR/SVFType.h"
|
|
36
|
+
#include "AbstractExecution/BoundedZ3Expr.h"
|
|
34
37
|
|
|
35
38
|
namespace SVF
|
|
36
39
|
{
|
|
37
40
|
class NumericLiteral
|
|
38
41
|
{
|
|
39
42
|
private:
|
|
40
|
-
|
|
43
|
+
BoundedZ3Expr _n;
|
|
41
44
|
|
|
42
45
|
public:
|
|
43
46
|
/// Default constructor
|
|
44
47
|
NumericLiteral() = delete;
|
|
45
48
|
|
|
46
|
-
/// Create a new NumericLiteral from double
|
|
47
|
-
NumericLiteral(double n) : _n(n) {}
|
|
48
|
-
|
|
49
49
|
/// Create a new NumericLiteral from s32_t
|
|
50
|
-
NumericLiteral(s32_t n) : _n(n) {}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
NumericLiteral(const Z3Expr &z3Expr) : _n(z3Expr) {}
|
|
52
|
+
|
|
53
|
+
NumericLiteral(const z3::expr &e) : _n(e) {}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
NumericLiteral(u32_t n) : _n(n) {}
|
|
55
|
+
NumericLiteral(s32_t i) : _n(i) {}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
NumericLiteral(int64_t i) : _n(i) {}
|
|
58
|
+
|
|
59
|
+
NumericLiteral(BoundedZ3Expr z3Expr) : _n(std::move(z3Expr)) {}
|
|
60
60
|
|
|
61
61
|
virtual ~NumericLiteral() = default;
|
|
62
62
|
|
|
63
63
|
/// Copy Constructor
|
|
64
|
-
NumericLiteral(const NumericLiteral &)
|
|
64
|
+
NumericLiteral(const NumericLiteral &) = default;
|
|
65
65
|
|
|
66
66
|
/// Move Constructor
|
|
67
|
-
NumericLiteral(NumericLiteral &&)
|
|
67
|
+
NumericLiteral(NumericLiteral &&) = default;
|
|
68
68
|
|
|
69
69
|
/// Operator = , another Copy Constructor
|
|
70
|
-
inline NumericLiteral &operator=(const NumericLiteral &)
|
|
70
|
+
inline NumericLiteral &operator=(const NumericLiteral &) = default;
|
|
71
71
|
|
|
72
72
|
/// Operator = , another Move Constructor
|
|
73
|
-
inline NumericLiteral &operator=(NumericLiteral &&)
|
|
73
|
+
inline NumericLiteral &operator=(NumericLiteral &&) = default;
|
|
74
|
+
|
|
75
|
+
static NumericLiteral plus_infinity()
|
|
76
|
+
{
|
|
77
|
+
return BoundedZ3Expr::plus_infinity();
|
|
78
|
+
}
|
|
74
79
|
|
|
75
|
-
/// Get minus infinity -oo
|
|
76
80
|
static NumericLiteral minus_infinity()
|
|
77
81
|
{
|
|
78
|
-
return
|
|
82
|
+
return BoundedZ3Expr::minus_infinity();
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
static NumericLiteral plus_infinity()
|
|
85
|
+
static z3::context &getContext()
|
|
83
86
|
{
|
|
84
|
-
return
|
|
87
|
+
return BoundedZ3Expr::getContext();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const std::string to_string() const
|
|
91
|
+
{
|
|
92
|
+
return _n.to_string();
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
/// Check if this is minus infinity
|
|
88
96
|
inline bool is_minus_infinity() const
|
|
89
97
|
{
|
|
90
|
-
return _n
|
|
98
|
+
return _n.is_minus_infinite();
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
/// Check if this is plus infinity
|
|
94
102
|
inline bool is_plus_infinity() const
|
|
95
103
|
{
|
|
96
|
-
return _n
|
|
104
|
+
return _n.is_plus_infinite();
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
/// Check if this is infinity (either of plus/minus)
|
|
@@ -105,13 +113,34 @@ public:
|
|
|
105
113
|
/// Check if this is zero
|
|
106
114
|
inline bool is_zero() const
|
|
107
115
|
{
|
|
108
|
-
return _n
|
|
116
|
+
return _n.is_zero();
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
/// Return Numeral
|
|
112
|
-
inline
|
|
120
|
+
inline int64_t getNumeral() const
|
|
113
121
|
{
|
|
114
|
-
|
|
122
|
+
if (_n.is_numeral())
|
|
123
|
+
{
|
|
124
|
+
int64_t i;
|
|
125
|
+
if(_n.getExpr().is_numeral_i64(i))
|
|
126
|
+
return _n.get_numeral_int64();
|
|
127
|
+
else
|
|
128
|
+
{
|
|
129
|
+
return leq(0) ? INT64_MIN : INT64_MAX;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (is_minus_infinity())
|
|
133
|
+
{
|
|
134
|
+
return INT64_MIN;
|
|
135
|
+
}
|
|
136
|
+
else if (is_plus_infinity())
|
|
137
|
+
{
|
|
138
|
+
return INT64_MAX;
|
|
139
|
+
}
|
|
140
|
+
else
|
|
141
|
+
{
|
|
142
|
+
assert(false && "other literal?");
|
|
143
|
+
}
|
|
115
144
|
}
|
|
116
145
|
|
|
117
146
|
/// Check two object is equal
|
|
@@ -134,7 +163,13 @@ public:
|
|
|
134
163
|
return rhs.is_plus_infinity();
|
|
135
164
|
}
|
|
136
165
|
}
|
|
137
|
-
|
|
166
|
+
if(is_infinity() && rhs.is_infinity())
|
|
167
|
+
{
|
|
168
|
+
if(is_minus_infinity()) return true;
|
|
169
|
+
else return rhs.is_plus_infinity();
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
return _n.leq(rhs._n).simplify().is_true();
|
|
138
173
|
}
|
|
139
174
|
|
|
140
175
|
// Greater than or equal
|
|
@@ -151,7 +186,13 @@ public:
|
|
|
151
186
|
return rhs.is_minus_infinity();
|
|
152
187
|
}
|
|
153
188
|
}
|
|
154
|
-
|
|
189
|
+
if(is_infinity() && rhs.is_infinity())
|
|
190
|
+
{
|
|
191
|
+
if(is_plus_infinity()) return true;
|
|
192
|
+
else return rhs.is_minus_infinity();
|
|
193
|
+
}
|
|
194
|
+
else
|
|
195
|
+
return _n.geq(rhs._n).simplify().is_true();
|
|
155
196
|
}
|
|
156
197
|
|
|
157
198
|
|
|
@@ -159,38 +200,38 @@ public:
|
|
|
159
200
|
//{%
|
|
160
201
|
friend NumericLiteral operator==(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
161
202
|
{
|
|
162
|
-
return eq(lhs, rhs);
|
|
203
|
+
return eq(lhs, rhs) ? 1 : 0;
|
|
163
204
|
}
|
|
164
205
|
|
|
165
206
|
friend NumericLiteral operator!=(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
166
207
|
{
|
|
167
|
-
return !eq(lhs, rhs);
|
|
208
|
+
return !eq(lhs, rhs) ? 1 : 0;
|
|
168
209
|
}
|
|
169
210
|
|
|
170
211
|
friend NumericLiteral operator>(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
171
212
|
{
|
|
172
|
-
return !lhs.leq(rhs);
|
|
213
|
+
return (!lhs.leq(rhs)) ? 1 : 0;
|
|
173
214
|
}
|
|
174
215
|
|
|
175
216
|
friend NumericLiteral operator<(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
176
217
|
{
|
|
177
|
-
return !lhs.geq(rhs);
|
|
218
|
+
return (!lhs.geq(rhs)) ? 1 : 0;
|
|
178
219
|
}
|
|
179
220
|
|
|
180
221
|
friend NumericLiteral operator<=(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
181
222
|
{
|
|
182
|
-
return lhs.leq(rhs);
|
|
223
|
+
return lhs.leq(rhs) ? 1 : 0;
|
|
183
224
|
}
|
|
184
225
|
|
|
185
226
|
friend NumericLiteral operator>=(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
186
227
|
{
|
|
187
|
-
return lhs.geq(rhs);
|
|
228
|
+
return lhs.geq(rhs) ? 1 : 0;
|
|
188
229
|
}
|
|
189
230
|
|
|
190
|
-
friend NumericLiteral operator+(const NumericLiteral&
|
|
231
|
+
friend NumericLiteral operator+(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
191
232
|
{
|
|
192
233
|
if (!lhs.is_infinity() && !rhs.is_infinity())
|
|
193
|
-
return lhs.
|
|
234
|
+
return (lhs._n + rhs._n).simplify();
|
|
194
235
|
else if (!lhs.is_infinity() && rhs.is_infinity())
|
|
195
236
|
return rhs;
|
|
196
237
|
else if (lhs.is_infinity() && !rhs.is_infinity())
|
|
@@ -207,7 +248,7 @@ public:
|
|
|
207
248
|
friend NumericLiteral operator-(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
208
249
|
{
|
|
209
250
|
if (!lhs.is_infinity() && !rhs.is_infinity())
|
|
210
|
-
return lhs.
|
|
251
|
+
return (lhs._n - rhs._n).simplify();
|
|
211
252
|
else if (!lhs.is_infinity() && rhs.is_infinity())
|
|
212
253
|
return -rhs;
|
|
213
254
|
else if (lhs.is_infinity() && !rhs.is_infinity())
|
|
@@ -228,11 +269,11 @@ public:
|
|
|
228
269
|
else if (lhs.is_infinity() && rhs.is_infinity())
|
|
229
270
|
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
230
271
|
else if (lhs.is_infinity())
|
|
231
|
-
return rhs.
|
|
272
|
+
return !rhs.leq(0) ? lhs : -lhs;
|
|
232
273
|
else if (rhs.is_infinity())
|
|
233
|
-
return lhs.
|
|
274
|
+
return !lhs.leq(0) ? rhs : -rhs;
|
|
234
275
|
else
|
|
235
|
-
return lhs.
|
|
276
|
+
return (lhs._n * rhs._n).simplify();
|
|
236
277
|
}
|
|
237
278
|
|
|
238
279
|
friend NumericLiteral operator/(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
@@ -244,11 +285,11 @@ public:
|
|
|
244
285
|
abort();
|
|
245
286
|
}
|
|
246
287
|
else if (!lhs.is_infinity() && !rhs.is_infinity())
|
|
247
|
-
return lhs.
|
|
288
|
+
return (lhs._n / rhs._n).simplify();
|
|
248
289
|
else if (!lhs.is_infinity() && rhs.is_infinity())
|
|
249
290
|
return 0;
|
|
250
291
|
else if (lhs.is_infinity() && !rhs.is_infinity())
|
|
251
|
-
return rhs.
|
|
292
|
+
return !rhs.leq(0) ? lhs : -lhs;
|
|
252
293
|
else
|
|
253
294
|
// TODO: +oo/-oo L'Hôpital's rule?
|
|
254
295
|
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
@@ -262,12 +303,12 @@ public:
|
|
|
262
303
|
abort();
|
|
263
304
|
}
|
|
264
305
|
else if (!lhs.is_infinity() && !rhs.is_infinity())
|
|
265
|
-
return (
|
|
306
|
+
return (lhs._n % rhs._n).simplify();
|
|
266
307
|
else if (!lhs.is_infinity() && rhs.is_infinity())
|
|
267
308
|
return 0;
|
|
268
309
|
// TODO: not sure
|
|
269
310
|
else if (lhs.is_infinity() && !rhs.is_infinity())
|
|
270
|
-
return rhs.
|
|
311
|
+
return !rhs.leq(0) ? lhs : -lhs;
|
|
271
312
|
else
|
|
272
313
|
// TODO: +oo/-oo L'Hôpital's rule?
|
|
273
314
|
return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
|
|
@@ -276,17 +317,17 @@ public:
|
|
|
276
317
|
// TODO: logic operation for infinity?
|
|
277
318
|
friend NumericLiteral operator^(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
278
319
|
{
|
|
279
|
-
return (
|
|
320
|
+
return (lhs._n ^ rhs._n).simplify();
|
|
280
321
|
}
|
|
281
322
|
|
|
282
323
|
friend NumericLiteral operator&(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
283
324
|
{
|
|
284
|
-
return (
|
|
325
|
+
return (lhs._n & rhs._n).simplify();
|
|
285
326
|
}
|
|
286
327
|
|
|
287
328
|
friend NumericLiteral operator|(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
288
329
|
{
|
|
289
|
-
return (
|
|
330
|
+
return (lhs._n | rhs._n).simplify();
|
|
290
331
|
}
|
|
291
332
|
|
|
292
333
|
friend NumericLiteral operator>>(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
@@ -297,7 +338,7 @@ public:
|
|
|
297
338
|
else if (lhs.is_infinity())
|
|
298
339
|
return lhs;
|
|
299
340
|
else if (rhs.is_infinity())
|
|
300
|
-
return lhs.
|
|
341
|
+
return lhs.geq(0) ? 0 : -1;
|
|
301
342
|
else
|
|
302
343
|
return (s32_t) lhs.getNumeral() >> (s32_t) rhs.getNumeral();
|
|
303
344
|
}
|
|
@@ -310,35 +351,44 @@ public:
|
|
|
310
351
|
else if (lhs.is_infinity())
|
|
311
352
|
return lhs;
|
|
312
353
|
else if (rhs.is_infinity())
|
|
313
|
-
return lhs.
|
|
354
|
+
return lhs.geq(0) ? plus_infinity() : minus_infinity();
|
|
314
355
|
else
|
|
315
356
|
return (s32_t) lhs.getNumeral() << (s32_t) rhs.getNumeral();
|
|
316
357
|
}
|
|
317
358
|
|
|
318
359
|
friend NumericLiteral operator&&(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
319
360
|
{
|
|
320
|
-
return lhs.
|
|
361
|
+
return (lhs._n && rhs._n).simplify();
|
|
321
362
|
}
|
|
322
363
|
|
|
323
364
|
friend NumericLiteral operator||(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
324
365
|
{
|
|
325
|
-
return lhs.
|
|
366
|
+
return (lhs._n || rhs._n).simplify();
|
|
326
367
|
}
|
|
327
368
|
|
|
328
369
|
friend NumericLiteral operator!(const NumericLiteral &lhs)
|
|
329
370
|
{
|
|
330
|
-
return !lhs.
|
|
371
|
+
return (!lhs._n).simplify();
|
|
331
372
|
}
|
|
332
373
|
|
|
333
374
|
friend NumericLiteral operator-(const NumericLiteral &lhs)
|
|
334
375
|
{
|
|
335
|
-
|
|
376
|
+
if (lhs.is_plus_infinity())
|
|
377
|
+
{
|
|
378
|
+
return minus_infinity();
|
|
379
|
+
}
|
|
380
|
+
else if (lhs.is_minus_infinity())
|
|
381
|
+
{
|
|
382
|
+
return plus_infinity();
|
|
383
|
+
}
|
|
384
|
+
else
|
|
385
|
+
return (-lhs._n).simplify();
|
|
336
386
|
}
|
|
337
387
|
|
|
338
388
|
/// Return ite? lhs : rhs
|
|
339
389
|
friend NumericLiteral ite(const NumericLiteral &cond, const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
340
390
|
{
|
|
341
|
-
return cond.
|
|
391
|
+
return ite(cond._n, lhs._n, rhs._n).simplify();
|
|
342
392
|
}
|
|
343
393
|
|
|
344
394
|
friend std::ostream &operator<<(std::ostream &out, const NumericLiteral &expr)
|
|
@@ -348,29 +398,34 @@ public:
|
|
|
348
398
|
else if (expr.is_minus_infinity())
|
|
349
399
|
out << "-INF";
|
|
350
400
|
else
|
|
351
|
-
out <<
|
|
401
|
+
out << expr._n;
|
|
352
402
|
return out;
|
|
353
403
|
}
|
|
354
404
|
|
|
355
405
|
friend bool eq(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
356
406
|
{
|
|
357
|
-
return lhs._n
|
|
407
|
+
return eq(lhs._n, rhs._n);
|
|
358
408
|
}
|
|
359
409
|
|
|
360
410
|
friend NumericLiteral min(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
361
411
|
{
|
|
362
|
-
return
|
|
412
|
+
return lhs.leq(rhs) ? lhs : rhs;
|
|
363
413
|
}
|
|
364
414
|
|
|
365
415
|
friend NumericLiteral max(const NumericLiteral &lhs, const NumericLiteral &rhs)
|
|
366
416
|
{
|
|
367
|
-
return
|
|
417
|
+
return lhs.leq(rhs) ? rhs : lhs;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
friend NumericLiteral abs(const NumericLiteral &lhs)
|
|
421
|
+
{
|
|
422
|
+
return lhs.leq(0) ? -lhs : lhs;
|
|
368
423
|
}
|
|
369
424
|
|
|
370
425
|
// TODO: how to use initializer_list as argument?
|
|
371
|
-
|
|
426
|
+
static NumericLiteral min(std::vector<NumericLiteral>& _l)
|
|
372
427
|
{
|
|
373
|
-
NumericLiteral ret(
|
|
428
|
+
NumericLiteral ret(plus_infinity());
|
|
374
429
|
for (const auto &it: _l)
|
|
375
430
|
{
|
|
376
431
|
if (it.is_minus_infinity())
|
|
@@ -383,9 +438,9 @@ public:
|
|
|
383
438
|
return ret;
|
|
384
439
|
}
|
|
385
440
|
|
|
386
|
-
|
|
441
|
+
static NumericLiteral max(std::vector<NumericLiteral>& _l)
|
|
387
442
|
{
|
|
388
|
-
NumericLiteral ret(
|
|
443
|
+
NumericLiteral ret(minus_infinity());
|
|
389
444
|
for (const auto &it: _l)
|
|
390
445
|
{
|
|
391
446
|
if (it.is_plus_infinity())
|
|
@@ -401,6 +456,6 @@ public:
|
|
|
401
456
|
//%}
|
|
402
457
|
|
|
403
458
|
|
|
404
|
-
}; // end class
|
|
459
|
+
}; // end class NumericLiteral
|
|
405
460
|
} // end namespace SVF
|
|
406
461
|
#endif //Z3_EXAMPLE_Number_H
|