Skip to content

Commit 904b131

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.
1 parent 05c9317 commit 904b131

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+604
-341
lines changed

regression/cbmc/Empty_struct1/test.desc

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

44
^EXIT=0$

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: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ bvt boolbvt::conversion_failed(const exprt &expr)
8585
ignoring(expr);
8686

8787
// try to make it free bits
88-
std::size_t width=boolbv_width(expr.type());
89-
return prop.new_variables(width);
88+
// TODO we likely end up in this path when an earlier call to boolbv_width
89+
// failed
90+
const auto &width_opt = boolbv_width(expr.type());
91+
CHECK_RETURN(width_opt.has_value());
92+
return prop.new_variables(*width_opt);
9093
}
9194

9295
/// Converts an expression into its gate-level representation and returns a
@@ -234,11 +237,12 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
234237

235238
bvt boolbvt::convert_array_comprehension(const array_comprehension_exprt &expr)
236239
{
237-
std::size_t width=boolbv_width(expr.type());
238-
239-
if(width==0)
240+
const auto &width_opt = boolbv_width(expr.type());
241+
if(!width_opt.has_value())
240242
return conversion_failed(expr);
241243

244+
const std::size_t width = *width_opt;
245+
242246
const exprt &array_size = expr.type().size();
243247

244248
const auto size = numeric_cast<mp_integer>(array_size);
@@ -276,7 +280,9 @@ bvt boolbvt::convert_array_comprehension(const array_comprehension_exprt &expr)
276280
bvt boolbvt::convert_symbol(const exprt &expr)
277281
{
278282
const typet &type=expr.type();
279-
std::size_t width=boolbv_width(type);
283+
const auto &width_opt = boolbv_width(type);
284+
CHECK_RETURN(width_opt.has_value());
285+
const std::size_t width = *width_opt;
280286

281287
const irep_idt &identifier = expr.get(ID_identifier);
282288
CHECK_RETURN(!identifier.empty());
@@ -304,7 +310,9 @@ bvt boolbvt::convert_function_application(
304310
functions.record(expr);
305311

306312
// make it free bits
307-
return prop.new_variables(boolbv_width(expr.type()));
313+
const auto &width_opt = boolbv_width(expr.type());
314+
CHECK_RETURN(width_opt.has_value());
315+
return prop.new_variables(*width_opt);
308316
}
309317

310318

@@ -515,12 +523,12 @@ bool boolbvt::is_unbounded_array(const typet &type) const
515523
if(unbounded_array==unbounded_arrayt::U_ALL)
516524
return true;
517525

518-
const std::size_t size = boolbv_width(type);
519-
if(size == 0)
526+
const auto &size_opt = boolbv_width(type);
527+
if(!size_opt.has_value())
520528
return true;
521529

522530
if(unbounded_array==unbounded_arrayt::U_AUTO)
523-
if(size > MAX_FLATTENED_ARRAY_SIZE)
531+
if(*size_opt > MAX_FLATTENED_ARRAY_SIZE)
524532
return true;
525533

526534
return false;
@@ -564,7 +572,9 @@ boolbvt::offset_mapt boolbvt::build_offset_map(const struct_typet &src)
564572
for(const auto &comp : components)
565573
{
566574
dest.push_back(offset);
567-
offset += boolbv_width(comp.type());
575+
const auto &comp_width_opt = boolbv_width(comp.type());
576+
CHECK_RETURN(comp_width_opt.has_value());
577+
offset += *comp_width_opt;
568578
}
569579
return dest;
570580
}

src/solvers/flattening/boolbv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class boolbvt:public arrayst
9898
return map;
9999
}
100100

101-
virtual std::size_t boolbv_width(const typet &type) const
101+
virtual optionalt<std::size_t> boolbv_width(const typet &type) const
102102
{
103103
return bv_width(type);
104104
}

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: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
3030
type.id()!=ID_vector)
3131
return conversion_failed(expr);
3232

33-
std::size_t width=boolbv_width(type);
34-
35-
if(width==0)
33+
const auto &width_opt = boolbv_width(type);
34+
if(!width_opt.has_value())
3635
return conversion_failed(expr);
3736

37+
const std::size_t width = *width_opt;
38+
3839
const exprt::operandst &operands=expr.operands();
3940

4041
DATA_INVARIANT(
@@ -73,8 +74,10 @@ bvt boolbvt::convert_add_sub(const exprt &expr)
7374

7475
if(type.id()==ID_vector || type.id()==ID_complex)
7576
{
76-
std::size_t sub_width =
77+
const auto &sub_width_opt =
7778
boolbv_width(to_type_with_subtype(type).subtype());
79+
CHECK_RETURN(sub_width_opt.has_value());
80+
const std::size_t sub_width = *sub_width_opt;
7881

7982
INVARIANT(sub_width != 0, "vector elements shall have nonzero bit width");
8083
INVARIANT(
@@ -158,11 +161,12 @@ bvt boolbvt::convert_saturating_add_sub(const binary_exprt &expr)
158161
return conversion_failed(expr);
159162
}
160163

161-
std::size_t width = boolbv_width(type);
162-
163-
if(width == 0)
164+
const auto &width_opt = boolbv_width(type);
165+
if(!width_opt.has_value())
164166
return conversion_failed(expr);
165167

168+
const std::size_t width = *width_opt;
169+
166170
DATA_INVARIANT(
167171
expr.lhs().type() == type && expr.rhs().type() == type,
168172
"saturating add/sub with mixed types:\n" + expr.pretty());
@@ -184,7 +188,10 @@ bvt boolbvt::convert_saturating_add_sub(const binary_exprt &expr)
184188
if(type.id() != ID_vector && type.id() != ID_complex)
185189
return bv_utils.saturating_add_sub(bv, op, subtract, rep);
186190

187-
std::size_t sub_width = boolbv_width(to_type_with_subtype(type).subtype());
191+
const auto &sub_width_opt =
192+
boolbv_width(to_type_with_subtype(type).subtype());
193+
CHECK_RETURN(sub_width_opt.has_value());
194+
const std::size_t sub_width = *sub_width_opt;
188195

189196
INVARIANT(sub_width != 0, "vector elements shall have nonzero bit width");
190197
INVARIANT(

src/solvers/flattening/boolbv_array.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ Author: Daniel Kroening, [email protected]
1515
/// Return an empty vector if the width is zero or the array has no elements.
1616
bvt boolbvt::convert_array(const exprt &expr)
1717
{
18-
const std::size_t width = boolbv_width(expr.type());
18+
const auto &width_opt = boolbv_width(expr.type());
19+
CHECK_RETURN(width_opt.has_value());
20+
const std::size_t width = *width_opt;
21+
1922
const exprt::operandst &operands = expr.operands();
2023

2124
if(operands.empty() && width == 0)

src/solvers/flattening/boolbv_array_of.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,13 @@ bvt boolbvt::convert_array_of(const array_of_exprt &expr)
2323
if(is_unbounded_array(array_type))
2424
return conversion_failed(expr);
2525

26-
std::size_t width=boolbv_width(array_type);
26+
const auto &width_opt = boolbv_width(array_type);
27+
if(!width_opt.has_value())
28+
return conversion_failed(expr);
29+
else if(*width_opt == 0)
30+
return bvt{};
2731

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-
}
32+
const std::size_t width = *width_opt;
3733

3834
const exprt &array_size=array_type.size();
3935

src/solvers/flattening/boolbv_bitreverse.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ Author: Michael Tautschnig
1212

1313
bvt boolbvt::convert_bitreverse(const bitreverse_exprt &expr)
1414
{
15-
const std::size_t width = boolbv_width(expr.type());
16-
if(width == 0)
15+
const auto &width_opt = boolbv_width(expr.type());
16+
if(!width_opt.has_value())
1717
return conversion_failed(expr);
1818

19+
const std::size_t width = *width_opt;
20+
1921
bvt bv = convert_bv(expr.op(), width);
2022

2123
std::reverse(bv.begin(), bv.end());

src/solvers/flattening/boolbv_bitwise.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ Author: Daniel Kroening, [email protected]
1212

1313
bvt boolbvt::convert_bitwise(const exprt &expr)
1414
{
15-
const std::size_t width = boolbv_width(expr.type());
16-
if(width==0)
15+
const auto &width_opt = boolbv_width(expr.type());
16+
if(!width_opt.has_value())
1717
return conversion_failed(expr);
1818

19+
const std::size_t width = *width_opt;
20+
1921
if(expr.id()==ID_bitnot)
2022
{
2123
const exprt &op = to_bitnot_expr(expr).op();

src/solvers/flattening/boolbv_bswap.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ Author: Michael Tautschnig
1212

1313
bvt boolbvt::convert_bswap(const bswap_exprt &expr)
1414
{
15-
const std::size_t width = boolbv_width(expr.type());
15+
const auto &width_opt = boolbv_width(expr.type());
16+
if(!width_opt.has_value())
17+
return conversion_failed(expr);
18+
19+
const std::size_t width = *width_opt;
1620

1721
// width must be multiple of bytes
1822
const std::size_t byte_bits = expr.get_bits_per_byte();

src/solvers/flattening/boolbv_byte_extract.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
4141
return convert_bv(lower_byte_extract(expr, ns));
4242
}
4343

44-
const std::size_t width = boolbv_width(expr.type());
44+
const auto &width_opt = boolbv_width(expr.type());
45+
if(!width_opt.has_value())
46+
return conversion_failed(expr);
47+
48+
const std::size_t width = *width_opt;
4549

4650
// special treatment for bit-fields and big-endian:
4751
// we need byte granularity

src/solvers/flattening/boolbv_case.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ bvt boolbvt::convert_case(const exprt &expr)
1616

1717
const std::vector<exprt> &operands=expr.operands();
1818

19-
std::size_t width=boolbv_width(expr.type());
20-
21-
if(width==0)
19+
const auto &width_opt = boolbv_width(expr.type());
20+
if(!width_opt.has_value())
2221
return conversion_failed(expr);
2322

23+
const std::size_t width = *width_opt;
24+
2425
// make it free variables
2526
bvt bv = prop.new_variables(width);
2627

src/solvers/flattening/boolbv_complex.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ Author: Daniel Kroening, [email protected]
1212

1313
bvt boolbvt::convert_complex(const complex_exprt &expr)
1414
{
15-
std::size_t width=boolbv_width(expr.type());
16-
17-
if(width==0)
15+
const auto &width_opt = boolbv_width(expr.type());
16+
if(!width_opt.has_value())
1817
return conversion_failed(expr);
1918

19+
const std::size_t width = *width_opt;
20+
2021
DATA_INVARIANT(
2122
expr.type().id() == ID_complex,
2223
"complex expression shall have complex type");
@@ -39,11 +40,12 @@ bvt boolbvt::convert_complex(const complex_exprt &expr)
3940

4041
bvt boolbvt::convert_complex_real(const complex_real_exprt &expr)
4142
{
42-
std::size_t width=boolbv_width(expr.type());
43-
44-
if(width==0)
43+
const auto &width_opt = boolbv_width(expr.type());
44+
if(!width_opt.has_value())
4545
return conversion_failed(expr);
4646

47+
const std::size_t width = *width_opt;
48+
4749
bvt bv = convert_bv(expr.op(), width * 2);
4850

4951
bv.resize(width); // chop
@@ -53,11 +55,12 @@ bvt boolbvt::convert_complex_real(const complex_real_exprt &expr)
5355

5456
bvt boolbvt::convert_complex_imag(const complex_imag_exprt &expr)
5557
{
56-
std::size_t width=boolbv_width(expr.type());
57-
58-
if(width==0)
58+
const auto &width_opt = boolbv_width(expr.type());
59+
if(!width_opt.has_value())
5960
return conversion_failed(expr);
6061

62+
const std::size_t width = *width_opt;
63+
6164
bvt bv = convert_bv(expr.op(), width * 2);
6265

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

src/solvers/flattening/boolbv_concatenation.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ Author: Daniel Kroening, [email protected]
1313

1414
bvt boolbvt::convert_concatenation(const concatenation_exprt &expr)
1515
{
16-
std::size_t width=boolbv_width(expr.type());
17-
18-
if(width==0)
16+
const auto &width_opt = boolbv_width(expr.type());
17+
if(!width_opt.has_value())
1918
return conversion_failed(expr);
2019

20+
const std::size_t width = *width_opt;
21+
2122
const exprt::operandst &operands=expr.operands();
2223

2324
DATA_INVARIANT(

src/solvers/flattening/boolbv_cond.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ bvt boolbvt::convert_cond(const cond_exprt &expr)
1414
{
1515
const exprt::operandst &operands=expr.operands();
1616

17-
std::size_t width=boolbv_width(expr.type());
18-
19-
if(width==0)
17+
const auto &width_opt = boolbv_width(expr.type());
18+
if(!width_opt.has_value())
2019
return conversion_failed(expr);
2120

21+
const std::size_t width = *width_opt;
22+
2223
bvt bv;
2324

2425
DATA_INVARIANT(operands.size() >= 2, "cond must have at least two operands");

src/solvers/flattening/boolbv_constant.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ Author: Daniel Kroening, [email protected]
1212

1313
bvt boolbvt::convert_constant(const constant_exprt &expr)
1414
{
15-
std::size_t width=boolbv_width(expr.type());
16-
17-
if(width==0)
15+
const auto &width_opt = boolbv_width(expr.type());
16+
if(!width_opt.has_value())
1817
return conversion_failed(expr);
1918

19+
const std::size_t width = *width_opt;
20+
2021
bvt bv;
2122
bv.resize(width);
2223

src/solvers/flattening/boolbv_constraint_select_one.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ bvt boolbvt::convert_constraint_select_one(const exprt &expr)
2626

2727
if(prop.has_set_to())
2828
{
29-
std::size_t width=boolbv_width(expr.type());
29+
const auto &width_opt = boolbv_width(expr.type());
30+
if(!width_opt.has_value())
31+
return conversion_failed(expr);
32+
33+
const std::size_t width = *width_opt;
34+
3035
bv=prop.new_variables(width);
3136

3237
bvt b;

0 commit comments

Comments
 (0)