Skip to content

Commit 6685497

Browse files
committed
boolbv_width: distinguish zero from unknown size
Use optionalt to distinguish types of known-zero size from those with unknown size, which previously had the default value of zero. This makes it possible to support index expressions over zero bitwidth arrays without mistaking the situation for an unknown size. (There is not really anything wrong in having empty bitvectors, which we otherwise already support (as of e021eef).)
1 parent 3b340ad commit 6685497

33 files changed

+177
-248
lines changed

regression/cbmc/dynamic_sizeof1/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-z3-smt-backend
22
main.c
33

44
^EXIT=0$

regression/cbmc/vla1/test.desc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
CORE
1+
CORE broken-cprover-smt-backend
22
main.c
33

44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
88
^warning: ignoring
9+
--
10+
The SMT back-end does not correctly support structs with non-constant size,
11+
unless named data types are used (as is the case with Z3).

src/solvers/flattening/boolbv.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,22 +242,16 @@ bvt boolbvt::convert_array_comprehension(const array_comprehension_exprt &expr)
242242
{
243243
std::size_t width=boolbv_width(expr.type());
244244

245-
if(width==0)
246-
return conversion_failed(expr);
247-
248245
const exprt &array_size = expr.type().size();
249246

250-
const auto size = numeric_cast<mp_integer>(array_size);
251-
252-
if(!size.has_value())
253-
return conversion_failed(expr);
247+
const auto size = numeric_cast_v<mp_integer>(to_constant_expr(array_size));
254248

255249
typet counter_type = expr.arg().type();
256250

257251
bvt bv;
258252
bv.resize(width);
259253

260-
for(mp_integer i = 0; i < *size; ++i)
254+
for(mp_integer i = 0; i < size; ++i)
261255
{
262256
exprt counter=from_integer(i, counter_type);
263257

@@ -266,7 +260,7 @@ bvt boolbvt::convert_array_comprehension(const array_comprehension_exprt &expr)
266260
const bvt &tmp = convert_bv(body);
267261

268262
INVARIANT(
269-
*size * tmp.size() == width,
263+
size * tmp.size() == width,
270264
"total bitvector width shall equal the number of operands times the size "
271265
"per operand");
272266

@@ -521,12 +515,12 @@ bool boolbvt::is_unbounded_array(const typet &type) const
521515
if(unbounded_array==unbounded_arrayt::U_ALL)
522516
return true;
523517

524-
const std::size_t size = boolbv_width(type);
525-
if(size == 0)
518+
const auto &size_opt = bv_width.get_width_opt(type);
519+
if(!size_opt.has_value())
526520
return true;
527521

528522
if(unbounded_array==unbounded_arrayt::U_AUTO)
529-
if(size > MAX_FLATTENED_ARRAY_SIZE)
523+
if(*size_opt > MAX_FLATTENED_ARRAY_SIZE)
530524
return true;
531525

532526
return false;

src/solvers/flattening/boolbv_abs.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ Author: Daniel Kroening, [email protected]
1616

1717
bvt boolbvt::convert_abs(const abs_exprt &expr)
1818
{
19-
const std::size_t width = boolbv_width(expr.type());
20-
21-
if(width==0)
22-
return conversion_failed(expr);
23-
2419
const bvt &op_bv=convert_bv(expr.op());
2520

2621
if(expr.op().type()!=expr.type())

src/solvers/flattening/boolbv_add_sub.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
3232

3333
std::size_t width=boolbv_width(type);
3434

35-
if(width==0)
36-
return conversion_failed(expr);
37-
3835
const exprt::operandst &operands=expr.operands();
3936

4037
DATA_INVARIANT(
@@ -160,9 +157,6 @@ bvt boolbvt::convert_saturating_add_sub(const binary_exprt &expr)
160157

161158
std::size_t width = boolbv_width(type);
162159

163-
if(width == 0)
164-
return conversion_failed(expr);
165-
166160
DATA_INVARIANT(
167161
expr.lhs().type() == type && expr.rhs().type() == type,
168162
"saturating add/sub with mixed types:\n" + expr.pretty());

src/solvers/flattening/boolbv_array_of.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,17 @@ bvt boolbvt::convert_array_of(const array_of_exprt &expr)
2424
return conversion_failed(expr);
2525

2626
std::size_t width=boolbv_width(array_type);
27-
28-
if(width==0)
29-
{
30-
// A zero-length array is acceptable;
31-
// an element with unknown size is not.
32-
if(boolbv_width(array_type.element_type()) == 0)
33-
return conversion_failed(expr);
34-
else
35-
return bvt();
36-
}
27+
if(width == 0)
28+
return bvt{};
3729

3830
const exprt &array_size=array_type.size();
3931

40-
const auto size = numeric_cast<mp_integer>(array_size);
41-
42-
if(!size.has_value())
43-
return conversion_failed(expr);
32+
const auto size = numeric_cast_v<mp_integer>(to_constant_expr(array_size));
4433

4534
const bvt &tmp = convert_bv(expr.what());
4635

4736
INVARIANT(
48-
*size * tmp.size() == width,
37+
size * tmp.size() == width,
4938
"total array bit width shall equal the number of elements times the "
5039
"element bit with");
5140

src/solvers/flattening/boolbv_bitreverse.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ Author: Michael Tautschnig
1313
bvt boolbvt::convert_bitreverse(const bitreverse_exprt &expr)
1414
{
1515
const std::size_t width = boolbv_width(expr.type());
16-
if(width == 0)
17-
return conversion_failed(expr);
1816

1917
bvt bv = convert_bv(expr.op(), width);
2018

src/solvers/flattening/boolbv_bitwise.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ Author: Daniel Kroening, [email protected]
1313
bvt boolbvt::convert_bitwise(const exprt &expr)
1414
{
1515
const std::size_t width = boolbv_width(expr.type());
16-
if(width==0)
17-
return conversion_failed(expr);
1816

1917
if(expr.id()==ID_bitnot)
2018
{

src/solvers/flattening/boolbv_case.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ bvt boolbvt::convert_case(const exprt &expr)
1818

1919
std::size_t width=boolbv_width(expr.type());
2020

21-
if(width==0)
22-
return conversion_failed(expr);
23-
2421
// make it free variables
2522
bvt bv = prop.new_variables(width);
2623

src/solvers/flattening/boolbv_complex.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ bvt boolbvt::convert_complex(const complex_exprt &expr)
1414
{
1515
std::size_t width=boolbv_width(expr.type());
1616

17-
if(width==0)
18-
return conversion_failed(expr);
19-
2017
DATA_INVARIANT(
2118
expr.type().id() == ID_complex,
2219
"complex expression shall have complex type");
@@ -41,9 +38,6 @@ bvt boolbvt::convert_complex_real(const complex_real_exprt &expr)
4138
{
4239
std::size_t width=boolbv_width(expr.type());
4340

44-
if(width==0)
45-
return conversion_failed(expr);
46-
4741
bvt bv = convert_bv(expr.op(), width * 2);
4842

4943
bv.resize(width); // chop
@@ -55,9 +49,6 @@ bvt boolbvt::convert_complex_imag(const complex_imag_exprt &expr)
5549
{
5650
std::size_t width=boolbv_width(expr.type());
5751

58-
if(width==0)
59-
return conversion_failed(expr);
60-
6152
bvt bv = convert_bv(expr.op(), width * 2);
6253

6354
bv.erase(bv.begin(), bv.begin()+width);

0 commit comments

Comments
 (0)