Skip to content

Commit 7da0d6f

Browse files
committed
Do not generate nil_exprt in bv_get
We have all the information available, and should thus always generate concrete values.
1 parent 47bdb15 commit 7da0d6f

File tree

6 files changed

+52
-53
lines changed

6 files changed

+52
-53
lines changed

regression/cbmc/memory_allocation1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.c
33
--pointer-check
44
^EXIT=10$

regression/cbmc/union12/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.c
33
--pointer-check
44
^EXIT=10$

src/solvers/flattening/boolbv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class boolbvt:public arrayst
226226
virtual exprt bv_get_unbounded_array(const exprt &) const;
227227

228228
virtual exprt bv_get_rec(
229+
const exprt &expr,
229230
const bvt &bv,
230231
const std::vector<bool> &unknown,
231232
std::size_t offset,

src/solvers/flattening/boolbv_get.cpp

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ Author: Daniel Kroening, [email protected]
1111
#include <cassert>
1212

1313
#include <util/arith_tools.h>
14+
#include <util/c_types.h>
15+
#include <util/simplify_expr.h>
1416
#include <util/std_expr.h>
15-
#include <util/threeval.h>
1617
#include <util/std_types.h>
17-
#include <util/simplify_expr.h>
18+
#include <util/threeval.h>
1819

1920
#include "boolbv_type.h"
2021

@@ -37,9 +38,6 @@ exprt boolbvt::get(const exprt &expr) const
3738
// the mapping
3839
PRECONDITION(expr.type() == typet() || expr.type() == map_entry.type);
3940

40-
if(is_unbounded_array(map_entry.type))
41-
return bv_get_unbounded_array(expr);
42-
4341
std::vector<bool> unknown;
4442
bvt bv;
4543
std::size_t width=map_entry.width;
@@ -63,14 +61,15 @@ exprt boolbvt::get(const exprt &expr) const
6361
}
6462
}
6563

66-
return bv_get_rec(bv, unknown, 0, map_entry.type);
64+
return bv_get_rec(expr, bv, unknown, 0, map_entry.type);
6765
}
6866
}
6967

7068
return SUB::get(expr);
7169
}
7270

7371
exprt boolbvt::bv_get_rec(
72+
const exprt &expr,
7473
const bvt &bv,
7574
const std::vector<bool> &unknown,
7675
std::size_t offset,
@@ -93,7 +92,7 @@ exprt boolbvt::bv_get_rec(
9392
}
9493
}
9594

96-
return nil_exprt();
95+
return false_exprt{}; // default
9796
}
9897

9998
bvtypet bvtype=get_bvtype(type);
@@ -102,6 +101,9 @@ exprt boolbvt::bv_get_rec(
102101
{
103102
if(type.id()==ID_array)
104103
{
104+
if(is_unbounded_array(type))
105+
return bv_get_unbounded_array(expr);
106+
105107
const typet &subtype=type.subtype();
106108
std::size_t sub_width=boolbv_width(subtype);
107109

@@ -114,8 +116,10 @@ exprt boolbvt::bv_get_rec(
114116
new_offset<width;
115117
new_offset+=sub_width)
116118
{
119+
const index_exprt index{
120+
expr, from_integer(new_offset / sub_width, index_type())};
117121
op.push_back(
118-
bv_get_rec(bv, unknown, offset+new_offset, subtype));
122+
bv_get_rec(index, bv, unknown, offset + new_offset, subtype));
119123
}
120124

121125
exprt dest=exprt(ID_array, type);
@@ -126,14 +130,14 @@ exprt boolbvt::bv_get_rec(
126130
else if(type.id()==ID_struct_tag)
127131
{
128132
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)));
130134
result.type() = type;
131135
return result;
132136
}
133137
else if(type.id()==ID_union_tag)
134138
{
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)));
137141
result.type() = type;
138142
return result;
139143
}
@@ -148,15 +152,14 @@ exprt boolbvt::bv_get_rec(
148152
for(const auto &c : components)
149153
{
150154
const typet &subtype = c.type();
151-
op.push_back(nil_exprt());
152155

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));
154159

160+
std::size_t sub_width = boolbv_width(subtype);
155161
if(sub_width!=0)
156-
{
157-
op.back()=bv_get_rec(bv, unknown, offset+new_offset, subtype);
158162
new_offset+=sub_width;
159-
}
160163
}
161164

162165
return struct_exprt(std::move(op), type);
@@ -173,9 +176,11 @@ exprt boolbvt::bv_get_rec(
173176

174177
const typet &subtype = components[component_nr].type();
175178

179+
const member_exprt member{
180+
expr, components[component_nr].get_name(), subtype};
176181
return union_exprt(
177182
components[component_nr].get_name(),
178-
bv_get_rec(bv, unknown, offset, subtype),
183+
bv_get_rec(member, bv, unknown, offset, subtype),
179184
union_type);
180185
}
181186
else if(type.id()==ID_vector)
@@ -190,8 +195,11 @@ exprt boolbvt::bv_get_rec(
190195
value.reserve_operands(size);
191196

192197
for(std::size_t i=0; i<size; i++)
198+
{
199+
const index_exprt index{expr, from_integer(i, index_type())};
193200
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+
}
195203

196204
return std::move(value);
197205
}
@@ -204,8 +212,10 @@ exprt boolbvt::bv_get_rec(
204212
if(sub_width!=0 && width==sub_width*2)
205213
{
206214
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),
209219
to_complex_type(type));
210220

211221
return value;
@@ -236,6 +246,7 @@ exprt boolbvt::bv_get_rec(
236246
switch(bvtype)
237247
{
238248
case bvtypet::IS_UNKNOWN:
249+
PRECONDITION(type.id() == ID_string || type.id() == ID_empty);
239250
if(type.id()==ID_string)
240251
{
241252
mp_integer int_value=binary2integer(value, false);
@@ -247,6 +258,10 @@ exprt boolbvt::bv_get_rec(
247258

248259
return constant_exprt(s, type);
249260
}
261+
else if(type.id() == ID_empty)
262+
{
263+
return constant_exprt{irep_idt(), type};
264+
}
250265
break;
251266

252267
case bvtypet::IS_RANGE:
@@ -267,14 +282,14 @@ exprt boolbvt::bv_get_rec(
267282
}
268283
}
269284

270-
return nil_exprt();
285+
UNREACHABLE;
271286
}
272287

273288
exprt boolbvt::bv_get(const bvt &bv, const typet &type) const
274289
{
275290
std::vector<bool> unknown;
276291
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);
278293
}
279294

280295
exprt boolbvt::bv_get_cache(const exprt &expr) const
@@ -284,8 +299,7 @@ exprt boolbvt::bv_get_cache(const exprt &expr) const
284299

285300
// look up literals in cache
286301
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());
289303

290304
return bv_get(it->second, expr.type());
291305
}
@@ -298,36 +312,24 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
298312
const exprt &size_expr=to_array_type(type).size();
299313
exprt size=simplify_expr(get(size_expr), ns);
300314

301-
// no size, give up
302-
if(size.is_nil())
303-
return nil_exprt();
304-
305315
// get the numeric value, unless it's infinity
306-
mp_integer size_mpint;
316+
mp_integer size_mpint = 0;
307317

308-
if(size.id()!=ID_infinity)
318+
if(size.is_not_nil() && size.id() != ID_infinity)
309319
{
310320
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)
314322
size_mpint = *size_opt;
315323
}
316-
else
317-
size_mpint=0;
318324

319325
// search array indices
320326

321327
typedef std::map<mp_integer, exprt> valuest;
322328
valuest values;
323329

330+
const auto opt_num = arrays.get_number(expr);
331+
if(opt_num.has_value())
324332
{
325-
const auto opt_num = arrays.get_number(expr);
326-
if(!opt_num)
327-
{
328-
return nil_exprt();
329-
}
330-
331333
// get root
332334
const auto number = arrays.find_number(*opt_num);
333335

@@ -363,10 +365,9 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
363365

364366
exprt result;
365367

366-
if(size_mpint>100 || size.id()==ID_infinity)
368+
if(values.size() != size_mpint)
367369
{
368370
result = array_list_exprt({}, to_array_type(type));
369-
result.type().set(ID_size, integer2string(size_mpint));
370371

371372
result.operands().reserve(values.size()*2);
372373

@@ -382,15 +383,10 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
382383
{
383384
// set the size
384385
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);
388386

389387
// 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});
394390

395391
// search uninterpreted functions
396392

src/solvers/flattening/bv_pointers.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,13 +585,14 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
585585
}
586586

587587
exprt bv_pointerst::bv_get_rec(
588+
const exprt &expr,
588589
const bvt &bv,
589590
const std::vector<bool> &unknown,
590591
std::size_t offset,
591592
const typet &type) const
592593
{
593594
if(type.id()!=ID_pointer)
594-
return SUB::bv_get_rec(bv, unknown, offset, type);
595+
return SUB::bv_get_rec(expr, bv, unknown, offset, type);
595596

596597
std::string value_addr, value_offset, value;
597598

src/solvers/flattening/bv_pointers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class bv_pointerst:public boolbvt
4343
bvt convert_bitvector(const exprt &expr) override; // no cache
4444

4545
exprt bv_get_rec(
46+
const exprt &expr,
4647
const bvt &bv,
4748
const std::vector<bool> &unknown,
4849
std::size_t offset,

0 commit comments

Comments
 (0)