svf-tools 1.0.682 → 1.0.684
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 +1 -1
- package/svf/include/AbstractExecution/BoundedZ3Expr.h +353 -0
- package/svf/include/AbstractExecution/IntervalValue.h +54 -46
- package/svf/include/AbstractExecution/NumericLiteral.h +117 -62
- package/svf/lib/SVFIR/SVFIRRW.cpp +3 -2
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -1
- package/svf-llvm/lib/LLVMModule.cpp +123 -151
- package/svf-llvm/lib/SymbolTableBuilder.cpp +159 -116
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.684",
|
|
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
|
{
|