Skip to content

Commit b1e7d5e

Browse files
committed
use only generic conversion functions
Signed-off-by: Elazar Gershuni <[email protected]>
1 parent 281e418 commit b1e7d5e

8 files changed

+83
-134
lines changed

src/crab/array_domain.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ static std::optional<std::pair<offset_t, unsigned>> kill_and_find_var(NumAbsDoma
583583
bool array_domain_t::all_num(NumAbsDomain& inv, const linear_expression_t& lb, const linear_expression_t& ub) {
584584
auto min_lb = inv.eval_interval(lb).lb().number();
585585
auto max_ub = inv.eval_interval(ub).ub().number();
586-
if (!min_lb || !max_ub || !min_lb->fits_sint32() || !max_ub->fits_sint32()) {
586+
if (!min_lb || !max_ub || !min_lb->fits<int32_t>() || !max_ub->fits<int32_t>()) {
587587
return false;
588588
}
589589

@@ -601,7 +601,7 @@ bool array_domain_t::all_num(NumAbsDomain& inv, const linear_expression_t& lb, c
601601
int array_domain_t::min_all_num_size(const NumAbsDomain& inv, variable_t offset) const {
602602
auto min_lb = inv.eval_interval(offset).lb().number();
603603
auto max_ub = inv.eval_interval(offset).ub().number();
604-
if (!min_lb || !max_ub || !min_lb->fits_sint32() || !max_ub->fits_sint32()) {
604+
if (!min_lb || !max_ub || !min_lb->fits<int32_t>() || !max_ub->fits<int32_t>()) {
605605
return 0;
606606
}
607607
auto lb = (int)min_lb.value();
@@ -616,7 +616,7 @@ std::optional<uint8_t> get_value_byte(NumAbsDomain& inv, offset_t o, int width)
616616
if (!t) {
617617
return {};
618618
}
619-
uint64_t n = t->cast_to_uint64();
619+
uint64_t n = t->cast_to<uint64_t>();
620620

621621
// Convert value to bytes of the appropriate endian-ness.
622622
switch (width) {
@@ -751,7 +751,7 @@ std::optional<linear_expression_t> array_domain_t::load(NumAbsDomain& inv, data_
751751
auto ub = ii.ub().number();
752752
if (lb.has_value() && ub.has_value()) {
753753
z_number fullwidth = ub.value() - lb.value() + width;
754-
if (lb.value().fits_uint32() && fullwidth.fits_uint32()) {
754+
if (lb.value().fits<uint32_t>() && fullwidth.fits<uint32_t>()) {
755755
auto [only_num, only_non_num] = num_bytes.uniformity((uint32_t)lb.value(), (uint32_t)fullwidth);
756756
if (only_num) {
757757
return number_t{T_NUM};

src/crab/ebpf_domain.cpp

+34-34
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,23 @@ static std::vector<linear_constraint_t> assume_bit_cst_interval(const NumAbsDoma
103103

104104
auto dst_interval = inv.eval_interval(dst_uvalue);
105105
std::optional<number_t> dst_n = dst_interval.singleton();
106-
if (!dst_n || !dst_n.value().fits_cast_to_int64()) {
106+
if (!dst_n || !dst_n.value().fits_cast_to<int64_t>()) {
107107
return {};
108108
}
109109

110110
std::optional<number_t> src_n = src_interval.singleton();
111-
if (!src_n || !src_n->fits_cast_to_int64()) {
111+
if (!src_n || !src_n->fits_cast_to<int64_t>()) {
112112
return {};
113113
}
114-
uint64_t src_int_value = src_n.value().cast_to_uint64();
114+
uint64_t src_int_value = src_n.value().cast_to<uint64_t>();
115115
if (!is64) {
116116
src_int_value = (uint32_t)src_int_value;
117117
}
118118

119119
bool result;
120120
switch (op) {
121-
case Op::SET: result = ((dst_n.value().cast_to_uint64() & src_int_value) != 0); break;
122-
case Op::NSET: result = ((dst_n.value().cast_to_uint64() & src_int_value) == 0); break;
121+
case Op::SET: result = ((dst_n.value().cast_to<uint64_t>() & src_int_value) != 0); break;
122+
case Op::NSET: result = ((dst_n.value().cast_to<uint64_t>() & src_int_value) == 0); break;
123123
default: throw std::exception();
124124
}
125125

@@ -148,11 +148,11 @@ static std::vector<linear_constraint_t> assume_signed_32bit_eq(const NumAbsDomai
148148
// Find the lowest 64-bit svalue whose low 32 bits match the singleton.
149149

150150
// Get lower bound as a 64-bit value.
151-
int64_t lb = inv.eval_interval(left_svalue).lb().number()->cast_to_sint64();
151+
int64_t lb = inv.eval_interval(left_svalue).lb().number()->cast_to<int64_t>();
152152

153153
// Use the high 32-bits from the left lower bound and the low 32-bits from the right singleton.
154154
// The result might be lower than the lower bound.
155-
int64_t lb_match = ((lb & 0xFFFFFFFF00000000) | (rn->cast_to_sint64() & 0xFFFFFFFF));
155+
int64_t lb_match = ((lb & 0xFFFFFFFF00000000) | (rn->cast_to<int64_t>() & 0xFFFFFFFF));
156156
if (lb_match < lb) {
157157
// The result is lower than the left interval, so try the next higher matching 64-bit value.
158158
// It's ok if this goes higher than the left upper bound.
@@ -162,11 +162,11 @@ static std::vector<linear_constraint_t> assume_signed_32bit_eq(const NumAbsDomai
162162
// Find the highest 64-bit svalue whose low 32 bits match the singleton.
163163

164164
// Get upper bound as a 64-bit value.
165-
int64_t ub = inv.eval_interval(left_svalue).ub().number()->cast_to_sint64();
165+
int64_t ub = inv.eval_interval(left_svalue).ub().number()->cast_to<int64_t>();
166166

167167
// Use the high 32-bits from the left upper bound and the low 32-bits from the right singleton.
168168
// The result might be higher than the upper bound.
169-
int64_t ub_match = ((ub & 0xFFFFFFFF00000000) | (rn->cast_to_sint64() & 0xFFFFFFFF));
169+
int64_t ub_match = ((ub & 0xFFFFFFFF00000000) | (rn->cast_to<int64_t>() & 0xFFFFFFFF));
170170
if (ub_match > ub) {
171171
// The result is higher than the left interval, so try the next lower matching 64-bit value.
172172
// It's ok if this goes lower than the left lower bound.
@@ -1514,8 +1514,8 @@ void ebpf_domain_t::operator()(const Un& stmt) {
15141514
if (m_inv.entail(type_is_number(stmt.dst))) {
15151515
auto interval = m_inv.eval_interval(v);
15161516
if (std::optional<number_t> n = interval.singleton()) {
1517-
if (n->fits_cast_to_int64()) {
1518-
input = (decltype(input))n.value().cast_to_sint64();
1517+
if (n->fits_cast_to<int64_t>()) {
1518+
input = (decltype(input))n.value().cast_to<int64_t>();
15191519
decltype(input) output = be_or_le(input);
15201520
m_inv.set(v, crab::interval_t(number_t(output), number_t(output)));
15211521
return;
@@ -1663,9 +1663,9 @@ void ebpf_domain_t::operator()(const FuncConstraint& s) {
16631663
const reg_pack_t& reg = reg_pack(s.reg);
16641664
auto src_interval = m_inv.eval_interval(reg.svalue);
16651665
if (auto sn = src_interval.singleton()) {
1666-
if (sn->fits_sint32()) {
1666+
if (sn->fits<int32_t>()) {
16671667
// We can now process it as if the id was immediate.
1668-
int32_t imm = sn->cast_to_sint32();
1668+
int32_t imm = sn->cast_to<int32_t>();
16691669
if (!global_program_info->platform->is_helper_usable(imm)) {
16701670
require(m_inv, linear_constraint_t::false_const(), "invalid helper function id " + std::to_string(imm));
16711671
return;
@@ -1693,7 +1693,7 @@ bool ebpf_domain_t::get_map_fd_range(const Reg& map_fd_reg, int32_t* start_fd, i
16931693
const crab::interval_t& map_fd_interval = m_inv[reg_pack(map_fd_reg).map_fd];
16941694
auto lb = map_fd_interval.lb().number();
16951695
auto ub = map_fd_interval.ub().number();
1696-
if (!lb || !lb->fits_sint32() || !ub || !ub->fits_sint32()) {
1696+
if (!lb || !lb->fits<int32_t>() || !ub || !ub->fits<int32_t>()) {
16971697
return false;
16981698
}
16991699
*start_fd = (int32_t)lb.value();
@@ -1841,9 +1841,9 @@ void ebpf_domain_t::operator()(const ValidMapKeyValue& s) {
18411841
linear_expression_t ub = lb + width;
18421842
if (!stack.all_num(inv, lb, ub)) {
18431843
auto lb_is = inv[lb].lb().number();
1844-
std::string lb_s = lb_is && lb_is->fits_sint32() ? std::to_string((int32_t)*lb_is) : "-oo";
1844+
std::string lb_s = lb_is && lb_is->fits<int32_t>() ? std::to_string((int32_t)*lb_is) : "-oo";
18451845
auto ub_is = inv.eval_interval(ub).ub().number();
1846-
std::string ub_s = ub_is && ub_is->fits_sint32() ? std::to_string((int32_t)*ub_is) : "oo";
1846+
std::string ub_s = ub_is && ub_is->fits<int32_t>() ? std::to_string((int32_t)*ub_is) : "oo";
18471847
require(inv, linear_constraint_t::false_const(),
18481848
"Illegal map update with a non-numerical value [" + lb_s + "-" + ub_s + ")");
18491849
} else if (thread_local_options.strict && fd_type.has_value()) {
@@ -2478,9 +2478,9 @@ void ebpf_domain_t::operator()(const Callx& callx) {
24782478
const reg_pack_t& reg = reg_pack(callx.func);
24792479
auto src_interval = m_inv.eval_interval(reg.svalue);
24802480
if (auto sn = src_interval.singleton()) {
2481-
if (sn->fits_sint32()) {
2481+
if (sn->fits<int32_t>()) {
24822482
// We can now process it as if the id was immediate.
2483-
int32_t imm = sn->cast_to_sint32();
2483+
int32_t imm = sn->cast_to<int32_t>();
24842484
if (!global_program_info->platform->is_helper_usable(imm)) {
24852485
return;
24862486
}
@@ -2569,8 +2569,8 @@ void ebpf_domain_t::shl(const Reg& dst_reg, int imm, int finite_width) {
25692569
if (interval.finite_size()) {
25702570
number_t lb = interval.lb().number().value();
25712571
number_t ub = interval.ub().number().value();
2572-
uint64_t lb_n = lb.cast_to_uint64();
2573-
uint64_t ub_n = ub.cast_to_uint64();
2572+
uint64_t lb_n = lb.cast_to<uint64_t>();
2573+
uint64_t ub_n = ub.cast_to<uint64_t>();
25742574
uint64_t uint_max = (finite_width == 64) ? UINT64_MAX : UINT32_MAX;
25752575
if ((lb_n >> (finite_width - imm)) != (ub_n >> (finite_width - imm))) {
25762576
// The bits that will be shifted out to the left are different,
@@ -2611,13 +2611,13 @@ void ebpf_domain_t::lshr(const Reg& dst_reg, int imm, int finite_width) {
26112611
number_t lb = interval.lb().number().value();
26122612
number_t ub = interval.ub().number().value();
26132613
if (finite_width == 64) {
2614-
lb_n = lb.cast_to_uint64() >> imm;
2615-
ub_n = ub.cast_to_uint64() >> imm;
2614+
lb_n = lb.cast_to<uint64_t>() >> imm;
2615+
ub_n = ub.cast_to<uint64_t>() >> imm;
26162616
} else {
26172617
number_t lb_w = lb.cast_to_signed_finite_width(finite_width);
26182618
number_t ub_w = ub.cast_to_signed_finite_width(finite_width);
2619-
lb_n = lb_w.cast_to_uint32() >> imm;
2620-
ub_n = ub_w.cast_to_uint32() >> imm;
2619+
lb_n = lb_w.cast_to<uint32_t>() >> imm;
2620+
ub_n = ub_w.cast_to<uint32_t>() >> imm;
26212621

26222622
// The interval must be valid since a signed range crossing 0
26232623
// was earlier converted to a full unsigned range.
@@ -2668,10 +2668,10 @@ void ebpf_domain_t::sign_extend(const Reg& dst_reg, const linear_expression_t& r
26682668
int64_t mask = 1ULL << (bits - 1);
26692669

26702670
// Sign extend each bound.
2671-
int64_t lb = right_interval.lb().number().value().cast_to_sint64();
2671+
int64_t lb = right_interval.lb().number().value().cast_to<int64_t>();
26722672
lb &= (span - 1);
26732673
lb = (lb ^ mask) - mask;
2674-
int64_t ub = right_interval.ub().number().value().cast_to_sint64();
2674+
int64_t ub = right_interval.ub().number().value().cast_to<int64_t>();
26752675
ub &= (span - 1);
26762676
ub = (ub ^ mask) - mask;
26772677
m_inv.set(dst.svalue, crab::interval_t{number_t{lb}, number_t{ub}});
@@ -2696,22 +2696,22 @@ void ebpf_domain_t::ashr(const Reg& dst_reg, const linear_expression_t& right_sv
26962696
right_interval, left_interval_positive, left_interval_negative);
26972697
if (auto sn = right_interval.singleton()) {
26982698
// The BPF ISA requires masking the imm.
2699-
int64_t imm = sn->cast_to_sint64() & (finite_width - 1);
2699+
int64_t imm = sn->cast_to<int64_t>() & (finite_width - 1);
27002700

27012701
int64_t lb_n = INT64_MIN >> imm;
27022702
int64_t ub_n = INT64_MAX >> imm;
27032703
if (left_interval.finite_size()) {
27042704
number_t lb = left_interval.lb().number().value();
27052705
number_t ub = left_interval.ub().number().value();
27062706
if (finite_width == 64) {
2707-
lb_n = lb.cast_to_sint64() >> imm;
2708-
ub_n = ub.cast_to_sint64() >> imm;
2707+
lb_n = lb.cast_to<int64_t>() >> imm;
2708+
ub_n = ub.cast_to<int64_t>() >> imm;
27092709
} else {
27102710
number_t lb_w = lb.cast_to_signed_finite_width(finite_width) >> (int)imm;
27112711
number_t ub_w = ub.cast_to_signed_finite_width(finite_width) >> (int)imm;
2712-
if (lb_w.cast_to_uint32() <= ub_w.cast_to_uint32()) {
2713-
lb_n = lb_w.cast_to_uint32();
2714-
ub_n = ub_w.cast_to_uint32();
2712+
if (lb_w.cast_to<uint32_t>() <= ub_w.cast_to<uint32_t>()) {
2713+
lb_n = lb_w.cast_to<uint32_t>();
2714+
ub_n = ub_w.cast_to<uint32_t>();
27152715
}
27162716
}
27172717
}
@@ -2957,7 +2957,7 @@ void ebpf_domain_t::operator()(const Bin& bin) {
29572957
auto src_interval = m_inv.eval_interval(src.uvalue);
29582958
if (std::optional<number_t> sn = src_interval.singleton()) {
29592959
// truncate to uint64?
2960-
uint64_t imm = sn->cast_to_uint64() & (bin.is64 ? 63 : 31);
2960+
uint64_t imm = sn->cast_to<uint64_t>() & (bin.is64 ? 63 : 31);
29612961
if (imm <= INT32_MAX) {
29622962
if (!bin.is64) {
29632963
// Use only the low 32 bits of the value.
@@ -2975,7 +2975,7 @@ void ebpf_domain_t::operator()(const Bin& bin) {
29752975
if (m_inv.entail(type_is_number(src_reg))) {
29762976
auto src_interval = m_inv.eval_interval(src.uvalue);
29772977
if (std::optional<number_t> sn = src_interval.singleton()) {
2978-
uint64_t imm = sn->cast_to_uint64() & (bin.is64 ? 63 : 31);
2978+
uint64_t imm = sn->cast_to<uint64_t>() & (bin.is64 ? 63 : 31);
29792979
if (imm <= INT32_MAX) {
29802980
if (!bin.is64) {
29812981
// Use only the low 32 bits of the value.

src/crab/interval.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ interval_t interval_t::SDiv(const interval_t& x) const {
5555
return bottom();
5656
}
5757
if (const auto n = x.singleton()) {
58-
if (n->fits_cast_to_int64()) {
58+
if (n->fits_cast_to<int64_t>()) {
5959
// Divisor is a singleton:
6060
// the linear interval solver can perform many divisions where
6161
// the divisor is a singleton interval. We optimize for this case.
62-
number_t c{n->cast_to_sint64()};
62+
number_t c{n->cast_to<int64_t>()};
6363
if (c == 1) {
6464
return *this;
6565
} else if (c != 0) {
@@ -100,11 +100,11 @@ interval_t interval_t::UDiv(const interval_t& x) const {
100100
return bottom();
101101
}
102102
if (const auto n = x.singleton()) {
103-
if (n->fits_cast_to_int64()) {
103+
if (n->fits_cast_to<int64_t>()) {
104104
// Divisor is a singleton:
105105
// the linear interval solver can perform many divisions where
106106
// the divisor is a singleton interval. We optimize for this case.
107-
number_t c{n->cast_to_uint64()};
107+
number_t c{n->cast_to<uint64_t>()};
108108
if (c == 1) {
109109
return *this;
110110
} else if (c > number_t{0}) {
@@ -215,11 +215,11 @@ interval_t interval_t::URem(const interval_t& x) const {
215215
// a value between the upper bound and 0, so set to top. A "positive" dividend
216216
// could result in anything between 0 and the dividend - 1.
217217
return (_ub < number_t{0}) ? top() : ((*this - interval_t(number_t{1})) | interval_t(number_t(0)));
218-
} else if (_ub.is_finite() && (_ub.number()->cast_to_uint64() < x._lb.number()->cast_to_uint64())) {
218+
} else if (_ub.is_finite() && (_ub.number()->cast_to<uint64_t>() < x._lb.number()->cast_to<uint64_t>())) {
219219
// Dividend lower than divisor, so the dividend is the remainder.
220220
return *this;
221221
} else {
222-
number_t max_divisor{x._ub.number()->cast_to_uint64()};
222+
number_t max_divisor{x._ub.number()->cast_to<uint64_t>()};
223223
return interval_t(number_t{0}, max_divisor - 1);
224224
}
225225
}
@@ -243,7 +243,7 @@ interval_t interval_t::And(const interval_t& x) const {
243243
if (const auto width = finite_size()) {
244244
const number_t lb32_n = lb().number()->truncate_to<uint32_t>();
245245
const number_t ub32_n = ub().number()->truncate_to<uint32_t>();
246-
if (width->fits_uint32() && lb32_n < ub32_n && lb32_n + width->truncate_to<uint32_t>() == ub32_n) {
246+
if (width->fits<uint32_t>() && lb32_n < ub32_n && lb32_n + width->truncate_to<uint32_t>() == ub32_n) {
247247
return interval_t{lb32_n, ub32_n};
248248
}
249249
}

src/crab/split_dbm.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ SplitDBM::vert_id SplitDBM::get_vert(variable_t v) {
4747
**/
4848
SafeInt64DefaultParams::Weight SafeInt64DefaultParams::convert_NtoW(const z_number& n, bool& overflow) {
4949
overflow = false;
50-
if (!n.fits_sint64()) {
50+
if (!n.fits<int64_t>()) {
5151
overflow = true;
5252
return 0;
5353
}
@@ -1031,7 +1031,7 @@ void SplitDBM::apply(bitwise_binop_t op, variable_t x, variable_t y, const numbe
10311031
// Convert to intervals and perform the operation
10321032
normalize();
10331033
interval_t yi = this->operator[](y);
1034-
interval_t zi(number_t(k.cast_to_uint64()));
1034+
interval_t zi(number_t(k.cast_to<uint64_t>()));
10351035
interval_t xi = interval_t::bottom();
10361036

10371037
switch (op) {

src/crab/var_factory.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ variable_t variable_t::stack_frame_var(data_kind_t kind, int i, std::string pref
176176
}
177177

178178
variable_t variable_t::cell_var(data_kind_t array, const number_t& offset, const number_t& size) {
179-
return make(mk_scalar_name(array, offset.cast_to_uint64(), size));
179+
return make(mk_scalar_name(array, offset.cast_to<uint64_t>(), size));
180180
}
181181

182182
// Given a type variable, get the associated variable of a given kind.

0 commit comments

Comments
 (0)