11
11
#include < cassert>
12
12
13
13
#include < util/arith_tools.h>
14
+ #include < util/c_types.h>
15
+ #include < util/simplify_expr.h>
14
16
#include < util/std_expr.h>
15
- #include < util/threeval.h>
16
17
#include < util/std_types.h>
17
- #include < util/simplify_expr .h>
18
+ #include < util/threeval .h>
18
19
19
20
#include " boolbv_type.h"
20
21
@@ -37,9 +38,6 @@ exprt boolbvt::get(const exprt &expr) const
37
38
// the mapping
38
39
PRECONDITION (expr.type () == typet () || expr.type () == map_entry.type );
39
40
40
- if (is_unbounded_array (map_entry.type ))
41
- return bv_get_unbounded_array (expr);
42
-
43
41
std::vector<bool > unknown;
44
42
bvt bv;
45
43
std::size_t width=map_entry.width ;
@@ -63,14 +61,15 @@ exprt boolbvt::get(const exprt &expr) const
63
61
}
64
62
}
65
63
66
- return bv_get_rec (bv, unknown, 0 , map_entry.type );
64
+ return bv_get_rec (expr, bv, unknown, 0 , map_entry.type );
67
65
}
68
66
}
69
67
70
68
return SUB::get (expr);
71
69
}
72
70
73
71
exprt boolbvt::bv_get_rec (
72
+ const exprt &expr,
74
73
const bvt &bv,
75
74
const std::vector<bool > &unknown,
76
75
std::size_t offset,
@@ -93,7 +92,7 @@ exprt boolbvt::bv_get_rec(
93
92
}
94
93
}
95
94
96
- return nil_exprt ();
95
+ return false_exprt{}; // default
97
96
}
98
97
99
98
bvtypet bvtype=get_bvtype (type);
@@ -102,6 +101,9 @@ exprt boolbvt::bv_get_rec(
102
101
{
103
102
if (type.id ()==ID_array)
104
103
{
104
+ if (is_unbounded_array (type))
105
+ return bv_get_unbounded_array (expr);
106
+
105
107
const typet &subtype=type.subtype ();
106
108
std::size_t sub_width=boolbv_width (subtype);
107
109
@@ -114,8 +116,10 @@ exprt boolbvt::bv_get_rec(
114
116
new_offset<width;
115
117
new_offset+=sub_width)
116
118
{
119
+ const index_exprt index {
120
+ expr, from_integer (new_offset / sub_width, index_type ())};
117
121
op.push_back (
118
- bv_get_rec (bv, unknown, offset+ new_offset, subtype));
122
+ bv_get_rec (index , bv, unknown, offset + new_offset, subtype));
119
123
}
120
124
121
125
exprt dest=exprt (ID_array, type);
@@ -126,14 +130,14 @@ exprt boolbvt::bv_get_rec(
126
130
else if (type.id ()==ID_struct_tag)
127
131
{
128
132
exprt result = bv_get_rec (
129
- bv, unknown, offset, ns.follow_tag (to_struct_tag_type (type)));
133
+ expr, bv, unknown, offset, ns.follow_tag (to_struct_tag_type (type)));
130
134
result.type () = type;
131
135
return result;
132
136
}
133
137
else if (type.id ()==ID_union_tag)
134
138
{
135
- exprt result =
136
- bv_get_rec ( bv, unknown, offset, ns.follow_tag (to_union_tag_type (type)));
139
+ exprt result = bv_get_rec (
140
+ expr, bv, unknown, offset, ns.follow_tag (to_union_tag_type (type)));
137
141
result.type () = type;
138
142
return result;
139
143
}
@@ -148,15 +152,14 @@ exprt boolbvt::bv_get_rec(
148
152
for (const auto &c : components)
149
153
{
150
154
const typet &subtype = c.type ();
151
- op.push_back (nil_exprt ());
152
155
153
- std::size_t sub_width=boolbv_width (subtype);
156
+ const member_exprt member{expr, c.get_name (), subtype};
157
+ op.push_back (
158
+ bv_get_rec (member, bv, unknown, offset + new_offset, subtype));
154
159
160
+ std::size_t sub_width = boolbv_width (subtype);
155
161
if (sub_width!=0 )
156
- {
157
- op.back ()=bv_get_rec (bv, unknown, offset+new_offset, subtype);
158
162
new_offset+=sub_width;
159
- }
160
163
}
161
164
162
165
return struct_exprt (std::move (op), type);
@@ -173,9 +176,11 @@ exprt boolbvt::bv_get_rec(
173
176
174
177
const typet &subtype = components[component_nr].type ();
175
178
179
+ const member_exprt member{
180
+ expr, components[component_nr].get_name (), subtype};
176
181
return union_exprt (
177
182
components[component_nr].get_name (),
178
- bv_get_rec (bv, unknown, offset, subtype),
183
+ bv_get_rec (member, bv, unknown, offset, subtype),
179
184
union_type);
180
185
}
181
186
else if (type.id ()==ID_vector)
@@ -190,8 +195,11 @@ exprt boolbvt::bv_get_rec(
190
195
value.reserve_operands (size);
191
196
192
197
for (std::size_t i=0 ; i<size; i++)
198
+ {
199
+ const index_exprt index {expr, from_integer (i, index_type ())};
193
200
value.operands ().push_back (
194
- bv_get_rec (bv, unknown, i*sub_width, subtype));
201
+ bv_get_rec (index , bv, unknown, i * sub_width, subtype));
202
+ }
195
203
196
204
return std::move (value);
197
205
}
@@ -204,8 +212,10 @@ exprt boolbvt::bv_get_rec(
204
212
if (sub_width!=0 && width==sub_width*2 )
205
213
{
206
214
const complex_exprt value (
207
- bv_get_rec (bv, unknown, 0 * sub_width, subtype),
208
- bv_get_rec (bv, unknown, 1 * sub_width, subtype),
215
+ bv_get_rec (
216
+ complex_real_exprt{expr}, bv, unknown, 0 * sub_width, subtype),
217
+ bv_get_rec (
218
+ complex_imag_exprt{expr}, bv, unknown, 1 * sub_width, subtype),
209
219
to_complex_type (type));
210
220
211
221
return value;
@@ -236,6 +246,7 @@ exprt boolbvt::bv_get_rec(
236
246
switch (bvtype)
237
247
{
238
248
case bvtypet::IS_UNKNOWN:
249
+ PRECONDITION (type.id () == ID_string || type.id () == ID_empty);
239
250
if (type.id ()==ID_string)
240
251
{
241
252
mp_integer int_value=binary2integer (value, false );
@@ -247,6 +258,10 @@ exprt boolbvt::bv_get_rec(
247
258
248
259
return constant_exprt (s, type);
249
260
}
261
+ else if (type.id () == ID_empty)
262
+ {
263
+ return constant_exprt{irep_idt (), type};
264
+ }
250
265
break ;
251
266
252
267
case bvtypet::IS_RANGE:
@@ -267,14 +282,14 @@ exprt boolbvt::bv_get_rec(
267
282
}
268
283
}
269
284
270
- return nil_exprt () ;
285
+ UNREACHABLE ;
271
286
}
272
287
273
288
exprt boolbvt::bv_get (const bvt &bv, const typet &type) const
274
289
{
275
290
std::vector<bool > unknown;
276
291
unknown.resize (bv.size (), false );
277
- return bv_get_rec (bv, unknown, 0 , type);
292
+ return bv_get_rec (nil_exprt{}, bv, unknown, 0 , type);
278
293
}
279
294
280
295
exprt boolbvt::bv_get_cache (const exprt &expr) const
@@ -284,8 +299,7 @@ exprt boolbvt::bv_get_cache(const exprt &expr) const
284
299
285
300
// look up literals in cache
286
301
bv_cachet::const_iterator it=bv_cache.find (expr);
287
- if (it==bv_cache.end ())
288
- return nil_exprt ();
302
+ CHECK_RETURN (it != bv_cache.end ());
289
303
290
304
return bv_get (it->second , expr.type ());
291
305
}
@@ -298,36 +312,24 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
298
312
const exprt &size_expr=to_array_type (type).size ();
299
313
exprt size=simplify_expr (get (size_expr), ns);
300
314
301
- // no size, give up
302
- if (size.is_nil ())
303
- return nil_exprt ();
304
-
305
315
// get the numeric value, unless it's infinity
306
- mp_integer size_mpint;
316
+ mp_integer size_mpint = 0 ;
307
317
308
- if (size.id ()!= ID_infinity)
318
+ if (size.is_not_nil () && size. id () != ID_infinity)
309
319
{
310
320
const auto size_opt = numeric_cast<mp_integer>(size);
311
- if (!size_opt.has_value () || *size_opt < 0 )
312
- return nil_exprt ();
313
- else
321
+ if (size_opt.has_value () && *size_opt >= 0 )
314
322
size_mpint = *size_opt;
315
323
}
316
- else
317
- size_mpint=0 ;
318
324
319
325
// search array indices
320
326
321
327
typedef std::map<mp_integer, exprt> valuest;
322
328
valuest values;
323
329
330
+ const auto opt_num = arrays.get_number (expr);
331
+ if (opt_num.has_value ())
324
332
{
325
- const auto opt_num = arrays.get_number (expr);
326
- if (!opt_num)
327
- {
328
- return nil_exprt ();
329
- }
330
-
331
333
// get root
332
334
const auto number = arrays.find_number (*opt_num);
333
335
@@ -363,10 +365,9 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
363
365
364
366
exprt result;
365
367
366
- if (size_mpint> 100 || size. id ()==ID_infinity )
368
+ if (values. size () != size_mpint )
367
369
{
368
370
result = array_list_exprt ({}, to_array_type (type));
369
- result.type ().set (ID_size, integer2string (size_mpint));
370
371
371
372
result.operands ().reserve (values.size ()*2 );
372
373
@@ -382,15 +383,10 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
382
383
{
383
384
// set the size
384
385
result=exprt (ID_array, type);
385
- result.type ().set (ID_size, size);
386
-
387
- std::size_t size_int = numeric_cast_v<std::size_t >(size_mpint);
388
386
389
387
// allocate operands
390
- result.operands ().resize (size_int);
391
-
392
- for (std::size_t i=0 ; i<size_int; i++)
393
- result.operands ()[i]=exprt (ID_unknown);
388
+ std::size_t size_int = numeric_cast_v<std::size_t >(size_mpint);
389
+ result.operands ().resize (size_int, exprt{ID_unknown});
394
390
395
391
// search uninterpreted functions
396
392
0 commit comments